Loadable Kernel Modules

Most stealth techniques work at the kernel level and are implemented in the form of Loadable Kernel Modules (LKMs). There are no specific difficulties in relation to programming such modules, especially for older kernels (version 2.4).

The source code of the simplest module is provided in Listing 13.1.

Listing 13.1: The skeleton of the simplest module for version 2.4 kernels
image from book
 // Inform the compiler that this is the kernel-level module. #define MODULE #define __KERNEL__ // Include the header file for modules. #include <linux/module.h> // On multiprocessor machines, it is also necessary to include smp_lock. #ifdef __SMP__         #include <linux/smp_lock.h> #endif // The function that is carried out when the module is loading. int init_module(void) {         // Now the module switches to the kernel mode         // and can do whatever it chooses.        ...        // Meow!         printk("\nWOW! Our module has been loaded!\n");         // Successful initialization.         return(0); } // The function executed when the module is unloaded. void cleanup_module(void) {         // Meow!         printk("\nHell! Our module has been unloaded\n"); } // Attach a license for distribution of the current file. // If this is not done, the module would load successfully // but the operating system would issue a warning // that would be saved in logs, which would attract the // administrator's attention. MODULE_LICENSE("GPL"); 
image from book
 

Starting from version 2.6, the kernel has undergone considerable changes, and now it is necessary to program as shown in Listing 13.2.

Listing 13.2: The skeleton of the simplest module for version 2.6 kernels
image from book
 #ifdef LINUX26         static int __init my_init() #else         int init_module() #endif #ifdef LINUX26         static void __exit my_cleanup #else         int cleanup_module() #endif #ifdef LINUX26         module_init(my_init);         module_exit(my_cleanup); #endif 
image from book
 

More detailed information on this topic can be found in official Linux documentation (/usr/src/linux/Documentation/modules.txt) , on the following man page: man -k module . It is also possible to download or buy a copy of the book Linux Kernel Internals , which can be easily found in e_Mule. Anyway, the module just written must be compiled by means of the following command: gcc -c my_module.c -o my_module.o (it is strongly recommended that you use optimization, which can be achieved by using -02 or -03 command-line options). After that, load it into the kernel by issuing the following command: insmod my_module.o . Only root can load modules. Obtaining root is a special topic, deserving a separate discussion; it won't be considered here. To ensure that the module is loaded automatically with the operating system, add it to the /etc/modules file.

The lsmod (or dd if=/proc/modules bs=1) command displays the list of loaded modules, and the rmmod my_module unloads the module from the memory. Pay special attention to the lack of file name extension in the latter case. The list of loaded modules displayed by the lsmod command is shown in Listing 13.3 (the line displayed in the example module is in bold).

Listing 13.3: Modules displayed by the Ismod command
image from book
 Module                 Size  Used by    Tainted: P  my_module               240   0  (unused)  parport_pc            25128   1  (autoclean) lp                     7460   0 processor              9008   0  [thermal] ... fan                    1600   0  (unused) button                 2700   0  (unused) rtc                    7004   0  (autoclean) BusLogic              83612   2  (autoclean) ext3                  64388   1  (autoclean) 
image from book
 

When new modules are loaded unexpectedly, administrators inevitably become more vigilant. Therefore, before starting any activities on the remote machine, the hacker must be disguised as carefully as possible. I know three methods of disguising :

  • Excluding the module from the list of modules (known as the J.B. method; see the modnidel.c file). This method is extremely unreliable, because it hinders normal operation of ps, top , and some other utilities and often crashes the system.

  • Trapping attempts at accessing /proc/modules . This is known as the Runar Jensen method. It was published on Bugtraq and can be implemented the same way as trapping all other attempts at accessing the file system. This method is too bulky and unreliable. Furthermore, it is powerless against the dd if = /proc/modules bs = 1 command.

  • Overwriting the module info structure, also known as the Solar Designer method. It was described in the " Weakening the Linux Kernel " article published in issue 52 of the Phrack e-zine. This method is elegant and reliable; therefore, I will describe it in more detail.

All information about the module is stored in the module info structure contained within the sys_init_module() system call. Having prepared the module for loading and filled the module info structure as appropriate, it passes control to the init_module function (see man init_module ). An interesting feature of the kernel is that unnamed modules are not displayed without references. Thus, to remove the module from the list it is enough to reset to zero the name and refs fields. This can be done easily. However, determining the address of the module info structure itself is more difficult. The kernel is not interested in providing this information to the first hacker that comes along. Therefore, hackers must proceed quietly . When investigating the garbage remained in the registers at the moment of passing control to init_module , Solar Designer detected that one of the garbage files there was the pointer to module info ! In this version of the kernel, this was the EBX register; in other versions this might be different or not even exist. Furthermore, there is a special patch for older kernels that closes this back door (however, not every administrator takes a trouble to install it). Nevertheless, the effective module info address can be easily determined by disassembling . To be more precise, it will not be the module info address (because memory is automatically allocated to it) but the address of machine instruction that references module info . It should be noted that in every kernel version this address would be different.

The simplest example of disguising appears as shown in Listing 13.4 (by the way, there was a misprint in Phrack ” ref instead of refs ).

Listing 13.4: Disguising the module using the Solar Designer method
image from book
 int init_module() {       register struct module *mp asm("%ebx");  // Substitute the register,                                                // in which your kernel                                                // stores the module info                                                // address.       *(char*)mp -> name = 0;                                                // Overwrite the module name.       mp -> size = 0;                          // Overwrite the size.       mp -> refs = 0;                          // Overwrite references. } 
image from book
 

If the module info address is chosen incorrectly, the system is most likely to crash or lock viewing the list of modules, which, most probably, will immediately warn the administrator (Fig. 13.2). However, the hacker has another variant on hand.

image from book
Figure 13.2: Consequences of disguising the module using the Solar Designer method ” commands such as insmod/Ismod/rmmod cease to work

The hacker can view the list of installed modules, find the least needed one, unload it from the memory, and load the hackish module under the same name. If the hacker is lucky, administrator won't notice anything



Shellcoder's Programming Uncovered
Shellcoders Programming Uncovered (Uncovered series)
ISBN: 193176946X
EAN: 2147483647
Year: 2003
Pages: 164

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net