MMD-0028-2014 - Linux/XOR.DDoS : Fuzzy reversing a new China ELF

Sticky note: The latest incident (MMD-0033-2015) we disclosed on ELF Linux/XOR.DDoS malware is here -->[LINK]

This research is detected & solved by a hard work of MMD members. Credits are in the bottom of the post.
The case is on and malware infrastructure is mostly up & alive, we don't want to be too details in writing because of that reason, we don't want to teach this crook of what they're lacking of by this post, yet this post necessary to raise awareness of this new emerged threat. Feel free to follow the process at will.

The infection

During the rush of #shellshock we saw another new threat emerged. We saw an attack log of one-liner shell script being injected via ssh connection. By the attack source+CNC IP and the payload, this looks like a China crook's new hack scheme to spread new ELF DDoS'er threat. This is spotted silently spread during the ‪#‎shellshock waves, noted: it was NOT using #shellshock exploit itself.

The details of the attacker's trace in one-liner shell command is as per shown below:

If we beautified it as per below we will see the obfuscation this shell script:

↑the marked mark is the point of all these code, to download the file 3502.rar from some defined host addresses.

The mentioned RAR file itself is actually a shell script too:

You can read the codes here, no free ride copy/paste this time, since we have hard times with those false positives from antiviruses

The main() function is explaining how this script works, read the comments we made (in purple colored words):

Shortly. The blue color explaining the obfuscation strings saved in some variables. The yellow marked color words are functions to be executed, and the red color area is the main function of this script, to download and install a payload.

The obfuscation used is in the enc() and dec() function (see that big pic codes) for encryption and decryption, by using the below code (I picked this one, the one used for decrypting)

tr "[.0-9a-zA-Z\/\/\:]" "[a-zA-Z0-9\;-=+*\/]";
They called it encryption, but is just a mere obfuscator using the character map translation in "tr". Below is the easy shell script I made to decode them:

Below is the result:

We'll see another 3502 file. And a bunch of the CNC used. Noted the username and password they use ;)

If you permutated the URL with the payload name you will some ALIVE malware URLs like these:

What is this thing? In short: It's a sophisticated & well-thought ELF malware infection scheme, aiming Linux in multiple platform. It downloads, detect all parameter need to download the payload or source code of payload. It detected infected host's architecture, compiler. libraries together with sending sensitive information of the host, sent request to CNC to download the certain bins or to download resources to hack and then install the ELF binary.

The POC of this hack is the payload below:

The payload

The header looks very "fine":

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: Intel 80386
Version: 0x1
Entry point address: 0x8048110
First block:

Various analysis can resulted to the payload was coded in C, hmm..a quality up, we have a challenger here :) A new DDoS'er made in China. Here's the codes (for future reference):

'crtstuff.c'
'autorun.c'
'crc32.c'
'encrypt.c'
'execpacket.c'
'buildnet.c'
'hide.c'
'http.c'
'kill.c'
'main.c'
'proc.c'
'socket.c'
'tcp.c'
'thread.c'
'findip.c'
'dns.c'
Some pointers for characteristic:

Self copy:

// create file for self-copy
open("/boot/[a-z]{10}", O_WRONLY|O_CREAT, 0400)
open("/boot/[a-z]{10}", O_WRONLY)

//chmod 755
chmod("/boot/[a-z]{10}", 0750)

// start to write..
open("/boot/[a-z]{10}", O_RDONLY)
Auto start:
// install SYS

.text:0x8048B2E mov dword ptr [esp], offset aSbinInsmod <== "/sbin/insmod"
.text:0x8048B35 call LinuxExec_Argv
.text:0x8048B3A mov dword ptr [esp], 2
.text:0x8048B41 call sleep

// xinetd setup..

