新威胁：使用DNS Tunnel技术的Linux后门B1txor20正在通过Log4j漏洞传播

背景


自从Log4J漏洞被曝光后，正所谓"忽如一夜漏洞来，大黑小灰笑开怀”。无数黑产团伙摩拳擦掌加入了这个“狂欢派对”，其中既有许多业界非常熟悉的恶意软件家族，同时也有一些新兴势力想趁着这股东风在黑灰产上分一杯羹。360Netlab作为专注于蜜罐和Botnet检测跟踪的团队，我们自该漏洞被公开后就一直关注它会被哪些僵尸网络利用，期间我们看到了Elknot，Gafgyt，Mirai等老朋友的从不缺席，也见证了一些新朋友的粉墨登场。


2022年2月9日，360Netlab的蜜罐系统捕获了一个未知的ELF文件通过Log4J漏洞传播，此文件在运行时产生的网络流量引发了疑似DNS Tunnel的告警，这引起了我们的兴趣。经过分析，我们确定是一个全新的僵尸网络家族，基于其传播时使用的文件名"b1t"，XOR加密算法，以及RC4算法秘钥长度为20字节，它被我们命名为B1txor20。


简单来说，B1txor20是一个针对Linux平台的后门木马， 它利用DNS Tunnel技术构建C2通信信道，除了传统的后门功能，B1txor20还有开启Socket5代理，远程下载安装Rootkit，反弹Shell等功能，这些功能可以很方便的将被侵入的设备变成跳板，供后续渗透时使用。


另外一个有意思的点是我们发现许多开发好了的功能并没有投入使用（在IDA中表现为，没有交叉引用)；有些功能存在BUG。我们推测B1txor20的作者会持续完善，并根据的不同场景，定制式地开启不同的功能，或许以后我们将遇到B1txor20的兄弟姐妹。


鉴于B1txor20所使用漏洞的高危性，以及其C2信道的隐蔽性，我们决定撰写本文向社区分享我们的发现，共同维护网络安全。



B1txor20概览


我们一共捕获了4个不同MD5的B1txor20样本文件，它们的功能几乎一样，一共支持15个功能号，根据这些功能，可以将B1txor20定性为：一个使用DNS Tunnel技术构建隐蔽的C2信道，支持直连和中继2种方式，同时使用zlib压缩，RC4加密，BASE64编码的方式保护流量的后门木马，目前通过Log4j漏洞传播，主要针对ARM,X64 CPU架构的Linux平台。


目前支持的主要功能如下所示：


 1. SHELL
 2. Proxy
 3. 执行任意命令
 4. 安装Rootkit
 5. 上传敏感信息


它的基本流程图如下所示：




逆向分析


本文选择2022年2月09日的样本为主要分析对象，它的基本信息如下所示：


MD5:0a0c43726fd256ad827f4108bdf5e772

ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped

Packer:None



B1txor20的样本是动态链接的，因此在逆向上比较容易，简单来说，当B1txor20在被侵入设备动行后，首先会将自身伪装成[netns]进程，通过/var/run/.netns.pid这个PID文件实现单一实例，然后使用/etc/machine-id，/tmp/.138171241或/dev/urandom3者中任意一个，生成BotID，接着解密用于DNS Tunnel的域名，以及用于加密流量的RC4秘钥并测试DNS服务器的连通性，最后使用DNS Tunnel技术向C2发送上线信息，等待执行C2下发的指令。其中进程伪装，单一实例这些功能比较简单，就再不细述，下文将围绕DNS Tunnel剖析B1txor20的实现。



生成Bot ID


B1txor20通过以下代码片段从etc/machine-id，或/tmp/.138171241，读取32字节用于生成BotId，如果失败，则通过/dev/urandom生成16字节数据，并将它写入到前面2个文件。





下面的代码片段是BotId的计算过程：




以我们虚拟机的machine-id值ab3b49d10ec42c38b1093b8ce9ad12af为例，通过下面等效的python代码，可以算出BotId的值为0x125d。


