概述

2021年3月25日,360 NETLAB的BotMon系统发现一个的VT 0检测的可疑ELF文件(MD5=64f6cfe44ba08b0babdd3904233c4857),它会与4个营业类型判然不同的域名停止通信,端口均为TCP 443(HTTPS),但流量却并不是TLS/SSL类型,那个异常行为引起了我们的兴趣,进一步阐发发现它是一个针对Linux X64系统的后门木马,该家族至少已经存在3年但目前仍是0检测。基于该家族利用rotate加密,而且运行后对root/non-root账户有差别的行为,犹如一只双头龙,一体双向,我们将它定名为RotaJakiro。

RotaJakiro隐蔽性较强,对加密算法利用比力多,包罗:利用AES算法加密样本内的资本信息;C2通信综合利用了AES,XOR,ROTATE加密和ZLIB压缩算法。指令方面,RotaJakiro撑持12种指令码,此中3种是和特定plugin相关的,遗憾的是目前我们并没有捕捉到那类payload,因而其实不晓得它的实正目标。从广义的后门角度来看,RotaJakiro撑持的功用能够归纳成以下4类:

上报设备信息窃取敏感的信息文件/Plugin办理(查询,下载,删除)施行特定的Plugin

当所有阐发完毕后,我们测验考试对RotaJakiro停止溯源,按照解密后的资本以及编码的气概的类似性,我们揣测它是Torii Botnet做者的又一做品。

暗藏了几?

我们从捕捉的样本动身,寻找RotaJakiro同源者,最末发现了以下4个样本,它们在VT上都是0检测,从VT的First Seen时间来看,RotaJakiro至少已经存在了3年。

FILENAME

MD5

DETECTION

FIRST SEEN IN VT

systemd-daemon

1d45cd2c1283f927940c099b8fab593b

0/61

2018-05-16 04:22:59

systemd-daemon

11ad1e9b74b144d564825d65d7fb37d6

0/58

2018-12-25 08:02:05

systemd-daemon

5c0f375e92f551e8f2321b141c15c48f

0/56

2020-05-08 05:50:06

gvfsd-helPEr

64f6cfe44ba08b0babdd3904233c4857

0/61

2021-01-18 13:13:19

那批样本都内嵌了以下4个C2,目前它们在VT上也是0检测。那4个C2域名有十分接近的Crteated Updated Expired时间,我们揣测它们不断以来用于统一个营业,从那个角度来看,RotaJakiro背后的团伙至少已经活动了6年。

DOMAIN

DETECTION

CREATED

LAST UPDATED

EXPIRED

news.thaPRior.net

0/83

2015-12-09 06:24:13

2020-12-03 07:24:33

2021-12-09 06:24:13

blog.eduelects.com

0/83

2015-12-10 13:12:52

2020-12-03 07:24:33

2021-12-10 13:12:52

cdn.mirror-codes.net

0/83

2015-12-09 06:24:19

2020-12-03 07:24:32

2021-12-09 06:24:19

status.sublineover.net

0/83

2015-12-09 06:24:24

2020-12-03 07:24:32

2021-12-09 06:24:24

逆向阐发

4个RotaJakiro样本,时间散布从2018到2021,它们的功用十分接近,本文拔取2021年的样本为阐发对象,它的根本信息如下:

MD5:64f6cfe44ba08b0babdd3904233c4857ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, strippedPacker:No

从编码层面来说,RotaJakiro接纳了动态AES,双层加密的通信协议等手艺来匹敌平安人员的二进造&收集流量阐发。

从功用层面来说,RotaJakiro运行时起首会判断其时用户是root,仍是non-root,差别的账户有差别的施行战略,然后利用AES&ROTATE解密出相关的敏感资本供后续的耐久化,历程守护和单一实例利用,最初和C2成立通信,期待施行C2下发的指令。

下文将从上述角度动身分析RotaJakiro详细实现。

样本匹敌技巧动态生成AES加密算法所需的常量表,避免算法被间接识别利用stack strings obfuscation手艺存储加密的敏感资本信息利用双层加密的收集通信加密算法

