Two builds of Mirai for ARM
theZoo keeps two builds of one Mirai
variant for ARM as Linux.Mirai.B. Both are static executables with their
symbols, so the symbols give the truth for a comparison by code alone.
Both fetch their next stage from the same host, so one operator built
them. This page calls the smaller build “old” and the larger one “new”:
the larger one holds more exploits, but nothing in the files dates them.
Warning
These files are live malware. Do not run them.
hereticusonly reads them.
| SHA-256 | Size | |
|---|---|---|
| Old | 03254e6240c35f7d787ca5175ffc36818185e62bdfc4d88d5b342451a747156d | 179383 bytes |
| New | f60b29cfb7eab3aeb391f46e94d4d8efadde5498583a2f5c71bd8212d8ae92da | 283000 bytes |
| Zip of theZoo | b50681094c040883f3da8fe697bd3a9e35e62d1672f59d9f14e0db494f9d41c2 | 182620 bytes |
Get the samples
$ curl -sLO https://github.com/ytisf/theZoo/raw/master/malware/Binaries/Linux.Mirai.B/Linux.Mirai.B.zip
$ sha256sum Linux.Mirai.B.zip
b50681094c040883f3da8fe697bd3a9e35e62d1672f59d9f14e0db494f9d41c2 Linux.Mirai.B.zip
$ unzip -P infected Linux.Mirai.B.zip && chmod a-x 03254e62* f60b29cf*
$ ln -s 03254e6240c35f7d787ca5175ffc36818185e62bdfc4d88d5b342451a747156d old
$ ln -s f60b29cfb7eab3aeb391f46e94d4d8efadde5498583a2f5c71bd8212d8ae92da new
Compare
$ hereticus --format markdown old new
The report pairs 531 functions: 492 unchanged and 39 changed, with 115 new. The first rows are the parts of the bot that grew:
| FUNCTION | CHANGE | SCORE | +/-/~ | TOUCHED | MATCHED BY |
|---|---|---|---|---|---|
killer_init | changed | 0.17 | 2224/39/52 | 304 branch, 242 call, 77 jump, 438 mem, 62 const, 1 unread | same name |
table_init | changed | 0.20 | 1046/8/27 | 209 call, 1 jump, 337 mem, 49 const | same name |
exploit_worker | changed | 0.19 | 225/4/1 | 111 call, 1 mem | same name |
attack_method_udpgeneric -> attack_method_ovh | changed | 0.65 | 129/31/13 | 4 branch, 10 call, 40 mem, 7 const | same place |
attack_method_udpdns -> attack_method_tcpfrag | changed | 0.62 | 125/119/38 | 21 branch, 15 call, 5 jump, 68 mem, 17 const | same place |
killer_init, which kills other bots, andtable_init, which holds the texts the bot hides, grew most.exploit_workerstarts each exploit in turn: about 20 more of them, asexploit_socket_hnap,_tr064,_huawei,_realtekand_gpon8080, each with its*_IPGenthat picks the addresses to try.- Six attacks, as
attack_method_udpgeneric, are gone, and six new ones, asattack_method_ovh, came. The report pairs each gone attack with a new one at the same place, as it pairs a renamed function, such asrand_alpha_strwithrand_alphastr. Here the names say that the attacks are different ones.
An exploit that changed its target
exploit_socket_edimax changed by only a few instructions:
$ hereticus --view il --diff exploit_socket_edimax old new
...
- r1 = 0x1b8
- r1 = r1 + 3
r0 = r4
+ r1 = 0x50
call socket_connect_tcp
- r1 = &"GET /tmui/login.jsp/..;/tmui/locallb/wor..."
+ r1 = &"POST /goform/mp HTTP/1.1\r\nUser-Agent: Mo..."
r4 = r0
- r2 = 0xf5
r0 = sp
- call memcpy
+ call sprintf
...
In the old build, the function named for Edimax sends the F5 BIG-IP
request of CVE-2020-5902 to port 443. The new build sends a request for
Edimax devices to port 80. Before this comparison, the IL view showed
the load of the payload as r1 = load.32 [pc + 0x4c] on both sides, and
the swap read as no change (RESEARCH.md, “Two builds of Mirai”).
By code alone
--ignore-names pairs the functions as if the builds had no symbols,
and --format json keeps the names, so each pair can be checked:
$ hereticus --ignore-names --all --format json old new
Of the 520 names in both builds, 514 pair with their own name and none pairs with another. 6 stay unpaired:
exploit_socket_edimax,exploit_socket_drayandattack_method_tcpackchanged.EDIMAX_IPGenandDRAY_IPGendid not change, but each*_IPGenis one template that differs from the others only in the exploit it calls, so it pairs only when its callee pairs (TODO.md, “Tell twins apart that no instruction separates”).
Three functions that only the old build has pair with three that only the new one has:
rand_alpha_strwithrand_alphastr, a rename.attack_method_udpvsewithattack_method_udpgame: the code is the same but for its constants, so the attack is likely the same, renamed.exploit_socket_arubawithexploit_socket_tp: two copies of one template, for different devices.
Indicators
The zip also holds two download scripts, which fetch builds for ten architectures and set up cron jobs. The addresses are defanged.
| Indicator | Where |
|---|---|
79.124.8[.]24 | the host of fetch.sh in the exploits of both builds, and of the sora.* builds in one script |
78.142.18[.]20 | a text in both builds |
dotheneedfull[.]xyz | the host of the fetch.* builds in the other script |
46.239.223[.]80 | the DNS server the second script writes to /etc/resolv.conf |