kstat - 从核心结构直接得到信息 著者 FuSyS [S0ftPj|BFi] 翻译 by patching heroes http://www.patching.net 概要 kstat [-i iff] [-P] [-p pid] [-M] [-m addr] [-s] 详述 kstat 从核心结构直接显示信息. 它能成功访问 /dev/kmem文件 因此,执行它需要 root 或 kmem 权限. 它很有用,因为我们虽然能访问自己的系统,但是我们不能相信从系统 和应用程序的所有输出。 以前我们通过在 kmem中用 /proc 来获得系统的信息。通过在核心 内存中查看,我们能得到我们的主机和它进程的各个信息。今天它 还很管用,对于如果我们不知道我们的 ps 已经被改过,或者系 统的调用已经被 hijacked 或 patched 过。但是 /proc 还能被攻 击者利用来修改 kmem,它对系统管理员和攻击者来说都能利用。 所以, kstat 的产生就是为了帮助管理员来检查关键的地方,象 进程, NICs, LKMs 还有系统调用等。 选项 [-i] iff 可以被指定为所有的或一个名字 (如:eth0). 在这种 选项下,我们能倒出要查询的接口的信息,而且能更清晰看到 网卡是否处于混杂模式下。 [-P] 在这种选项下,我们能显示每个运行进程的信息。象 ps(1) ,我们能得到一般的 uid 和 gid 信息。 [-p] pid 是我们要查询的进程的 id 。它倒出来的信息是这个 进程的权能和细节。 [-M] 它倒出核心中的可装载模块的链表。 执行前,我们可以先装 载一个简单的,什么也不干的 lkm 来得到这个链表的首地址。 倒完后,那个模块会被删除,链表的末尾一般就是kernel_module。 你在编译时内核时必须导出kernel_module符号。 [-m] 要查询模块的十六进制格式的地址 ( 0x 开头的格式 ) 这个选项会显示它在它的结构中的名字,大小,标志和第一 次注册的标号。[请注意隐藏的模块一般不注册新的标号到 出口]. [-s] 这个选项,我们将倒出核心系统调用的所有地址. 如果探察出 的地址和原来的地址不同,就会给出一个警告。[请注意,为了 用这个选项,你必须先提供一个更新的 System.map 文件, 这个 文件你可以在Makefile中指定] 例子 (1) 这个小例子将简单的比较一个正常的 ps 和运行 kstat 后的结果, 来找被搅乱的那个。 kstat -P|cut -f 1|grep [0-9]|cut -d -f 4 和 ls /proc/ |grep [0-9]|cut -d -f 1|sort -n 将给你两种格式的被比较的pid的列表。 (2) 如果你的核心中有一个隐藏的模块,你可以探察他们结构的链表, 让我们设想这种情况:,一个恶意的模块被加入到sys_query_module 来阻止 lsmod 查询和 sys_read 来防止管理员来通过 /proc/modules 找到它. SLaCKy:~/KSTAT# lsmod Module Size Used by ppp_deflate 40536 0 (unused) serial_cs 5040 0 (unused) pcnet_cs 10052 1 8390 5860 0 [pcnet_cs] ds 6088 2 [serial_cs pcnet_cs] i82365 21276 2 pcmcia_core 43424 0 [serial_cs pcnet_cs ds i82365] bsd_comp 3620 0 SLaCKy:~/KSTAT# cat /proc/modules serial_cs 5040 0 (unused) pcnet_cs 10052 1 8390 5860 0 [pcnet_cs] ds 6088 2 [serial_cs pcnet_cs] i82365 21276 2 pcmcia_core 43424 0 [serial_cs pcnet_cs ds i82365] bsd_comp 3620 0 (unused) SLaCKy:~/KSTAT# ./kstat -M Module Address knull 0xc283a000 oMBRa 0xc2838000 serial_cs 0xc2835000 pcnet_cs 0xc282f000 8390 0xc282c000 ds 0xc2827000 i82365 0xc281c000 pcmcia_core 0xc2810000 bsd_comp 0xc280e000 knull 是什么? 就是一个什么也不做的 LKM. 它被 kstat 装载来获 得链表的初始地址,然后它会被删除的,因此不用担心。你能在相关 的目录找到它的源码。 现在我们能探察它: SLaCKy:~/KSTAT# ./kstat -m 0xc2838000 Probing memory at 0xc2838000 ! Name: oMBRa Size: 4096 Flags: MOD_RUNNING First Registered Symbol: open at 0xc2838f88 然而有一些别的方法可以搞乱核心中的模块。象结构模块的成员 *name,size 和 *refs是zero的话, 这种情况下,它很容易 发现。因为所有的模块会从 lsmod(1) 输出中消失,还有个象这 样的出错: SLaCKy:~/KSTAT# lsmod Module Size Used by lsmod: QM_INFO: Invalid argument 此外,我们将不能装载更多的模块,象 knull. 在这时候,我们能 试图定位第一个合法模块,然后探察高位内存地址来找出空的名字 和零地址的模块结构。 为了顺利完成,有两个方法。我们必须知道我们定位的模块的地址 范围,或者通过搜索它的名字来找到第一个合法模块的地址,然后 在 /dev/kmem 来指向它的内存位置。 你能看到 ksyms -m 的输出时,说明所有的模块被包含在一个固定 的范围内,一般是在 0x1000 和 0x3000 地址之间跳转。 因此,通过知道首地址(我们知道哪一个模块在初始化时在哪儿被 装载),我们能用 kstat -m 来做尝试。 在当前的 kstat 版本中,搜索引擎还没有具备,因此要探察模块 结构必须要提供一个地址。 查看System.map文件的系统调用的位移,和通过读/dev/kmem文件 找出的系统调用地址来比较判断是否有恶意lkm劫持系统调用。 (3) 当一个入侵者的 LKM 嵌入到你的系统会怎样?大多数情况,你 不能再相信你的核心了。 最坏的情况是你还没有发现他的 LKM 已经嵌入了。kstat 可以帮你 探察所有的系统调用地址(一般被由指向到系统调用表劫持的) 通过比较一个最新的 System.map文件和由 /dev/kmem 的探察表, 我们可以判断该系统调用是否在它应该在的地方。 如: SLaCKy:~/KSTAT# ./kstat -s SysCall Address sys_exit 0xc011608c sys_fork 0xc0107668 sys_read 0xc012356c (snip) sys_creat 0xc01231c4 sys_link 0xc012ad6c sys_unlink 0xc283838c WARNING! Should be at 0xc012abb8 sys_execve 0xc2838168 WARNING! Should be at 0xc01076c4 sys_chdir 0xc2838440 WARNING! Should be at 0xc0122a08 (snip) sys_socketcall 0xc2838730 WARNING! Should be at 0xc01534b0 sys_syslog 0xc011269c (snip) sys_vm86 0xc0109e70 sys_query_module 0xc28388bc WARNING! Should be at 0xc0115058 sys_query_module is, BTW, probably hijacked to prevent be at 0xc01534b0 sys_syslog 0xc011269c (snip) sys_vm86 0xc0109e70 sys_query_module 0xc28388bc WARNING! Should be at 0xc0115058 sys_query_module is, BTW, probably hijacked to prevent lsmod to show the rogue LKM. So we can try to locate it as well. 文件 /dev/kmem - kernel memory 相关 kstat(1) BSD 版本