RotaJakiro中所有的敏感资本都是加密的,在IDA中我们能够看出解密办法dec_proc挪用了60次,它是由AES,Rotate俩部门构成。

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第1张

AES解密入口如下所示:

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第2张

此中aes_dec的接纳的是AES-256, CBC形式,key&iv都是硬编码。

key14 BA EE 23 8F 72 1A A6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00iv00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Rotate解密入口如下所示:

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第3张

所谓Rotate即轮回移位,能够看出此处利用的轮回左移,此中移位的次数由plain_len(明文长度)&7的值决定。

以解密以下C2密文为例:

ff ba a2 3b cd 5b 7b 24 8c 5f e3 4b fc 56 5b 99 ac 91 cf e3 9a 27 d4 c9 6b 39 34 ce 69 ce 18 60

其与解密相关的各类参数如下图所示,密文长度为32字节,明文长度为26字节

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第4张

起首利用AES解密后得到以下“次级密文”:

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第5张

然后从次级密文中取出有效密文,此中有效密文从第8字节起头,长度为明文长度减8,此处即为26-8=18字节。

98 1B DB D9 8B 59 19 5D 59 1B 59 D8 1D DC 8B D8 DB 5B

最初通过明文长度26能够计算26&7=2,得到移位的次数,将上述有效密文逐字节左移2位,就能得到C2明文。

blog.eduelects.com耐久化

RotaJakiro在实现耐久功用时,对root/non-root用户做了区分,差别的账号接纳了差别的手艺。

针对root账号的耐久化实现按照差别Linux系统发行版本,创建响应的自启动脚本/etc/init/systemd-agent.conf或者/lib/systemd/system/systemd-agent.service。Content of systemd-agent.conf ----------------------------- #system-daemon - configure for system daemon #This service causes system have an associated #kernel object to be started on boot. description "system daemon" start on filesystem or runlevel [2345] exec /bin/systemd/systemd-daemon respawn Content of systemd-agent.service ----------------------------- [Unit] Description=System Daemon Wants=network-online.target After=network-online.target [Service] ExecStart=/usr/lib/systemd/systemd-daemon Restart=always [Install]用于假装的文件名,俩者2选1/bin/systemd/systemd-daemon /usr/lib/systemd/systemd-daemon针对non-root账号的耐久化实现创建桌面情况的自启动脚本$HOME/$.config/autostart/gnomehelper.desktop[Desktop Entry] Type=Application Exec=$HOME/.gvfsd/.profile/gvfsd-helper修改.bashrc文件,创建shell情况的自启动脚本# Add GNOME's helper designed to work with the I/O abstraction of GIO # this environment variable is set, gvfsd will not start the fuse filesystem if [ -d ${HOME} ]; then ${HOME}/.gvfsd/.profile/gvfsd-helper fi用于用于假装的文件名,俩者同时存在$HOME/.dbus/sessions/session-dbus $HOME/.gvfsd/.profile/gvfsd-helper历程守护

RotaJakiro实现了历程守护以庇护本身的运行,和耐久化一样,对root/non-root用户有差别的实现体例。

针对root账号的历程守护实现

在root账号下运行时,按照差别Linux系统发行版本,通过向办事的设置装备摆设文件中写入Restart=always或者respawn,当办事历程被完毕时,会主动创建新历程。

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第6张

现实效果如下图所示,能够看到systemd-daemon历程被完毕后,立马就生成了新历程。

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第7张

针对non-root账号的历程守护实现

在non-root账号下运行时,RotaJakiro生成session-dbus和gvfsd-helper俩个历程,它们监控着相互的存活,当此中一方被完毕时,另一方将其恢复,那长短常典型的双历程庇护。

RotaJakiro的双历程庇护是若何实现的呢?起首以shmget API创建一片共享内存,session-dbus和gvfsd-helper通过那片共享内存实现历程间通信,告诉对方的本身的PID。然后通过/proc/[PID]目次,动态地获取历程的存活情况。当发现对方历程灭亡时,通过execvp创建历程,帮忙灭亡一方“新生”,大致流程如下图所示:

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第8张