.text:0x8048852 call abstract_file_name
.text:0x8048857 mov [ebp+var_8], eax
.text:0x804885A mov eax, [ebp+arg_0]
.text:0x804885D mov [esp+0Ch], eax
.text:0x8048861 mov dword ptr [esp+8], offset aBinShS <== "#!/bin/sh\n%s\n"
.text:0x8048869 mov dword ptr [esp+4], 400h
.text:0x8048871 lea eax, [ebp+newpath]
.text:0x8048877 mov [esp], eax
.text:0x804887A call snprintf
:
.text:0x804887F mov eax, [ebp+var_8]
.text:0x8048882 mov [esp+0Ch], eax
.text:0x8048886 mov dword ptr [esp+8], offset aEtcInit_dS <== "/etc/init.d/%s"
.text:0x804888E mov dword ptr [esp+4], 400h
.text:0x8048896 lea eax, [ebp+filename]
.text:0x804889C mov [esp], eax
.text:0x804889F call snprintf
.text:0x80488A4 mov dword ptr [esp+4], offset aW <== "w"
.text:0x80488AC lea eax, [ebp+filename]
.text:0x80488B2 mov [esp], eax
.text:0x80488B5 call fopen
:
.text:0x8048980 mov dword ptr [esp+8], offset aEtcRcD_dS90S <== "/etc/rc%d.d/S90%s"
.text:0x8048988 mov dword ptr [esp+4], 400h
.text:0x8048990 lea eax, [ebp+newpath]
.text:0x8048996 mov [esp], eax
.text:0x8048999 call "snprintf"
.text:0x804899E lea eax, [ebp+newpath] // assemble flag component for file attribs
.text:0x80489A4 mov [esp], eax <== "filename"
.text:0x80489A7 call "unlink"
.text:0x80489AC lea eax, [ebp+newpath]
.text:0x80489B2 mov [esp+4], eax <== "newpath"
.text:0x80489B6 lea eax, [ebp+filename]
.text:0x80489BC mov [esp], eax <== "oldpath"
.text:0x80489BF call "symlink"
.text:0x80489C4 cmp [ebp+var_C], 0
.text:0x80489C8 jnz short loc_80489E8
.text:0x80489CA mov dword ptr [esp+8], 0AD1473B8h <== "group"
.text:0x80489D2 mov dword ptr [esp+4], 0AD1473B8h <== "owner"
.text:0x80489DA lea eax, [ebp+filename]
.text:0x80489E0 mov [esp], eax <== "filename"
.text:0x80489E3 call "lchown"
Malicious environment setup (i.e. export cmd):
0x06988C   HOME=/
0x069893 HISTFILE=/dev/null
0x0698A6 MYSQL_HISTFILE=/dev/null
0x0698C0 PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

Encryption:

There are some encryption to be decrypted in this malware, that I tested as per below, that looks having xor pattern:

// checking decryptor...

.text:0x804CB63 mov dword ptr [esp+4], offset aM_Nfr7nlqqgf_0
.text:0x804CB6B lea eax, [ebp+filename]
.text:0x804CB71 mov [esp], eax
.text:0x804CB74 call dec_conf // decrypting function..
.text:0x804CB79 mov dword ptr [esp+8], 0Ch // <== break it here..

Breakpoint 1, 0x0804cb79 in main ()
query offset aM_Nfr7nlqqgf_0: "m.[$nFR$7nLQQGF"
query register: $esp
0xffffa1b0: "[\305\377\377\343\033\v\b\020"
;-----------------------
.text:0x804CB81 mov dword ptr [esp+4], offset aM_Nfr7n9_0
.text:0x804CB89 lea eax, [ebp+var_114D]
.text:0x804CB8F mov [esp], eax
.text:0x804CB92 call dec_conf

Breakpoint 2, 0x0804cb9 in main ()
query offset aM_Nfr7n9_0: "m.[$nFR$7n9"
query register: $esp
0xffffa1b0: "[\304\377\377\363\033\v\b\f"
;-----------------------
.text:0x804CBBD mov dword ptr [esp+4], offset aM4s4nacNa ; "m4S4nAC/nA"
.text:0x804CBC5 lea eax, [ebp+var_E4D]
.text:0x804CBCB mov [esp], eax
.text:0x804CBCE call dec_conf
.text:0x804CBD3 mov [ebp+var_34], 0

Breakpoint 3, 0x0804cbd3 in main ()
query offset aM4s4nacNa ; "m4S4nAC/nA"
query register: $esp
0xffffa1b0: "[\307\377\377#\034\v\b\v"
Here is the xor used as the component logic for the decryption function:

With the key that lead to this address:

It "looks like" the author is having "interesting" way to remind him the XOR key itself, I don't investigate this further since I had the goal..

A hard-coded callback IP address

And look what I got next to the xor key :))

So now we know the CNC is too ;)

IP: 103.25.9.228||59270 | 103.25.9.0/24 | CLOUD 
Country: "HK | CLOUDRELY.COM" |CLOUD RELY LIMITED

The bummer part of this malware is, it crashed itself when run under limited permission...

