linux隐藏文件:一种Linux下隐藏文件的新思路方法

. 概述
      目前通用隐藏文件思路方法还是hooksys_getdents64系统 大致流程就是先原始
sys_getdents64系统然后在在buf中做过滤修改sys_call_table是比较原始rk技术了碰到好点管理员 基本上gdb下vmlinux就能检测出来 如何想做到更加隐蔽就要
寻找新技术 inline hook也是目前比较流行做法不容易检测本文通过讲解种利用
inline hook内核中某 来达到隐藏文件思路方法

2. 剖析sys_getdnts64系统
      想隐藏文件 还是要从sys_dents64系统下手 去看下它在内核中是如何实现
代码在linux-2.6.26/fs/readdir.c中:

asmlinkage long sys_getdents64(unsigned fd, struct linux_dirent64 __user * dirent, unsigned count)
{
struct file * file;
struct linux_dirent64 __user * lastdirent;
struct getdents_callback64 buf;
error;

error = -EFAULT;
(!access_ok(VERIFY_WRITE, dirent, count))
goto out;

error = -EBADF;
file = fget(fd);
(!file)
goto out;

buf.current_dir = dirent;
buf.previous = NULL;
buf.count = count;
buf.error = 0;

error = vfs_readdir(file, filldir64, &buf);
(error < 0)
goto out_putf;
error = buf.error;
lastdirent = buf.previous;
(lastdirent) {
typeof(lastdirent->d_off) d_off = file->f_pos;
error = -EFAULT;
(__put_user(d_off, &lastdirent->d_off))
goto out_putf;
error = count - buf.count;
}

out_putf:
fput(file);
out:
error;
}

      首先access_ok来验证是下用户空间dirent地址是否越界是否可写 接着根据fd
利用fget找到对应file结构 接着出现了个填充buf数据结构操作先不管它是干什么
接着往下看
vfs_readdir(file, filldir64, &buf);
      最终还是vfs层vfs_readdir来获取文件列表 到这我们可以是否通过hook
vfs_readdir来达到隐藏文件效果呢 继续跟踪vfs_readdir看看这个想法是否可行

源代码在同文件中:

vfs_readdir(struct file *file, filldir_t filler, void *buf)
{
struct inode *inode = file->f_path.dentry->d_inode;
res = -ENOTDIR;
(!file->f_op || !file->f_op->readdir)
goto out;

res = security_file_permission(file, MAY_READ);
(res)
goto out;

res = mutex_lock_killable(&inode->i_mutex);
(res)
goto out;

res = -ENOENT;
(!IS_DEADDIR(inode)) {
res = file->f_op->readdir(file, buf, filler);
file_accessed(file);
}
mutex_unlock(&inode->i_mutex);
out:
res;
}

EXPORT_SYMBOL(vfs_readdir);

      它有3个参数个是通过fget得到file结构指针 第2个通过结合上下文可得知这是个回调用来填充第3个参数开始用户空间指针 接着看看它具体是如何实现通过security_file_permission验证后 在用mutex_lock_killable对inode结构加了锁
然后ile->f_op->readdir(file, buf, filler);通过进底层来对buf进行填充
这个buf就是用户空间strcut dirent64结构开始地址

      所以到这里我们可以断定通过hook vfs_readdir对buf做过滤还是可以完成隐藏文件功能而且vfs_readdir地址是导出 这样就不用复杂思路方法找它地址了但是还有没有更进思路方法呢? 前面不是提到过有个filldir64 它用来填充buf结构也许通过hook它来做更隐蔽隐藏文件思路方法 继续跟踪filldir64看看它是如何实现

filldir64(void * __buf, const char * name, namlen, loff_t off,
u64 ino, unsigned d_type)
{
struct linux_dirent64 __user *dirent;
struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf;
reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 1, (u64));

buf->error = -EINVAL;
(reclen > buf->count)
-EINVAL;
dirent = buf->previous;
(dirent) {
(__put_user(off, &dirent->d_off))
goto efault;
}
dirent = buf->current_dir;
(__put_user(ino, &dirent->d_ino))
goto efault;
(__put_user(0, &dirent->d_off))
goto efault;
(__put_user(reclen, &dirent->d_reclen))
goto efault;
(__put_user(d_type, &dirent->d_type))
goto efault;
(copy_to_user(dirent->d_name, name, namlen))
goto efault;
(__put_user(0, dirent->d_name + namlen))
goto efault;
buf->previous = dirent;
dirent = (void __user *)dirent + reclen;
buf->current_dir = dirent;
buf->count -= reclen;
0;
efault:
buf->error = -EFAULT;
-EFAULT;
}

先把参数buf转换成struct getdents_callback64结构指针
struct getdents_callback64 {
struct linux_dirent64 __user * current_dir;
struct linux_dirent64 __user * previous;
count;
error;
};
current_dir始终指向当前struct dirent64结构filldir64每次只填充个dirent64结构
它是被file->f_op->readdir循环 通过代码可以看出是把dirent64结构相关项拷贝到
用户空间dirent64结构中 然后更新相应指针

所以通过分析filldir64代码 可以判定通过判断参数name看它是否是我们想隐藏文件
0就好了

3. 扩展

      通过分析sys_getdents64代码实现我们可以了解到通过hook内核思路方法来完成
rootkit功能是很简单和方便 关键你能了解它实现逻辑 对linux平台来说阅读内核
源代码是开发rootkit根本 如何hook? 最简单就是修改前几个字节jmp到我们
中去 在新完成类似功能 根本不必在跳回原 有了内核源代码在手
如何实现我们就如何copy过去给它在实现 所在linux实现rk也有很方便
就是它内核源代码是公开 好好阅读源代码吧 你会有更多收获

Tags:  linux查找文件 linux删除隐藏文件 linux显示隐藏文件 linux隐藏文件

延伸阅读

最新评论

发表评论