现实效果如下图所示,能够看到session-dbus和gvfsd-helper被kill -9完毕后,新历程立马就创建了。

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第9张

单一实例

RotaJakiro通过文件锁来实现单一实例,详细实现如下所示:

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第10张

此中用到的lockfile在root/non-root账号下有所差别。

root下的lockfile,2选1/usr/lib32/.X11/X0-lock /bin/lib32/.X11/X0-locknon-root下的lockfile,同时存在$HOME/.X11/X0-lock $HOME/.X11/.X11-lock

以现实中non-root账号为例,通过/proc/locks能够将历程以及文件锁对应起来,此时再施行对应的RotaJakiro的样本,能够看到其实不会有对应的新历程创建。

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第11张

收集通信

RotaJakiro通过以下代码片段和C2成立通信,期待施行后续指令:

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第12张

那个过程能够分红2个阶段

Stage 1,初始化阶段:解密出C2列表,和C2成立毗连,发送上线信息,接回并解密C2返回的信息。Stage 2,营业阶段:验证C2的返回信息,若通过验证,施行C2后续下发的指令。Stage 1:初始化

通过前文所述的解密算法解密出C2列表,目前样本中内置了以下4个C2:

news.thaprior.netblog.eduelects.comcdn.mirror-codes.netstatus.sublineover.net

RotaJakiro起首会测验考试和它们成立毗连,然后通过以下代码片段构造上线信息,

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第13张

接着将上线信息加密并发送给C2

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第14张

最初领受C2的回包,解密并校验其合法性,若通过校验,进入Stage 2。

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第15张

Stage 2:详细营业

通过以下代码片段领受并施行C2下发的指令:

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第16张

目前RotaJakiro一共撑持12条指令,指令码与功用的对应关系如下表所示:

CMDID

FUNCTION

0x138E3E6

Exit

0x208307A

Test

0x5CCA727

Heartbeat

0x17B1CC4

Set C2 timeout time

0x25360EA

Streal Senstive Info

0x18320e0

Upload Device Info

0x2E25992

Deliver File/Plugin

0x2CD9070

Query File/Plugin Status

0x12B3629

Delete File/Plugin Or Dir

0x1B25503

Run Plugin_0x39C93E

0x1532E65

Run Plugin_0x75A7A2

0x25D5082

Run Plugin_0x536D01

此中Run Plugin功用复用不异的代码,通过以下逻辑实现函数挪用:

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第17张

我们目前被没有捕捉到那类payload,因而用Plugin_“参数”的形式来暗示差别的使命。

RotaJakiro的收集通信包如下图所示,由head,key,payload三部门构成,此中header是必需的,长度为82字节,而body&payload部门是可选的。head&key接纳的XOR&Rotate加密,payload接纳AES&ZLIB加密压缩。

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第18张

下面我们将通过BOT与C2的一轮交互,来申明收集流量head&key&payload的构成以及解密过程。

C2 -> BOT双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第19张

读取前0x52字节,就是head的内容。head若何解密呢?办法很简单,逐字节左移3位,然后和0x1b异或即可,解密后得下以内容:

00000000 16 11 10 b9 03 b1 0c fb 04 20 00 00 00 08 00 e0 |...¹.±.û. .....à|00000010 20 83 01 c2 20 64 20 01 e2 00 00 00 00 c2 0c 00 | .. d .â....Â..|00000020 00 00 32 42 36 39 33 33 34 46 38 34 31 44 30 44 |..2B69334F841D0D|00000030 39 46 41 30 36 35 38 45 43 33 45 32 39 46 41 44 |9FA0658EC3E29FAD|00000040 34 39 c8 53 e6 9c 48 c4 8b 77 24 2e 02 1c 96 d9 |49ÈSæ.HÄ.w$....Ù|00000050 81 28------------filed parse------------------offset 0x09, 4 bytes--->payload lengthoffset 0x0d, 2 bytes--->body lengthoffset ox0f, 4 bytes--->cmdid