import struct
id='ab3b49d10ec42c38b1093b8ce9ad12af'
values=struct.unpack("<16H",id)
sum=0
for i in values:
    sum ^= i
print hex(sum)
if sum&0xff <0xf:
    sum+=0x10
if sum>>8 < 0xf:
    sum+=0x1000
print hex(sum)   # sum=0x125d





解密


B1txor20通过以下代码片段解密存储在样本中的域名和RC4秘钥，



它的原理非常简单，就是单字节xor操作，其中xor_key为49 D3 4F A7 A2 BC 4D FA 40 CF A6 32 31 E9 59 A1



通过下图的CyberChef实现等效的解密过程，可知域名为.dns.webserv.systems，RC4秘钥为EnLgLKHhy20f8A1dX85l。




测出DNS服务器的连通性


B1txor20通过以下代码片段测试3个DNS （8.8.8.8:53，8.8.8.4:53，194.165.16.24:443）服务器的连通性。



它的原理是使用res_mkqueryAPI构建“google.com”的DNS请求报文，然后通过res_send发送请求，只要能够发送成功，就认为和相应DNS服务器的网络是连通，把它们保存起来供后续使用。




实际中Bot与194.165.16.24产生的流量如下所示：





C&C通信


当上述的准备工作完成后，B1txor20进入最终阶段，使用DNS Tunnel技术和C2建立通信，等待执行C2下发的指令。




一般来说恶意软件使用DNS Tunnel的场景是这样的：Bot把窃取的敏感信息，命令的执行结果等等任何需要传递的信息，在使用特定的编码技术隐藏之后，以DNS请求的方式，将它发送到C2；C2到接收到请求之后，把payload做为DNS请求的响应，将它发送到Bot端。这样一来，Bot与C2就在DNS协议的帮助之下实现了通信。在这样的网络结构中，有3个关键的点值得注意


 1. C2必须支持DNS协议
 2. 特定的编码技术
 3. DNS请求的发送方式


下文将围绕这些点，结合B1txor20在实际中产生的流量，分析B1txor20的通信技术细节。





0x01:定位C2


通过上图的流量，可以看出B1txor20使用的SLD是webserv.systems，使用DIG命令可知此SLD绑定的IP为194.165.16.24；而194这个IP上又开启了DNS解析服务，因此我们可以确定B1txor20的C2正是194.165.16.24。




0x02:生成Tunnel域名


B1txor20的Tunnel域名格式为Base64-Like String+.dns.websrv.systems 很明显前面

类似Base64的字串就是Bot发往C2的信息，它是如何生成的呢？

首先，B1txor20数据包的有一个前置构造过程，可以看出其格式为0xFF + BotId + 0xFF + Stage + 0xFF + Other Info，0xFF用于分隔不同的项，当成完构造后，再根据不同的Stage值，进入不同的任务，填充Other Info部分。



以上线这个任务为例，Stage值为1，通过gather_info函数，将"sysinfo_uptime,uid,hostname"这些信息填充到Other Info中，它们使用0x0a分隔。



当所需的信息都已准备好之后，B1txor20接着使用process_query函数对上面的信息进一步处理，它包括ZLIB压缩，RC4加密，Base64编码3个过程。



其中RC4加密所使用的秘钥就是前文解密章节所说的字串“EnLgLKHhy20f8A1dX85l”，Base64使用的Alphabet String为ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789^_。


最后B1txor20在上面生成的Base64字串前加入1字节表示status，4字节随机字串，再和domain进行拼接，就么得了最终要查询的域名。其中status的取值为['0', '1', '2']，0表示当前的查询被截断了，后续的查询和当前应该拼成同一个；1表示当成查询是完整的。



以实际产生的一个查询1HQoOKPvBKs8yqO1tTUQkCqGWN9anB4RAGWhnJy8A.dns.webserv.systems为例，去除前5字节，以及.dns.webserv.systems部分，得到KPvBKs8yqO1tTUQkCqGWN9anB4RAGWhnJy8A，然后使用Base64解码，RC4解密，ZLIB解压，就能得到了以下原始数据。



