Since the Log4J vulnerability was exposed, we see more and more malware jumped on the wagon, Elknot, Gafgyt, Mirai are all too familiar, on February 9, 2022, 360Netlab's honeypot system captured an unknown ELF file propagating through the Log4J vulnerability. What stands out is that the network traffic generated by this sample triggered a DNS Tunnel alert in our system, We decided to take a close look, and indeed, it is a new botnet family, which we named B1txor20 based on its propagation using the file name "b1t", the XOR encryption algorithm, and the RC4 algorithm key length of 20 bytes.
In short, B1txor20 is a Backdoor for the Linux platform, which uses DNS Tunnel technology to build C2 communication channels. In addition to the traditional backdoor functions, B1txor20 also has functions such as opening Socket5 proxy and remotely downloading and installing Rootkit.
Another interesting point is that we found that many developed features are not put into use (in IDA, there is no cross-reference); some features have bugs. we presume that the author of B1txor20 will continue to improve and open different features according to different scenarios, so maybe we will meet B1txor20's siblings in the future.
We have captured a total of four different B1txor20 samples, their functions are almost the same, a total of 15 function numbers are supported, according to these functions, B1txor20 can be characterized as: using DNS Tunnel to establish C2 channel, support direct connection and relay, while using
ZLIB compression, RC4 encryption, BASE64 encodingto protect the traffic of the backdoor Trojan, mainly targets
ARM, X64 CPU architecture of the Linux platform.
The main features currently supported are shown below.
- Execute arbitrary commands
- Install Rootkit
- Upload sensitive information
Its basic flowchart is shown below.
We choose the sample on February 09, 2022 as the main object of analysis, and its basic information is shown as follows.
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
The sample of B1txor20 is dynamically linked, so it is relatively easy to reverse. Simply put, when B1txor20 executes, it will first disguise itself as a [netns] process, run a single instance through the PID file
/var/run/.netns.pid, and then use
/dev/urandom to generate the BotID, then decrypt the domain name used for DNS Tunnel and the RC4 secret key used to encrypt the traffic and test the connectivity of the DNS server, and finally use DNS Tunnel to send registration information to C2 and wait for the execution of the commands issued by C2. Here we will not go into details about the regular functions, we will take a look at the DNS Tunnel implementation of the B1txor20.
Generating Bot ID
B1txor20 uses the following code snippet to read 32 bytes from
/tmp/.138171241, for generating BotId, and if it fails, a 16 bytes of data will be generated via /dev/urandom and will be written to the previous 2 files.
The following code snippet shows the process of BotId calculation.
Taking the machine-id value
ab3b49d10ec42c38b1093b8ce9ad12afof our VM as an example, the following equivalent python code can be used to calculate the value of BotId as 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 decrypts the domain name and RC4 secret key stored in the sample with the following code snippet.
Its principle is very simple, it is a single-byte xor operation, where xor_key is
49 D3 4F A7 A2 BC 4D FA 40 CF A6 32 31 E9 59 A1.
The decryption process is equivalent to the CyberChef implementation in the following figure, which shows that the domain name is
.dns.webserv.systems and the RC4 secret key is
Measure the connectivity of DNS servers
B1txor20 tests the connectivity of 3 DNS (126.96.36.199:53, 188.8.131.52:53, 184.108.40.206:443) servers with the following code snippet.
The principle is to use
res_mkquery API to build the DNS request message for "google.com", then send the request via
res_send, and as long as it can be sent successfully, the network is considered to be connected to the corresponding DNS server, and they are saved for subsequent use.
The actual traffic generated by Bot and 220.127.116.11 is as follows.
When the above preparations are completed, B1txor20 enters the final stage, using DNS Tunnel to establish communication with C2 and wait for the execution of the commands sent by C2.
Generally speaking, the scenario of malware using DNS Tunnel is as follows:
Bot sends the stolen sensitive information, command execution results, and any other information that needs to be delivered, after hiding it using specific encoding techniques, to C2 as a DNS request; After receiving the request, C2 sends the payload to the Bot side as a response to the DNS request. In this way, Bot and C2 achieve communication with the help of DNS protocol.
In such a network structure, there are 3 key points:
1:C2 must support the DNS protocol
2: Specific encoding techniques
3: The way DNS requests are sent
The following section will analyze the technical details of B1txor20's communication around these points, in conjunction with the traffic generated by B1txor20 in practice.
Through the traffic in the above figure, we can see that the SLD used by B1txor20 is webserv.systems, and using the DIG command, we can see that this SLD is point to IP 18.104.22.168; and the DNS resolution service is turned on at this IP 194, so we can determine that the C2 of B1txor20 is exactly 22.214.171.124.
0x02:Generate Tunnel domain name
The format of B1txor20's Tunnel domain name is
Base64-Like String+.dns.websrv.systems. It is obvious that the front Base64 string is the information sent by Bot to C2, how is it generated?
First, the B1txor20 packet has a pre-construction process, which can be seen in the format of
0xFF + BotId + 0xFF + Stage + 0xFF + TaskInfo, 0xFF is used to separate different items, and when the construction is finished, according to different Stage values, different tasks will fill the
Take the above task as an example, the Stage value is 1. Through the
gather_info function, the information of "sysinfo_uptime,uid,hostname" is filled into
TaskInfo, and they are separated by0x0a.
When the required information is ready, B1txor20 uses theprocess_queryfunction to further process the above information, which includes three processes: ZLIB compression, RC4 encryption, and Base64 encoding.
The secret key used in RC4 encryption is the string "EnLgLKHhy20f8A1dX85l" mentioned in the previous decryption section, and the Alphabet String used in Base64 is
Finally, B1txor20 adds 1 byte of status and 4 bytes of random string before the Base64 string generated above, and then splices it with domain, which is the final domain name to be queried. The value of status is ['0', '1', '2'], 0 means that the current query is truncated, the subsequent query and the current should be spelled into the same; 1 means that when the query is complete.
Let's take a look at the actual generated query
1HQoOKPvBKs8yqO1tTUQkCqGWN9anB4RAGWhnJy8A.dns.webserv.systems, removing the first 5 bytes, and the .dns.webserv.systems part to get
KPvBKs8yqO1tTUQkCqGWN9anB4RAGWhnJy8A, then use Base64 decoding, RC4 decryption, ZLIB decompression, you can get the following raw data.
From the data content and format, it can correspond with our previous description one by one, indicating that our previous analysis is correct.
Botid =0x125d Stage=1 sysinfo.uptime = 34 uid=30 hostname=debian
0x3:Send DNS request
When the above domain name construction is complete, B1txor20 generates and sends DNS requests using the RES series API.
There are 3 ways to send DNS requests, depending on the previous test of DNS connectivity.
1.Send to public dns (126.96.36.199, 188.8.131.52)
2.Send directly to C2 (184.108.40.206)
3.Send to local dns (nameserver in /etc/resolv.conf)
In this way, it is faster, but less concealed and easy to be detected and traced; in this way, 1 and 3 are more concealed, but a little slower.
0x4:Process C2 payload
After the Bot sends the DNS request in the above way, it waits for the execution of the C2 instruction, which is stored in the response message of the DNS request in the format of
Status(1 byte):Body, where the Body part also uses "ZLIB compression, RC4 encryption, BASE64 encoding " protection method.
For example, the actual command "1VSE6NZwczNMm2zgaXeLkZro=" is received in the following figure.
Body part for "VSE6NZwczNMm2zgaXeLkZro=", After decoded by Base64, RC4 decryption, you can get the following format of data, and then decompression of the
red part, you get the final instruction
FF 02 FF 0A FF, you can see that its format and the format generated by the above query is consistent, at this point it can be known that Bot will go to perform 0x02 function, so that Bot's round of interaction with C2 is complete.
B1txor20 supports a total of 14 instructions, and the correspondence between instruction number and function is shown in the following table.
|0x2||Upload system info|
|0x3||Create "/dev/pamd" (unix domain socket) which can get a shell|
|0x4||Exec arbitrary system cmd via popen|
|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|
|0x50||Upload "/boot/conf- XXX" info，Not used|
|0x51||install M3T4M0RPH1N3.ko rootkit|
In the table, "Not used" means that this function has the corresponding processing code in the sample, but it is not called. We are not sure if these codes are used for debugging or in other scenarios.
We found that some functions are buggy in their implementation, such as 0x3, which uses the remove function to delete the socket file after bind the domain socket, which makes the socket unconnectable and thus the whole function is useless.
We noticed the domain name has been registered for 6 years, which is kind unusual?
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
Readers are always welcomed to reach us on Twitter or email us to netlab at 360 dot cn.
webserv.systems 220.127.116.11:53 18.104.22.168:443
22.214.171.124 Luxembourg|Luxembourg|Unknown 53667|FranTech_Solutions 126.96.36.199 Netherlands|North_Holland|Amsterdam 43350|NForce_Entertainment_B.V. 188.8.131.52 United_States|New_York|New_York_City 4224|The_Calyx_Institute 184.108.40.206 United_States|Texas|Dallas 33070|Rackspace_Hosting 220.127.116.11 Sweden|Stockholm_County|Stockholm 198093|Foreningen_for_digitala_fri-_och_rattigheter 18.104.22.168 Romania|Bucharest|Unknown 200651|Flokinet_Ltd 22.214.171.124 Denmark|Region_Hovedstaden|Copenhagen 57860|Zencurity_ApS 126.96.36.199 Germany|Bavaria|Nuremberg 205100|F3_Netze_e.V. 188.8.131.52 Germany|Bavaria|Nuremberg 205100|F3_Netze_e.V. 184.108.40.206 Germany|Bavaria|Nuremberg 205100|F3_Netze_e.V. 220.127.116.11 Germany|Bavaria|Nuremberg 205100|F3_Netze_e.V. 18.104.22.168 Germany|Bavaria|Nuremberg 205100|F3_Netze_e.V. 22.214.171.124 Germany|Bavaria|Nuremberg 205100|F3_Netze_e.V. 126.96.36.199 Germany|Bavaria|Nuremberg 205100|F3_Netze_e.V. 188.8.131.52 Germany|Bavaria|Nuremberg 205100|F3_Netze_e.V. 184.108.40.206 Germany|Bavaria|Nuremberg 205100|F3_Netze_e.V. 220.127.116.11 Germany|Bavaria|Nuremberg 205100|F3_Netze_e.V. 18.104.22.168 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 22.214.171.124 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 126.96.36.199 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 188.8.131.52 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 184.108.40.206 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 220.127.116.11 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 18.104.22.168 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 22.214.171.124 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 126.96.36.199 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 188.8.131.52 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 184.108.40.206 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 220.127.116.11 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 18.104.22.168 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 22.214.171.124 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 126.96.36.199 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 188.8.131.52 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 184.108.40.206 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 220.127.116.11 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 18.104.22.168 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 22.214.171.124 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 126.96.36.199 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 188.8.131.52 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 184.108.40.206 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 220.127.116.11 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 18.104.22.168 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 22.214.171.124 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 126.96.36.199 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 188.8.131.52 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 184.108.40.206 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 220.127.116.11 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 18.104.22.168 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 22.214.171.124 Netherlands|North_Holland|Amsterdam 200052|Feral.io_Ltd 126.96.36.199 Netherlands|South_Holland|Capelle_aan_den_IJssel 43350|NForce_Entertainment_B.V. 188.8.131.52 Ukraine|Kiev|Unknown None; 184.108.40.206 Romania|Romania|Unknown None; 220.127.116.11 Romania|Romania|Unknown None; 18.104.22.168 Italy|Lombardy|Metropolitan_City_of_Milan 49367|Seflow_S.N.C._Di_Marco_Brame'_&_C. 22.214.171.124 United_States|New_York|New_York_City 53667|FranTech_Solutions 126.96.36.199 United_States|Washington|Seattle 396507|Emerald_Onion 188.8.131.52 North_America_Regions|North_America_Regions|Unknown None; 184.108.40.206 France|Ile-de-France|Paris 57199|MilkyWan 220.127.116.11 Sweden|Stockholm_County|Stockholm 41281|KeFF_Networks_Ltd 18.104.22.168 United_States|United_States|Unknown 8100|QuadraNet_Enterprises_LLC 22.214.171.124 Netherlands|South_Holland|Capelle_aan_den_IJssel 43350|NForce_Entertainment_B.V. 126.96.36.199 Netherlands|Flevoland|Dronten 60404|Liteserver_Holding_B.V. 188.8.131.52 Netherlands|North_Holland|Haarlem 12876|Online_S.a.s. 184.108.40.206 Sweden|Stockholm_County|Akersberga 51815|IP-Only_Networks_AB 220.127.116.11 Sweden|Stockholm_County|Akersberga 51815|IP-Only_Networks_AB 18.104.22.168 Switzerland|Canton_of_Ticino|Unknown 51852|Private_Layer_INC
hxxp://22.214.171.124:8000/xExportObject.class ldap://126.96.36.199:1389/o=tomcat hxxp://188.8.131.52:8229/b1t_1t.sh hxxp://184.108.40.206:8228/b1t hxxp://220.127.116.11:8228/b1t hxxp://18.104.22.168:8228/_run.sh hxxp://22.214.171.124:8228/run.sh hxxp://126.96.36.199:8228/share.sh hxxp://188.8.131.52:8228/b1t hxxp://184.108.40.206:8228/run.sh hxxp://220.127.116.11:8228/run.sh hxxp://18.104.22.168:8229/b4d4b1t.elf
027d74534a32ba27f225fff6ee7a755f 0a0c43726fd256ad827f4108bdf5e772 24c49e4c75c6662365e10bbaeaeecb04 2e5724e968f91faaf156c48ec879bb40 3192e913ed0138b2de32c5e95146a24a 40024288c0d230c0b8ad86075bd7c678 43fcb5f22a53a88e726ebef46095cd6b 59690bd935184f2ce4b7de0a60e23f57 5f77c32c37ae7d25e927d91eb3b61c87 6b42a9f10db8b11a15006abced212fa4 6c05637c29b347c28d05b937e670c81e 7ef9d37e18b48de4b26e5d188a383ec8 7f4e74e15fafaf3f8b79254558019d7f 989dd7aa17244da78309d441d265613a dd4b6e2750f86f2630e3aea418d294c0 e82135951c3d485b7133b9673194a79e fd84b2f06f90940cb920e20ad4a30a63