(CVE-2025-54098) Windows Hyper-V vhdmp.sys Arbitrary File Write Leading to Elevation of Privilege

CVE: CVE-2025-54098

Affected Versions: Windows 10 (1507, 1607, 1809, 21H2, 22H2); Windows 11 (22H2, 23H2, 24H2); Windows Server 2008 R2 SP1 through 2025

CVSS3.1: 7.8 (High) — CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Summary

Product Windows Hyper-V (vhdmp.sys)
Vendor Microsoft
Severity High — a local unprivileged attacker may write arbitrary data to any file on the system
Affected Versions Windows 10 (1507, 1607, 1809, 21H2, 22H2); Windows 11 (22H2, 23H2, 24H2); Windows Server 2008 R2 SP1 – 2025
Tested Versions Windows 11 24H2 (Build 26100.4061)
CVE Identifier CVE-2025-54098
CVE Description Improper access control in Windows Hyper-V allows an authorized attacker to elevate privileges locally
CWE Classification(s) CWE-284: Improper Access Control

CVSS3.1 Scoring System

Base Score: 7.8 (High) Vector String: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Metric Value
Attack Vector (AV) Local
Attack Complexity (AC) Low
Privileges Required (PR) Low
User Interaction (UI) None
Scope (S) Unchanged
Confidentiality (C) High
Integrity (I) High
Availability (A) High

Product Background

The Virtual Hard Disk Miniport Driver (vhdmp.sys) handles VHD and ISO mount requests on Windows. It is present and running by default on every installation of Windows 11. The driver exposes IOCTL handlers that allow userspace to interact with virtual disk operations including CT Log management.

Technical Details

VhdmpiCTLogCreateBackingStore() is responsible for creating a file on disk to store CT Log data. It calls ZwCreateFile() with a file path that is fully user-controllable:

ObjectAttributes.RootDirectory = 0LL;
ObjectAttributes.ObjectName = (PUNICODE_STRING)(CTLogObj__ + 16);
ObjectAttributes.Length = 48;
ObjectAttributes.Attributes = 0x240;
*(_OWORD *)&ObjectAttributes.SecurityDescriptor = 0LL;
if ( !a5
  || (HIWORD(EaBuffer[0]) = 16,
      strcpy((char *)&EaBuffer[1], "ClusteredApplicationInstance"),
      v17 = *a5,
      BYTE5(EaBuffer[0]) = 28,
      *(_OWORD *)((char *)&EaBuffer[4] + 5) = v17,
      ZwCreateFile(
        &FileHandle,
        0xC0000000,
        &ObjectAttributes,
        &IoStatusBlock,
        0LL,
        0x80u,
        1u,
        1u,
        0x42u,
        EaBuffer,
        0x38u) < 0) )
{
    v18 = ZwCreateFile(&FileHandle, 0xC0000000, &ObjectAttributes,
                       &IoStatusBlock, 0LL, 0x80u, 1u, 1u, 0x42u, 0LL, 0);
    status = v18;
    if ( v18 < 0 )
        goto LABEL_12;
}

The critical issue is that the OBJ_FORCE_ACCESS_CHECK flag is not passed in OBJECT_ATTRIBUTES, and the Zw* API variant is used instead of Nt*. When called from kernel mode via Zw* without OBJ_FORCE_ACCESS_CHECK, Windows skips the access check against the caller’s token entirely. This means a low-privileged user can supply a path to any file on the system — including protected system files — and the kernel will open it without verifying whether the caller has write permission.

After the file is opened, the driver writes CT Log header data followed by user-influenced CT Log content. Since the log data can be partially controlled by the caller, this enables:

  • Permanent DoS — corrupting core system files, requiring OS reinstallation to recover
  • Security tool bypass — overwriting AV/EDR executables or configuration files
  • Potential code execution — with partial data control, further exploitation may be possible

One path to reach VhdmpiCTLogCreateBackingStore() is via IOCTL 0x2D197C, which calls VhdmpiEnableTracking(). Directory traversal (\..\) and NTFS junctions are both viable techniques for redirecting the file path to an arbitrary target.

The fix is to pass OBJ_FORCE_ACCESS_CHECK in the OBJECT_ATTRIBUTES when calling ZwCreateFile(), which restores the access check against the caller’s security token.

Credit

Chen Le Qi of STAR Labs SG Pte. Ltd.

Timeline