从数据内容和格式来看，它和我们前文的描述能一一对应，说明我们前面的分析是正确的。


Botid =0x125d
Stage=1
sysinfo.uptime = 34
uid=30
hostname=debian




0x3:发送DNS请求


当上述域名构造完成后，B1txor20使用RES系列API生成并发送DNS请求。



根据前文测试DNS连通情况的不同，发送DNS请求的方式有3种。


 1. 向public dns(8.8.8.8，8.8.4.4)发送
 2. 直接向C2(194.165.16.24)发送
 3. 向local dns(nameserver in /etc/resolv.conf)发送


其中2这种方式，它的速度较快，但蔽性弱，很容易被探测追踪；1,3这种俩种方式隐蔽性强，但速度稍慢。



0x4:处理C2指令


当Bot通过上述方式发送DNS请求后，就等待执行C2下发的指令。C2的指令存放在DNS请求的响应报文中，它的格式为Status(1 byte):Body，其中Body部分也使用了“ZLIB压缩，RC4加密，BASE64编码”这种保护方法。



以下图实际收到的指令“1VSE6NZwczNMm2zgaXeLkZro= ”为例，



Body部分为"VSE6NZwczNMm2zgaXeLkZro="，它经过Base64解码，RC4解密后，就能得到了以下格式的数据，再将红色部分解压，就得到了最终的指令FF 02 FF 0A FF，可以看出它的格式和上文查询产生的格式是一致的，此时可知Bot将去执行0x02号功能，至此Bot与C2的一轮交互就完成了。




C&C指令


B1txor20一共支持15条指令，指令号与功能的对应关系如下表所示：





Cmd ID
Function




0x1
Beacon/Heartbeat


0x2
Upload system info


0x3
Create "/dev/pamd" (unix domain socket) which can get a shell


0x4
Exec arbitrary system cmd via popen


0x5
Traffic forwarding


0x6
Write File


0x7
Read File


0x8
Deliver info via "/var/tmp/.unetns"(unix domain socket)，Not used


0x9
Upload specific info，Not used


0x10
Stop proxy service


0x11
Start proxy service


0x1a
Create proxy service


0x21
Reverse shell


0x50
Upload "/boot/conf- XXX" info，Not used


0x51
install M3T4M0RPH1N3.ko rootkit





表中"Not used"表示这个功能，在样本中有应的处理代码，但没有被调用，我们不确定这些代码是用于调试的，或是在别的样本中使用。

另外有意思的一点是，我们发现有些功能在实现上是有Bug的，如0x3，它在bind 域套接字后，使用remove函数删除了套接字文件，这会让此套接字无法被connect，进而整个功能失效。





花絮


域名一买就是6年，这是想要大干一票？


webserv.systems	createddate                 2021-02-08 15:13:22
webserv.systems	updateddate                 2021-02-24 22:27:23
webserv.systems	expiresdate                 2027-02-08 15:13:22




联系我们


感兴趣的读者，可以在twitter或者在微信公众号 360Netlab上联系我们。



IOC



C2


webserv.systems
194.165.16.24:53
194.165.16.24:443




Scanner


