本文总结Linux Rookit类型,研究隐藏技术与手段...
0x01 基础知识
1. 定义
Rootkit是一种特殊的恶意软件,它的功能是在安装目标上隐藏自身及指定的文件、进程和网络链接等信息。Rootkit通过加载特殊的驱动,修改系统内核,进而达到隐藏信息的目的。
2. 类型
1)应用级rootkit
通过替换login、ps、ls、netstat等系统工具,或修改.rhosts等系统配置文件等实现隐藏及后门
2)内核级rootkit
加载内核模块:Linux 内核可以在运行时加载内核模块(例如设备驱动程序)。这允许攻击者插入一个覆盖内核系统调用的模块,以返回不正确的值(例如,不列出某些文件),或提供对攻击者有用的新功能(例如,为某些进程提供 root 权限)
操作内存修改内核:指在系统不支持lkm机制时修改内核的一种方法,通过写入 /dev/kmem、/dev/mem等设备可以在运行时覆盖内核,从而执行任意修改
3)硬件级rootkit
主要指bios rootkit,可以在系统加载前获得控制权,通过向磁盘中写入文件,再由引导程序加载该文件重新获得控制权,也可以采用虚拟机技术,控制整个操作系统运行
3. 目的功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| 1. 隐藏文件 通过strace ls可以发现ls命令其实是通过sys_getdents64获得文件目录的,因此可以通过修改sys_getdents64系统调用或者更底层的readdir实现隐藏文件及目录
2. 隐藏进程 隐藏进程的方法和隐藏文件类似,ps命令是通过读取/proc文件系统下的进程目录获得进程信息的,只要能够隐藏/proc文件系统下的进程目录就可以达到隐藏进程的效果,即hook sys_getdents64和readdir等。
3. 隐藏连接 netstat命令是通过读取/proc文件系统下的net/tcp和net/udp文件获得当前连接信息,因此可以通过hook sys_read调用实现隐藏连接,也可以修改tcp4_seq_show和udp4_seq_show等函数实现。
4. 隐藏模块 lsmod命令主要是通过sys_query_module系统调用获得模块信息,可以通过hook sys_query_module系统调用隐藏模块,也可以通过将模块从内核模块链表中摘除从而达到隐藏效果
5. 嗅探工具 1) 嗅探工具可以通过libpcap库直接访问链路层,截获数据包 2) 也可以通过linux的netfilter框架在IP层的hook点上截获数据包 嗅探器要获得网络上的其他数据包需要将网卡设置为混杂模式,这是通过ioctl系统调用的SIOCSIFFLAGS命令实现的,查看网卡的当前模式是通过SIOCGIFFLAGS命令,因此可以通过hook sys_ioctl隐藏网卡的混杂模式
6. 密码记录 密码记录可以通过hook sys_read系统调用实现,比如通过判断当前运行的进程名或者当前终端是否关闭回显,可以获取用户的输入密码。hook sys_read还可以实现login后门等其它功能
7. 日志擦除 传统的unix日志主要在 1) /var/log/messages 2) /var/log/lastlog 3) /var/run/utmp 4) /var 5) /log/wtmp下 可以通过编写相应的工具对日志文件进行修改,还可以将HISTFILE等环境变设为/dev/null隐藏用户的一些操作信息
8. 内核后门 1) 本地的提权后门 本地的提权可以通过对内核模块发送定制命令实现 2) 网络的监听后门 网络内核后门可以在IP层对进入主机的数据包进行监听,发现匹配的指定数据包后立刻启动回连进程
|
0x02 隐藏技术
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| 1. 灵活的指令配置 1) 通过创建/proc下虚拟目录的读写接口函数接收ring3层的指令、指令灵活配置 2) 通过netlink技术实现ring3和ring0的通信,向rootkit下发指令
2. 内核模块隐藏(包括隐藏rootkit自身分模块) 1) 基于断链法的内核模块隐藏技术
3. 文件、目录隐藏 1) 基于对/etc目录文件读取枚举接口函数劫持的的文件隐藏 2) 隐藏文件中"特定的内容" 3) 替换关键系统指令程序,例如ls、ll 4) 基于sys_execv系统调用劫持实现可执行程序执行重定向技术
4. 进程隐藏 1) 基于/proc的目录读取函数劫持的进程隐藏 2) 基于系统调用hook的进程隐藏 3) 替换关键系统指令程序,例如ps、top 4) 基于getdents64系统调用劫持实现可执行程序执行重定向技术
5. 网络连接状态隐藏 1) netfilter注册回调实现网络连接状态隐藏 2) /proc/net/tcp修改过滤实现网络连接状态隐藏 6. 获取root权限的shell 1) 通过内核API(prepare_creds()、commit_creds())获得rootkit权限shell 2) 无连接方式SHELL激活 2.1) tcp激活 2.2) udp激活 2.3) icmp激活
7. 远程控制(shell) 1) kernel mode socket connect back(内核态反向回连)
8. 通信加密 1) commit_creds 2) 借助HTTP、或DNS协议进行通信 9. 键盘记录 1) 密码记录(ssh, su, mysql, pop3, passwd etc)
|
0x03 驻留技术
1. 用户态驻留点
a. INIT自启动利用
Linux init
在systemd成为主流之前,sysvinit是大多数发行版的选择。作为Linux的init程序,也就是PID 1,负责启动之后的所有进程,所有的服务都是由它管理,可用其实现rootkit驻留
对于sysvinit,常见的驻留点需要以root身份写入:
1 2 3
| /etc/init.d /etc/rc[runlevel].d /etc/rc.local
|
对于systemd,可以用更多手段实现驻留,不需要root权限也可以:
1 2 3 4 5 6
| etc/systemd/system /etc/systemd/user /lib/systemd/system /lib/systemd/user ~/.local/share/systemd/user ~/.config/systemd/user
|
systemctl --user enable ervice
使服务随用户登录启动, systemctl enable service
让服务随系统启动。
bashrc
bashrc或者zshrc等文件会随着shell的运行而被执行,利用时只需在里面加入恶意的shell script
1 2 3 4
| /etc/profile ~/.bashrc ~/.bash_profile ~/.bash_logout
|
xinitrc
当目标主机有安装Xorg,也可以以下位置写入shell script实现rootkit驻留,不需要root权限
1 2 3 4
| ~/.xinitrc ~/.xserverrc /etc/X11/xinit/xinitrc /etc/X11/xinit/xserverrc
|
用户initrc
任何应用程序都可能在启动时执行代码,而且它们可能会执行用户home目录的rc文件,可用于rootkit驻留
vimrc
可以在vimrc里 写入vimscript来执行代码实现rookit的驻留,可以不需要root权限
b. CROND计划任务利用
写入软件包使用的crontab里面,如/etc/cron.d目录,模拟正常程序隐藏rootkit
定时任务文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 1) 系统配置项:系统执行的计划任务
/etc/crontab /etc/cron.d/
2) 用户允许/禁止配置文件
/etc/cron.deny :用来禁止一些用户使用cron服务的配置文件 /etc/cron.allow :允许一些用户来使用cron服务的配置文件,优先级高
3) 用户配置项:执行crontab命令操作的目录
/var/spool/cron
4) 其他计划任务文件
/etc/cron.daily /etc/cron.deny /etc/cron.hourly /etc/cron.monthly /etc/cron.weekly
|
c. 命令/文件替换
常用替换命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| 1) bin目录
/bin/ls
/bin/ps
/bin/bash
/bin/netstat
/bin/login
/bin/find
/bin/lsmod
/bin/pidof
/bin/lsof
/bin/ss
2) usr目录
/usr/bin/ls
/usr/bin/ps
/usr/sbin/ps
/usr/bin/bash
/usr/bin/netstat
/usr/sbin/netstat
/usr/sbin/rsyslogd
/usr/sbin/ifconfig
/usr/bin/login
/usr/bin/find
/usr/sbin/lsmod
/usr/sbin/pidof
/usr/bin/lsof
/usr/sbin/lsof
/usr/sbin/tcpd
/usr/bin/passwd
/usr/bin/top
/usr/bin/du
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/killall
/usr/bin/ss
/usr/sbin/ss
/usr/bin/ssh
/usr/bin/scp
3)sbin目录
/sbin/ifconfig
/sbin/lsmod
/sbin/pidof
/sbin/syslog-ng
/sbin/rsyslogd
|
程序文件替换
替换或者patch一些会被服务或用户本身执行的程序文件,同时执行恶意代码,是比较常见的驻留方式
如果目标主机是git或svn服务器,如果能获取项目源码,可以通过修改目标的源码植入恶意代码,或者利用编译环境,在项目构建时插入恶意代码,比如在configure脚本里或者Makefile里插入代码,既可以在本机运行,又有可能在编译之后在更多主机上运行,进一步扩大感染范围
d. 动态链接库劫持
替换动态链接库
libc会被几乎所有的ELF调用,而特定的lib则会被特定的ELF调用,可以利用重新编译的恶意so替换掉它所链接的某个so文件,达到执行恶意代码的效果;大部分程序都是动态链接库文件,需避免加入的代码调用的程序最终往回调用修改的库文件本身,作为动态链接库,其函数可能被频繁调用,在利用的时候要避免造成不必要的负载
ld.so.preload
最常见是在 /etc/ld.so.preload 中写入需要让libc执行的so文件,或者设置 LD_PRELOAD 环境变量,这样,任何依赖系统libc的user space程序,都会在运行之前执行我们的so文件,从而实现rootkit驻留
2. 内核态驻留点
a. LKM – 可加载内核模块
Linux 内核可以在运行时加载内核模块(例如设备驱动程序)。这允许攻击者插入一个覆盖内核系统调用的模块,以返回不正确的值(例如,不列出某些文件),或提供对攻击者有用的新功能(例如,为某些进程提供 root 权限)
LKM实现比较简单,在加载和退出的时候执行了两个shell脚本,并使用printk输出了内核调试信息。只需定义两个函数分别用于initialize和exit即可完成LKM的主体框架了,module.h会有相应函数 module_init 和module_exit用来实现
b. 通过 /dev/kmem 加载的 Rootkit
指在系统不支持lkm机制时修改内核的一种方法,通过写入 /dev/kmem、/dev/mem等设备可以在运行时覆盖内核,从而执行任意修改
0xFF Reference