分享
 
 
 

可加载内核模块:入侵响应新领域分析

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

如果在入侵事件调查中,传统的工具完全失效了,你该怎么办?当我在对付入侵者已经加载的内核模块时,就陷入了这种困境。由于从用户空间升级到了内核空间,LKM方式的入侵改变了以往使用的入侵响应的技术。一旦内核空间遭破坏,影响将覆盖到整个用户空间,这样入侵者无须改动系统程序就能控制他们的行为。而用户即使将可信的工具包上传到被入侵的主机,这些工具也不再可信。下面我将揭示恶意的内核模块如何工作,并且给出一些我开发的对付此类入侵的工具。

LKM概述

LKM的存在对系统管理员是个福音,对入侵检测却是个噩梦。lkm最初被设计用来无须重新启动而改变运行中的内核,从而提供一些动态功能。动态内核提供了对诸如新文件系统类型和网卡等设备的额外支持。此外,由于内核模块能够访问内核的所有调用和存储区,它能不受控制地改动整个操作系统的各个部位,因而所有调用和内存常驻的结构都有被恶意内核模块修改的危险。

lkm的一个臭名昭著的例子是knark。一旦knark编译并加载到入侵主机,将改变系统调用表从而改变操作系统的行为。系统调用表常驻在内核空间,基本上是提供给用户级别程序访问操作系统的入口。大多数unix系统在手册的第二部分给出syscalls的正式定义。一旦内核作为用户空间运行,OS将把命令行上运行的所有命令和调用映像到系统调用表中。因此当knark改变系统调用表时也就改变了用户命令的执行。knark改动了以下的重要系统调用。

* getdents - 获得目标路径的目录项内容(即文件和子目录)。通过修改这个调用,knark实现对用户程序隐藏文件和目录。

* kill - 向进程发送信号,通常是杀掉进程。修改过的调用将使用无用的信号31,触发设置进程为"hidden"状态。当进程在hidden状态时,它在/proc中的纪录被删除,从而实现了对ps命令隐身。信号32被用来解除隐藏状态。

* read - 读取目标文件的内容。knark通过修改此调用实现对netstat隐藏入侵者的连接。

* ioctl - 改变文件和设备的状态。通过修改此调用,knark能够隐藏网卡的混杂位,同时在调用中插入了隐藏文件的函数。

* fork - 派生新进程。knark修改用来隐藏一个隐藏的父进程所派生的所有子进程。

* execve - 执行一个程序。每次用户在命令行下输入命令时调用。一旦此调用被劫持,内核模块可以控制命令的选择和运行。knark使入侵者可以把一个程序指向另一个,如同符号连接一样,而不留下罪证。knark控制了execve后,任何你希望执行的程序都有可能是入侵者的替代品。

* settimeofday - 设置系统时间。knark用来监控预定的时间。当这些预定时间之一被送给此系统调用时,knark可以触发某些管理任务或者立即赋予当前用户root的用户和组id。这样就无需更改到suid的shell而直接获得root权限。

由于系统调用被更改,那些管理工具的功能也被更改了。netstat将永远不报告网卡的混杂模式,来自特定地点的连接也被隐藏。ps和top命令不会报告隐藏的进程,因为/proc中没有信息。ls将跳过隐藏的文件和目录。所有这些,都是因为此类工具依靠操作系统提供信息,而入侵者在控制了操作系统后就能够向来自用户空间的请求反馈虚假情报,并且无需改动netstat,ps,top和ls程序的二进制文件。因此,tripwire一类的文件系统校验工具对这类工具将失效,也无法防备knark的执行重定向功能。如果入侵者将hackme连接到cat上,每次cat被调用,实际上是hackme在执行。这样,cat仍然保留在系统上,md5校验码也没有改变,但执行的功能却改变了。

更糟糕的是,将一套新的工具上传到被knark入侵的主机也无济于事。即使是可信的工具一样要使用系统调用,于是他们也变得不再可信。目前还无法绕过入侵者在内核级别的陷阱,除非我们也进入内核空间。基于此,我开发了检测系统是否安装了恶意LKM的工具。