104.244.73.126	Luxembourg|Luxembourg|Unknown	53667|FranTech_Solutions
109.201.133.100	Netherlands|North_Holland|Amsterdam	43350|NForce_Entertainment_B.V.
162.247.74.27	United_States|New_York|New_York_City	4224|The_Calyx_Institute
166.78.48.7	United_States|Texas|Dallas	33070|Rackspace_Hosting
171.25.193.78	Sweden|Stockholm_County|Stockholm	198093|Foreningen_for_digitala_fri-_och_rattigheter
185.100.87.202	Romania|Bucharest|Unknown	200651|Flokinet_Ltd
185.129.62.62	Denmark|Region_Hovedstaden|Copenhagen	57860|Zencurity_ApS
185.220.100.240	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.241	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.242	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.243	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.246	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.249	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.250	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.252	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.254	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.100.255	Germany|Bavaria|Nuremberg	205100|F3_Netze_e.V.
185.220.101.134	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.136	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.140	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.143	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.144	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.151	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.155	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.161	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.162	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.164	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.166	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.168	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.172	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.174	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.176	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.181	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.191	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.34	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.37	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.39	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.40	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.42	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.43	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.46	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.5	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.50	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.51	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.53	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.54	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.56	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.57	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.220.101.61	Netherlands|North_Holland|Amsterdam	200052|Feral.io_Ltd
185.56.80.65	Netherlands|South_Holland|Capelle_aan_den_IJssel	43350|NForce_Entertainment_B.V.
193.218.118.158	Ukraine|Kiev|Unknown	None;
194.32.107.159	Romania|Romania|Unknown	None;
194.32.107.187	Romania|Romania|Unknown	None;
194.88.143.66	Italy|Lombardy|Metropolitan_City_of_Milan	49367|Seflow_S.N.C._Di_Marco_Brame'_&_C.
199.195.250.77	United_States|New_York|New_York_City	53667|FranTech_Solutions
23.129.64.216	United_States|Washington|Seattle	396507|Emerald_Onion
23.154.177.4	North_America_Regions|North_America_Regions|Unknown	None;
45.13.104.179	France|Ile-de-France|Paris	57199|MilkyWan
45.154.255.147	Sweden|Stockholm_County|Stockholm	41281|KeFF_Networks_Ltd
45.61.185.90	United_States|United_States|Unknown	8100|QuadraNet_Enterprises_LLC
46.166.139.111	Netherlands|South_Holland|Capelle_aan_den_IJssel	43350|NForce_Entertainment_B.V.
5.2.69.50	Netherlands|Flevoland|Dronten	60404|Liteserver_Holding_B.V.
51.15.43.205	Netherlands|North_Holland|Haarlem	12876|Online_S.a.s.
62.102.148.68	Sweden|Stockholm_County|Akersberga	51815|IP-Only_Networks_AB
62.102.148.69	Sweden|Stockholm_County|Akersberga	51815|IP-Only_Networks_AB
81.17.18.62	Switzerland|Canton_of_Ticino|Unknown	51852|Private_Layer_INC




Downloader


hxxp://179.60.150.23:8000/xExportObject.class
ldap://179.60.150.23:1389/o=tomcat
hxxp://194.165.16.24:8229/b1t_1t.sh
hxxp://194.165.16.24:8228/b1t
hxxp://194.165.16.24:8228/b1t
hxxp://194.165.16.24:8228/_run.sh
hxxp://194.165.16.24:8228/run.sh
hxxp://194.165.16.24:8228/share.sh
hxxp://194.165.16.24:8228/b1t
hxxp://194.165.16.24:8228/run.sh
hxxp://194.165.16.24:8228/run.sh
hxxp://194.165.16.24:8229/b4d4b1t.elf




Sample MD5


027d74534a32ba27f225fff6ee7a755f
0a0c43726fd256ad827f4108bdf5e772
24c49e4c75c6662365e10bbaeaeecb04
2e5724e968f91faaf156c48ec879bb40
3192e913ed0138b2de32c5e95146a24a
40024288c0d230c0b8ad86075bd7c678
43fcb5f22a53a88e726ebef46095cd6b
59690bd935184f2ce4b7de0a60e23f57
5f77c32c37ae7d25e927d91eb3b61c87
6b42a9f10db8b11a15006abced212fa4
6c05637c29b347c28d05b937e670c81e
7ef9d37e18b48de4b26e5d188a383ec8
7f4e74e15fafaf3f8b79254558019d7f
989dd7aa17244da78309d441d265613a
dd4b6e2750f86f2630e3aea418d294c0
e82135951c3d485b7133b9673194a79e
fd84b2f06f90940cb920e20ad4a30a63