如何检测Linux内核的Rootkit
最近一段时间搞了些Rootkit攻略,每个方法都比较彻底,无论是隐藏进程,还是隐藏CPU利用率,隐藏TCP连接,隐藏文件,甚至隐藏CPU风扇的狂转,均采用了相对底层的方案,一般的Rootkit检测很难检测到。所谓的一般的Rootkit就是那些通常的hook,比方说hook系统调用,hook proc/sys接口,hook library等等,但是这些均是掩耳盗铃的鸵鸟策略,均不彻底。针对这些Ro.
·
最近一段时间搞了些Rootkit攻略,每个方法都比较彻底,无论是隐藏进程,还是隐藏CPU利用率,隐藏TCP连接,隐藏文件,甚至隐藏CPU风扇的狂转,均采用了相对底层的方案,一般的Rootkit检测很难检测到。
所谓的一般的Rootkit就是那些通常的hook,比方说hook系统调用,hook proc/sys接口,hook library等等,但是这些均是掩耳盗铃的鸵鸟策略,均不彻底。针对这些Rootkit,业内已经有很多的方法来检测:
- 定期检测重要文件的校验码。
- 检测text段内存。
- …
然而我一一试了,检测不到我这些Rootkit。
最近很多朋友同事提醒我,为了不让这些方法诉诸恶意,我必须提供破解方案。
以下的代码可以检测我自己的Rootkit:
#include <linux/module.h>
#include <linux/kallsyms.h>
#define TEXT_SIZE 0xff0000
static int __init checker_init(void)
{
s32 offset;
int i = 0;
unsigned char *pos;
unsigned int *code;
unsigned long *lcode, target;
char *__text;// = 0xffffffff81000000;
__text = (void *)kallsyms_lookup_name("_text");
for (i = 0; i < TEXT_SIZE; i++) {
pos = &__text[i];
code = (unsigned int *)pos;
// 0xe5894855 的含义就是 "push %rbp; mov %rsp,%rbp" 的字节码
if (*code == 0xe5894855) {
pos -= 5;
lcode = (unsigned long *)pos;
// 0x8948550000441f0f 的含义是 "nopl 0x0(%rax,%rax,1) [FTRACE NOP]" 的字节码
if (*lcode != 0x8948550000441f0f && *pos == 0xe8) {
offset = *(s32 *)&pos[1];
target = (unsigned long)__text + i + offset;
// 如果call指令的target越过了内核的text区域,则有被hook的可能
if (target > (unsigned long)__text + TEXT_SIZE) {
// 这里需要根据输出检测是不是“正规的kaptch”,若不是,则报告给经理!
printk("## %llx %llx %x %llx\n", *lcode, __text + i - 5, offset, target);
}
}
}
}
return -1;
}
module_init(checker_init);
MODULE_LICENSE("GPL");
我加载了之前的那个隐藏进程和TCP连接(仅仅hook tcp的seq show函数的版本)的rootkit,然后加载我这个新模块,看看效果:
[ 2234.422336] ## 8948551f0650ebe8 ffffffff810b4f10 1f0650eb ffffffffa011a000
[ 2234.422340] ## 8948551f06504be8 ffffffff810b4fb0 1f06504b ffffffffa011a000
[ 2234.430383] ## 8948551eb9d16be8 ffffffff81585e90 1eb9d16b ffffffffa0123000
我们看看这些地址意味着什么。
crash> dis ffffffff810b4f10 1
0xffffffff810b4f10 <account_user_time>: callq 0xffffffffa011a000
crash> dis ffffffff810b4fb0 1
0xffffffff810b4fb0 <account_system_time>: callq 0xffffffffa011a000
crash> dis ffffffff81585e90 1
0xffffffff81585e90 <tcp4_seq_show>: callq 0xffffffffa0123000
是不是一下子就查出来了呢!
总结下来就是:
- 检测内核text段的所有call/jmp指令,只要target越过了text段范围,即有可能被hook了!
至于说如何扫描call/jmp指令,那就是另一个话题了。
背后的意思是, 一般而言,内核函数不会调用模块里的函数的。
再次提示,不要拿这些手艺去做不好的事情,不然经理会不高兴。
浙江温州皮鞋湿,下雨进水不会胖!
更多推荐
已为社区贡献63条内容
所有评论(0)