之前有一点我们没有提及,lsmod会报告装载了knark.o模块。不幸的是,入侵者能轻易的将此信息抹去。knark同时还包括了另一个LKM叫做modhide,能够隐藏自身以及上一个模块。一旦模块隐藏,如果不重启动机器就无法卸载,而且没有简单的方法检测到模块的加载,所有的相关信息都不见了。正如之前介绍的,knark的所有功能令其成为终极秘密武器。

预防方法

阻止LKM破坏显然是最佳解决方案。我们有几种方法能够提前预防lkm。可以通过保护系统调用表来预防大部分的恶毒lkm。我们可以构造一个简单的lkm,定时的或者在其他模块加载时监控系统调用表。如果它发现系统调用表改变了,可以通知系统管理员甚至将调用表修改回原来的值。下面的例子能很好的工作在linux 2.2和2.4上。如果你的机器有超过一个处理器,可以用如下命令编译:gcc -D __SMP__ -c syscall_sentry.c。如果是单处理器,去掉-D __SMP__就行了。编译成功后,用insmod加载。

/*

* This LKM is designed to be a tripwire for the sys_call_table.

*/

#define MODULE_NAME "syscall_sentry"

/* This definition is the time between periodic checks. */

#define TIMEOUT_SECS 10

#define MODULE

#define __KERNEL__

#include<linux/module.h

#include<linux/config.h

#include<linux/version.h

#include<linux/kernel.h

#include<linux/sys.h

#include<linux/param.h

#include<linux/sched.h

#include<linux/timer.h

#include<sys/syscall.h

/* This function is a simple string comparison function */

static int mystrcmp( const char *str1, const char *str2)

{

while(*str1 && *str2)

if (*(str1++) != *(str2++))

return -1;

return 0;

}

/* This function builds a timer struct for versions of linux

* less than linux 2.4. It is used to set a timer

*/

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)

/* Initializes a timer */

void init_timer(struct timer_list * timer)

{

timer-next = NULL;

timer-prev = NULL;

}

#endif

/* This is our timer */

static struct timer_list syscall_timer;

/* This is the system’s syscall table */

extern void *sys_call_table[];

/* This is the saved, valid syscall table */

static void *orig_sys_call_table[ NR_syscalls ];

/* This function is needed to protect yourself */

static unsigned long (*orig_init_module) (const char *, struct module*);

/* This function checks the syscalls for changes

* and changes them back to the original if it has

* been changed.

*/

static int check_syscalls( void )

{

int i;

/* Add a new timer for our next check */

del_timer( &syscall_timer );

init_timer( &syscall_timer );

syscall_timer.function = (void *)check_syscalls;

syscall_timer.expires = jiffies + TIMEOUT_SECS * HZ;

add_timer( &syscall_timer );

for ( i = 0; i < NR_syscalls - 1; i++ )

{

if (orig_sys_call_table[i] != sys_call_table[i])

{

printk(KERN_INFO " SysCallSentry - sys_call_table has been

modified in entry %d! ", i);

sys_call_table[i] = orig_sys_call_table[i];

}

}

return 1;

}

/* Check sys_call_table anytime a new module is loaded. */

static int long sys_init_module_wrapper( const char *name, struct

module *mod )

{

int i;

int res = (*orig_init_module)(name,mod);

for ( i = 0; i < NR_syscalls - 1; i++ )

{

if (orig_sys_call_table[i] != sys_call_table[i])

{

printk( KERN_INFO " SysCallSentry - sys_call_table has been

modified in entry %d! ", i);

sys_call_table[i] = orig_sys_call_table[i];

}

}

return res;

}

/* Module Init Code */

static int init_module (void)

{

int i;

printk(KERN_INFO " SysCallSentry Inserted ");

/* Initiate the periodic timer */

init_timer( &syscall_timer );

/* Save the old values of the sys_call_table */

orig_init_module = sys_call_table[SYS_init_module];

/* Wrap the init_module syscall. This will check to see

* if any calls have been altered when a new module loads.

*/

sys_call_table[SYS_init_module] = sys_init_module_wrapper;

for ( i=0; i < NR_syscalls - 1; i++ )

{

orig_sys_call_table[i] = sys_call_table[i];

}

/* Start our first check */

check_syscalls();

return(0);

}

/* Module Cleanup Code */

static void cleanup_module (void)

{

/* Return system status to the original */

sys_call_table[SYS_init_module] = orig_init_mo

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有