Finding the Linux System Call table in 2.6 series kernels
I have been modifying Sebek to get it to work in more recent 2.6 series (~2.6.18) kernels and ran into some snags. Most notably, I could not intercept/redirect/wrap any system calls. As it turns out, Sebek couldn't find the system call table. The code Sebek was using to find the system call table is 100% identical to the code found in this article on KernelTrap.
Unfortunately, that code is outdated as either loops_per_jiffy, boot_cpu_data, or sys_call_table appear to have been moved. I found that I could find the system call table between unlock_kernel and loops_per_jiffy and have modified the code as follows.
// -----------------------------------------------------------------------------
// Sys Call Table Address
// -----------------------------------------------------------------------------
unsigned long **find_sys_call_table(void)
{
unsigned long **sctable;
unsigned long ptr;
extern int loops_per_jiffy;
sctable = NULL;
for (ptr = (unsigned long)&unlock_kernel;
ptr < (unsigned long)&loops_per_jiffy;
ptr += sizeof(void *))
{
unsigned long *p;
p = (unsigned long *)ptr;
if (p[__NR_close] == (unsigned long) sys_close)
{
sctable = (unsigned long **)p;
return &sctable[0];
}
}
return NULL;
}
I have try this code on kernel 2.6.26/.27 and i get :
Cannot find the system call address
and dont load the kernel
Any idea if lasts kernels change something ?
Thanks
Did you compiled the kernel by yourself or are you using a "precompiled kernel"?
It works fine for me on a 2.6.27 kernel i compiled myself.
Hello.
With this method, i can't find the system call table :
[Sablov@box]~/LKM$ insmod plop.ko
insmod: error inserting 'plop.ko': -1 Operation not permitted
(i'm root of course)
[Sablov@box]~/LKM$ dmesg
Cannot find the system call address
My kernel is : 2.6.18-5-xen-amd64 #1 SMP x86_64
The problem is due to my kernel ? to SMP ?
Thanks for this great article.
error: conflicting types for ‘loops_per_jiffy’
include/linux/delay.h:10: error: previous declaration of ‘loops_per_jiffy’ was here
Can you show me please, how i can correct those?
Thanks...
include file smp_lock.h
#include <linux/smp_lock.h>Great, thanks for the update!
this method seems hacky, is there any better way we may find to export linux syscall table? or should linux kernel provide some mechenisms for such a common requirement?
There used to be mechanisms for it, but they were removed because they were more frequently than not being used by rootkits. You're right though, this method is very hackish.
I'm trying to make sebek work in a RHEL5 system, with no luck till now. I got to this page and tried to apply the mod you posted, but it seems that both of the two syscall.c I'm trying to use are different from yours. One of them doesn't even have the find_sys_call_table function and in the other one it looks like this:
u32 **find_sys_call_table(u32 sc_asm)
As I think you've been able to make it work, could it be possible to know where did you get sebek sources from? I'm going nuts with this...
Angel,
I'm pretty sure I was using Sebek 3.2.0b for Linux 2.6-series kernels found on the Sebek page on honeynet.org. I had to put the project on hold due to re-provisioning my dev server for another project, but when I get back to my home state I should be able to put a dev system together again to verify.
Another option would be if you could send me the sebek code you are using, if it's possible.
Anyway, thanks for your time.
Angel
[root@vcentOS code1]# make
make -C /lib/modules/`uname -r`/build M=`pwd` modules
make[1]: Entering directory `/usr/src/kernels/2.6.18-53.1.14.el5-i686'
CC [M] /home/test/tmp/code1/find_addr1.o
/home/test/tmp/code1/find_addr1.c: In function 'find_sys_call_table':
/home/test/tmp/code1/find_addr1.c:23: error: 'unlock_kernel' undeclared (first use in this function)
/home/test/tmp/code1/find_addr1.c:23: error: (Each undeclared identifier is reported only once
/home/test/tmp/code1/find_addr1.c:23: error: for each function it appears in.)
/home/test/tmp/code1/find_addr1.c: In function 'init_lkm':
/home/test/tmp/code1/find_addr1.c:99: warning: assignment from incompatible pointer type
/home/test/tmp/code1/find_addr1.c:106: warning: format '%8x' expects type 'unsigned int', but argument 2 has type 'void **'
/home/test/tmp/code1/find_addr1.c: In function 'exit_lkm':
/home/test/tmp/code1/find_addr1.c:134: warning: assignment makes pointer from integer without a cast
make[2]: *** [/home/test/tmp/code1/find_addr1.o] Error 1
make[1]: *** [_module_/home/test/tmp/code1] Error 2
make[1]: Leaving directory `/usr/src/kernels/2.6.18-53.1.14.el5-i686'
make: *** [all] Error 2
It looks like you're missing an include, can you show me what you have for find_addr1.c?
The prototype for unlock_kernel is as follows:
static inline void unlock_kernel(void)Post new comment