通过字段解析,可知key的长度为0x8字节,payload的长度为0x20字节,要施行的指令码为0x18320e0,即上报设备信息。

从偏移0x52读取8字节就得到了keyea 9a 1a 18 18 44 26 a0,利用和head一样的解密办法,得到4c cf cb db db 39 2a 1e,它是做为AES的密钥来解密payload。

从偏移0x5a读取32字节,就得到了下面的payload:

54 c1 c3 69 00 18 31 e4 a2 5b 10 7f 67 ab d1 4b b2 7b 3d 3f b3 bc 66 6a 26 f6 f6 b3 f7 2e 66 6d

利用解密后的key做为AES-256的密钥,以CBC形式解密以上数据得下以下内容:

3b c7 f8 9b 73 2b d1 04 78 9c e3 60 60 60 d8 df d9 c1 71 56 f7 6f 00 00 13 80 04 28

第8字节起即为ZLIB压缩数据,解压得到如下内容:

08 00 00 00 bf 89 88 08 cd 2d fd 50------------filed parse------------------offset 0, 4 bytes--->length

解压后的payload有什么用呢?它是做为新的AES密钥,用来解密部门敏感资本信息。例如Bot在搜集设备信息时,有一项是当前操做系统发行版本的信息,它是通过cat /etc/*release | uniq号令实现的。

root@debian:~# cat /etc/*release | uniqPRETTY_NAME="Debian GNU/Linux 9 (stretch)"NAME="Debian GNU/Linux"VERSION_ID="9"VERSION="9 (stretch)"ID=debianHOME_URL="https://www.debian.org/"SUPPORT_URL="https://www.debian.org/support"BUG_REPORT_URL="https://bugs.debian.org/"

cat /etc/*release | uniq那条号令恰是以下密文通过新的AES密钥共同下图中的参数解密而来。

cmd ciphertxt---------------------------74 00 dd 79 e6 1e aa bb 99 81 7e ca d9 21 6b 81 6b d9 9d 14 45 73 6a 1c 61 cc 28 a3 0f 2b 41 5a 6b 33 8c 37 25 89 47 05 44 7e f0 6b 17 70 d8 ca双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第20张

Bot -> C2

当BOT领受到C2的“上报设备信息”指令后,会向C2发送以下数据,能够看出key部门的值仍然是ea 9a 1a 18 18 44 26 a0。

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第21张

从上文已知解密后key值为4c cf cb db db 39 2a 1e,通过那个值将Bot发往C2的payload解密解压后,得到如下数据,恰是设备的各类信息,此中有前文提到的通过cat /etc/*release | uniq获取的信息,验证了我们的阐发是准确的。

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第22张

与Torii Botnet团伙的关系

Torii僵尸收集于2018年9月20日被友商Avast曝光,比照RotaJakiro,俩者的类似之处表现在以下3方面:

1:字符串类似性

RotaJakiro&Torii的敏感资本解密后,我们发现它们复用了大量不异的号令。

1:semanage fcontext -a -t bin_t '%s' && restorecon '%s'2:which semanage3:cat /etc/*release 4:cat /etc/issue5:systemctl enable6:initctl start...2:流量类似性

在构造流量的过程中,大量利用常数,构造体例十分接近。

双头龙(RotaJakiro),一个至少潜伏了3年的后门木马  第23张

3:功用类似性

从平安研究人员停止逆向工程的角度来说,RotaJakiro&Torii有着相常类似的气概:利用加密算法隐藏敏感资本,都实现了相当old-school式的耐久化,构造化的收集流量等。

基于那些考量,我们揣测RotaJakiro和Torii出自统一个团伙之手。

冰山一角

至此RotaJakiro的逆向与溯源告一段落,但实正的工做远没完毕,有许多问题仍然没有谜底:“RotaJakiro是怎么传布的,它的目标是什么?”,“RotaJakiro能否有特定的攻击目的,是不是APT?”,“RotaJakiro与Torii背后的黑手是谁?”......因为我们的视野有限,目前只能向平安社区分享那么多。若是社区有相关的线索,欢送与我们联络,让我们一路Make Cyber Security Great Again。