"msec   calls "
-----------------------------------------------------------------------
(120): execve("./SAMPLE-MALWARE", ["./SAMPLE-MALWARE"], ["SHELL=etc..])
(125): set_thread_area(0xffc8373c)
(126): set_tid_address(0x92e6888)
(127): set_robust_list(0x92e6890, 0xc)
(128): futex(0xffc83a04, FUTEX_WAKE_PRIVATE, 1)
(129): rt_sigaction(SIGRTMIN, {0x8053860, [], SA_SIGINFO}, NULL, 8)
(130): rt_sigaction(SIGRT_1, {0x8053780, [], SA_RESTART|SA_SIGINFO}, NULL, 8)
(131): rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8)
(132): getrlimit(RLIMIT_STACK,etc)
(133): uname({sysname="Linux", nodename="mmd", release="mmd-amd64",
version="#1 SMP mmd-7u1", machine="saever-momma"})
(142): readlink("/proc/self/exe", "/home/mmd/test/SAMPLE-MALWARE", 1023)
(143): clone(Process)
(145): exit_group(0)
(146): [pid new] setsid()
(147): open("/dev/null", O_RDWR)
(148): fstat64(3, {st_dev=makedev] etc)
(149): dup2(3, 0)
(150): dup2(3, 1)
(151): dup2(3, 2)
(152): close(3)
(153): readlink("/proc/self/exe", "/home/mmd/test/SAMPLE-MALWARE", 1023) = 20
(154): stat64("/boot" etc)
(155): stat64("/lib", etc)
(156): stat64("/lib/udev" etc)
(157): stat64("/var", etc)
(158): stat64("/var/run", etc)
(159): gettimeofday({1411989055, 135168}, NULL)
(160): readlink("/proc/self/exe", "/home/mmd/test/SAMPLE-MALWARE", 1023)
(161): unlink("/lib/udev/udev")
(162): open("/home/mmd/test/SAMPLE-MALWARE", O_RDONLY)
(163): open("/lib/udev/udev", O_WRONLY|O_CREAT, 0400)
(165): open("/home/mmd/test/SAMPLE-MALWARE", O_RDONLY)
(166): open("/boot/[a-z]{10}", O_WRONLY|O_CREAT, 0400)
(168): open("/boot/[a-z]{10}", O_WRONLY)
(169): clone(Process attached
(171): waitpid(Process suspended
(173): clone(Process attached
(175): exit_group(0)
(179): rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8)
(180): rt_sigaction(SIGCHLD, NULL, {SIG_IGN, [CHLD], SA_RESTART}, 8)
(181): nanosleep({1, 0},..
(192): chmod("/boot/[a-z]{10}", 0750)
(193): open("/boot/[a-z]{10}", O_RDONLY)
(194): "--- SIGSEGV (Segmentation fault) @ 0 (0)" --- ref: [a-z]{10}
(197): "rt_sigprocmask(SIG_SETMASK, [], NULL, 8)"
It saves the file in /boot with this regex: [a-z]{10}

What is the purpose of this malware?

The first is backdoor, and then, obviously DoS (SYN, UDP, TCP flood), using encrypted (temporary) config. Below is the PoC of the DDoS function names:

0x09305E   build_syn // SYN Flood
0x0950D0 build_tcphdr // TCP Flood
0x097101 build_udphdr // UDP FLood
And below is part of backdoor operation using HTTP/1.1 GET (to download / update) and callback in HTTP/1.1 POST:
.text:0x804A917   mov   dword ptr [esp+8], offset aPostSHttp1_1Sh
value: "POST %s HTTP/1.1\r\n%sHost: %s\r\nContent-T"
.text:0x804AB1D mov dword ptr [esp+8], offset aGetSHttp1_1Sho
value: "GET %s HTTP/1.1\r\n%sHost: %s\r\n%s"
Based on the code it looks like using AES.DDoS'er and IptabLes strategy to install, but the source are different. So, this is another new China DDoS'er, I call this as Linux/XOR.DDoS.

Virus Total and sample

Virus total detection is below (click the image to access..) One of 55 is a bad detection..

Sample is shared in kernel mode-->[here]

Conclusion & Credits

This threat is the first time we see using complicated installer/builder. I and other team mates start to feel like playing CTF with this crook. They (China actors) are improving in steps, we must be aware. Please stay safe folks..

Credit: @shibumi (threat sensoring), @wirehack7 (formulation), and others who doesn't want to be mentioned.

Additional

(A reserved section for additional and updates)

#MalwareMustDie!!