Intercepting sys_unlink( ) Using System.map

In the previous section, we looked at how to obtain the address of sys_call_table by searching kernel memory. However, if the kernel’s System.map file is available, you can use it to obtain the location of sys_call_table, and this location can be hardcoded into the LKM. An LKM that denies the deletion of files by intercepting sys_unlink( ) is a good illustration. First, find the location of sys_call_table from System.map:

[notroot]$ grep sys_call_table /boot/System.map
c044fd00 D sys_call_table

The module’s source code hardcodes the address to obtain sys_call_table:

*(long *)&sys_call_table=0xc044fd00;

The module alters the system call table to point __NR_unlink to hacked_sys_unlink, and stores the original location of sys_unlink( ):

original_sys_unlink =(void * )xchg(&sys_call_table[_ _NR_unlink],
hacked_sys_unlink);

The hacked_sys_unlink( ) function returns -1 whenever it is called. It never invokes the original sys_unlink( ):

asmlinkage long hacked_sys_unlink(const char *pathname)
{
        return -1;
}

This prevents any process from being able to delete any file on the system.

intercept_unlink.c

Following is the full source code of our intercept_unlink LKM:

#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/syscalls.h> #include <linux/unistd.h> MODULE_LICENSE ("GPL"); unsigned long *sys_call_table; asmlinkage long (*original_sys_unlink) (const char *pathname); /*return -1. this will prevent any process from ...

Get Network Security Tools now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.