# Root Cause Analysis — CVE-2025-60705

## Overview

| | |
|---|---|
| CVE | CVE-2025-60705 |
| Binary | csc.sys (Windows Client-Side Caching kernel driver) |
| Impact | Elevation of Privilege |
| CVSS | 7.8 (Important) — Exploitation More Likely |
| CWE | CWE-284: Improper Access Control |
| Pre-patch version | 10.0.26100.5074 |
| Post-patch version | 10.0.26100.7171 |
| KB | KB5068861 (November 2025) |
| Credit | [T0 (@t0zhang)](https://x.com/t0zhang) |

## Root Cause

The Windows Client-Side Caching (CSC) kernel driver (`csc.sys`) performs privileged registry operations on behalf of the calling user **without validating the caller's identity or access rights**. Specifically, `CscRebootRenamepOpenKey` calls `ZwCreateKey`/`ZwOpenKey` with `OBJECT_ATTRIBUTES.Attributes = 0x240` (`OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE`), which is missing `OBJ_FORCE_ACCESS_CHECK` (0x400). Because the driver runs at SYSTEM level, the Zw* calls bypass all access checks, allowing any low-privileged user to create or open arbitrary registry keys in protected hives.

The attacker triggers this via the Offline Files COM interface (`IOfflineFilesCache::RenameItem`), which dispatches through RDBSS to `CscRebootRenameAddEntry`. By placing a **registry symbolic link** at the expected CSC registry path (`HKLM\SYSTEM\CurrentControlSet\Services\CSC\Parameters\RebootRename`), the attacker redirects the SYSTEM-level registry write to an arbitrary location (e.g., creating a malicious service entry).

This is architecturally similar to CVE-2022-35820 (bthport.sys EoP via registry symlink).

## Ghidra-Verified Call Chain

```
User-mode entry point:
  CoCreateInstance(CLSID_OfflineFilesCache, ..., IID_IOfflineFilesCache, ...)
    → IOfflineFilesCache::RenameItem(oldPath, newPath)
      → DeviceIoControl / IRP_MJ_FILE_SYSTEM_CONTROL to csc.sys

Kernel call chain (pre-patch csc.sys 10.0.26100.5074):

  CscInitializeDispatchTable @ 0x14009251e
    → Registers CscFsCtl in dispatch table (DATA xref @ 0x1400423a4)

  CscFsCtl @ 0x14007d080
    → CscDclInternalFsControl @ 0x14007d520
      → Jump table dispatch on FSCTL operation code (table @ 0x1400347c8)
        → CscDclMRxRebootRenameAdd @ 0x140019c90         [thin wrapper]
          → CscRebootRenameAddEntry @ 0x14004fd9c
            → CscStoreRebootRenameIsValidRename()         [input validation]
            → CscRebootRenamepOpenKey @ 0x140050870       [VULNERABLE]
              → ZwCreateKey / ZwOpenKey with Attributes=0x240
                (OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE)
                MISSING: OBJ_FORCE_ACCESS_CHECK (0x400)
            → CscRebootRenamepAddToKey @ 0x1400501d8
              → CscRebootRenamepOpenKey()                 [also vulnerable]
              → CscRegistrypWriteString()                 [writes rename entries]
              → CscRegistrypWriteULong()                  [writes index counter]
```

### Vulnerable Code — CscRebootRenamepOpenKey

From Ghidra decompilation at `0x140050870` (162 bytes pre-patch):

```c
void CscRebootRenamepOpenKey(
    undefined8 *param_1,      // output: key handle
    undefined8 param_2,       // UNICODE_STRING* registry path
    char param_3,             // create flag (1=create, 0=open)
    undefined1 *param_4)      // disposition output
{
    *param_1 = 0;
    // Build OBJECT_ATTRIBUTES on stack
    local_38 = 0x30;            // Length
    local_20 = 0x240;           // Attributes = OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE
                                //              ← MISSING OBJ_FORCE_ACCESS_CHECK (0x400)
    local_28 = param_2;         // ObjectName = registry path
    local_18 = 0; uStack_10 = 0; // SecurityDescriptor = NULL, SQoS = NULL

    if (param_3 == '\0') {
        ZwOpenKey(0, 0xf003f, &local_38);      // KEY_ALL_ACCESS, no access check
    } else {
        ZwCreateKey(0, 0xf003f, &local_38, 0, 0, 0, local_res18);  // KEY_ALL_ACCESS
    }
}
```

Key issue: `Attributes = 0x240` means the kernel performs the registry operation with SYSTEM privileges, completely ignoring the caller's security context. A legitimate fix would be either:
- Adding `OBJ_FORCE_ACCESS_CHECK` (0x400) → `Attributes = 0x640`
- Or performing an explicit privilege check before the call (what Microsoft chose)

### Registry Path Used

From `CscRebootRenameAddEntry` decompilation:

```c
local_38 = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\CSC\\Parameters\\RebootRename";
local_58 = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\CSC\\Parameters";
```

The attacker creates a registry symbolic link at this path to redirect the SYSTEM-level `ZwCreateKey` to an arbitrary registry location.

## The Fix

The patch adds a **feature-flag-gated explicit caller privilege check** (function grew from 162 → 406 bytes):

1. `FeatureFlagEvaluator` at `0x1400220c4` — checks the Controlled Feature Rollout (CFR) state
2. When enabled, calls `PrivilegeCheckHelper` at `0x140050420` before `ZwCreateKey`
3. The helper acquires the calling thread's security context and validates it against the required access rights
4. If the check fails (NTSTATUS < 0), `ZwCreateKey`/`ZwOpenKey` is skipped entirely
5. When the feature flag is disabled (kill-switch), the old vulnerable code path executes unchanged

## Attack Surface Analysis

### Prerequisites
- Any local user (low-privileged)
- Offline Files feature must be available (default on Windows client SKUs)
- CSC service must be running

### Attack Steps
1. Create a registry symbolic link from `HKLM\...\CSC\Parameters\RebootRename` to an attacker-chosen target path (e.g., `HKLM\SYSTEM\CurrentControlSet\Services\MaliciousService`)
2. Invoke `IOfflineFilesCache::RenameItem()` via COM — this triggers the CSC driver's reboot-rename logic
3. `CscRebootRenamepOpenKey` calls `ZwCreateKey` with SYSTEM privileges, following the symbolic link to the attacker's target
4. The driver creates/opens the key at the redirected path and writes rename entries as string values
5. Result: arbitrary registry key creation in protected hives under SYSTEM context

### Impact
Full SYSTEM-level registry write primitive. An attacker can:
- Create malicious service entries for persistence
- Modify security-sensitive registry keys
- Install rootkit-level persistence via boot-start drivers
- Disable security features by modifying their configuration keys

## Detection Rules

### YARA — PoC Detection

```yara
rule CVE_2025_60705_CSC_Registry_Symlink_EoP
{
    meta:
        description = "Detects PoC/exploit code for CVE-2025-60705 csc.sys registry symlink EoP"
        author = "OnlyFm252"
        date = "2026-07-18"
        cve = "CVE-2025-60705"
        severity = "high"

    strings:
        $reg_path1 = "CSC\\Parameters\\RebootRename" ascii wide nocase
        $reg_path2 = "CurrentControlSet\\Services\\CSC" ascii wide nocase
        $api1 = "IOfflineFilesCache" ascii wide
        $api2 = "RenameItem" ascii wide
        $api3 = "NtCreateKey" ascii
        $api4 = "RegCreateKeyEx" ascii
        $symlink1 = "REG_LINK" ascii wide
        $symlink2 = "SymbolicLinkValue" ascii wide
        $com_clsid = "{48C45312-3E30-11D3-8B2D-00C04FB9513B}" ascii wide  // CLSID_OfflineFilesCache

    condition:
        uint16(0) == 0x5A4D and
        (($reg_path1 and ($symlink1 or $symlink2)) or
         ($reg_path2 and $api1) or
         ($com_clsid and ($api3 or $api4)))
}
```

### YARA — Vulnerable Binary Detection

```yara
rule CVE_2025_60705_Vulnerable_csc_sys
{
    meta:
        description = "Detects pre-patch csc.sys vulnerable to CVE-2025-60705"
        author = "OnlyFm252"
        date = "2026-07-18"
        cve = "CVE-2025-60705"

    strings:
        // CscRebootRenamepOpenKey: MOV DWORD [rbp-0x18], 0x240
        // This is the Attributes = OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE
        // without the feature flag check preceding it
        $attr_set = { C7 45 E8 40 02 00 00 }  // mov [rbp-0x18], 0x240

        // Small function size indicator (162 bytes = 0xA2)
        $driver = "csc.sys" ascii wide

        // The feature flag call should NOT be present in vulnerable version
        $feature_flag = { E8 [4] 85 C0 74 }  // call FeatureFlag; test eax,eax; jz

    condition:
        uint16(0) == 0x5A4D and
        $driver and
        $attr_set and
        not $feature_flag
}
```

### Sigma — Registry Symbolic Link at CSC Parameters

```yaml
title: Registry Symbolic Link at CSC RebootRename Path
id: a3c8f291-60b5-4e1a-b902-cve202560705a
status: experimental
description: |
    Detects creation of registry symbolic links at the CSC Parameters
    RebootRename path, which is the attack vector for CVE-2025-60705.
    A symbolic link here redirects SYSTEM-level ZwCreateKey calls to
    an attacker-chosen registry path.
author: OnlyFm252
date: 2026/07/18
references:
    - https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-60705
logsource:
    category: registry_event
    product: windows
detection:
    selection:
        EventType: SetValue
        TargetObject|contains|all:
            - 'Services\CSC\Parameters'
            - 'RebootRename'
        Details|contains: '\\Registry\\'
    condition: selection
level: high
tags:
    - attack.privilege_escalation
    - attack.t1547.001
    - cve.2025.60705
```

### Sigma — Offline Files COM Instantiation from Suspicious Process

```yaml
title: Suspicious IOfflineFilesCache COM Instantiation
id: a3c8f291-60b5-4e1a-b902-cve202560705b
status: experimental
description: |
    Detects processes loading cscobj.dll (Offline Files COM server) that
    are not the standard Offline Files UI or sync components. This is
    a prerequisite for triggering CVE-2025-60705 via IOfflineFilesCache::RenameItem.
author: OnlyFm252
date: 2026/07/18
logsource:
    category: image_load
    product: windows
detection:
    selection:
        ImageLoaded|endswith: '\cscobj.dll'
    filter_known:
        Image|endswith:
            - '\mobsync.exe'
            - '\cscui.dll'
            - '\explorer.exe'
            - '\svchost.exe'
    condition: selection and not filter_known
level: medium
tags:
    - attack.privilege_escalation
    - attack.t1547.001
    - cve.2025.60705
```

### Sysmon Configuration

```xml
<!-- CVE-2025-60705: Monitor for CSC registry symlink exploitation -->

<!-- Rule: Detect registry modifications to CSC RebootRename path -->
<RuleGroup name="CVE-2025-60705" groupRelation="or">
  <RegistryEvent onmatch="include">
    <TargetObject condition="contains">Services\CSC\Parameters\RebootRename</TargetObject>
  </RegistryEvent>
</RuleGroup>

<!-- Rule: Detect cscobj.dll loading from unusual processes -->
<RuleGroup name="CVE-2025-60705-COM" groupRelation="or">
  <ImageLoad onmatch="include">
    <ImageLoaded condition="end with">cscobj.dll</ImageLoaded>
  </ImageLoad>
</RuleGroup>

<!-- Rule: Detect csc.sys driver operations -->
<RuleGroup name="CVE-2025-60705-Driver" groupRelation="or">
  <DriverLoad onmatch="include">
    <ImageLoaded condition="end with">csc.sys</ImageLoaded>
  </DriverLoad>
</RuleGroup>
```

## References

- [MSRC — CVE-2025-60705](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-60705)
- Diff report: [csc_sys-kb5068861.md](/data/patch_diffs/csc_sys-kb5068861.md)
- Similar: CVE-2022-35820 (bthport.sys registry symlink EoP)

---

<sub>Analysis by OnlyFm252 — Ghidra MCP call-flow analysis of csc.sys 10.0.26100.5074 (pre-patch).</sub>
