flawopen.com/インシデント/Windows Updateスタックのジャンクション悪用による特権昇格ゼロデイ

Windows Updateスタックのジャンクション悪用による特権昇格ゼロデイ

高重大度 · CVSS 7.8 CWE-59: 不適切なリンク解決 (Link Following) インシデント分析 · 2026年9月
ELI5 (5歳児でもわかる解説)

オフィスの受付に誰でも郵便物を入れられる共通の回収箱があると想像してください。見習い社員が箱の内側に「この中身はすべて社長の専用金庫へ転送せよ」というメモを貼りました。夜になり、マスターキーを持つ警備員(SYSTEM権限で動くWindows Update)が回収にやってきます。警備員はメモの正当性を確認せず、言われた通り社長の金庫を開けて見習い社員の荷物を入れ、鍵の権限まで書き換えてしまいました。結果として、見習い社員がビル全体のマスターキーを手に入れたのです。

このページの重要用語
NTFSジャンクション / リパースポイント
NTFSファイルシステムの機能で、あるディレクトリへのアクセスを別のターゲットディレクトリへと透過的に転送する仕組み。
不適切なリンク解決 (CWE-59: Link Following)
高特権サービスが、低特権ユーザーが細工したシンボリックリンクやジャンクションを検証せずに辿ってしまう脆弱性。
Update Orchestrator (UsoSvc / MoUsoCoreWorker)
NT AUTHORITY\SYSTEM権限で動作し、OSのアップデート確認・一時展開・適用を担うWindowsの中核サービス。
任意ファイル書き込み・DACL書き換えプリミティブ
特権サービスのファイル生成処理を悪用してSystem32内のファイルを上書きしたり、アクセス権限を書き換えて管理者権限を奪う手法。

インシデントの概要

On September 8, 2026 (September 2026 Patch Tuesday), Microsoft released patches for an actively exploited zero-day vulnerability tracked as CVE-2026-81963. The vulnerability was discovered in the wild being utilized by sophisticated threat actors to elevate from low-privileged user accounts (and sandboxed AppContainers) to full NT AUTHORITY\SYSTEM control on Windows 11 and Windows Server 2025.

Classified under CWE-59 (Improper Link Resolution Before File Access), the flaw resided in the Windows Update Stack—specifically the Update Orchestrator worker (MoUsoCoreWorker.exe). The service relied on a staging directory inside C:\ProgramData\USOPrivate\UpdateStore\ to cache download manifests, metadata, and temporary update CAB files.

Because standard unprivileged users have permission to create folders and manipulate files within ProgramData, attackers replaced the staging directory with an NTFS directory junction point pointing to protected operating system directories (such as C:\Windows\System32). When the Update Orchestrator initiated a background scan or update check, it executed file creation and DACL permission resets as SYSTEM without verifying whether the directory had been redirected, granting attackers full control over critical system binaries.

技術的根本原因の徹底解剖

1. Permissive Staging Directory in a Shared Public Namespace

The Windows Update Stack used C:\ProgramData\USOPrivate\UpdateStore as its scratchpad. Under default Windows NTFS security descriptors, the C:\ProgramData root allows standard authenticated users to create subdirectories and files, creating a shared boundary between unprivileged users and a privileged system service.

2. Absence of FILE_FLAG_OPEN_REPARSE_POINT Validation

When MoUsoCoreWorker.exe accessed files and created folders in its staging directory, it invoked standard Win32 APIs (CreateFileW, CreateDirectoryW) without passing FILE_FLAG_OPEN_REPARSE_POINT. Windows transparently resolved the NTFS junction, redirecting the high-privilege write operations to the attacker's chosen target.

3. Unchecked Ownership and DACL Inheritance

The update worker failed to verify the filesystem security descriptor and owner SID of the staging path. If a path was owned by standard unprivileged users (e.g., BUILTIN\Users), the service should have rejected it immediately rather than trusting it for administrative operations.

脆弱な実装 vs 安全なファイル操作

VULNERABLE: BLIND REPARSE POINT RESOLUTION (MoUsoCoreWorker)
// Conceptual flaw in Windows Update Stack worker
BOOL StageUpdateManifest(LPCWSTR manifestName, PBYTE data, DWORD size) {
  WCHAR targetPath[MAX_PATH];
  // Path under user-writable ProgramData!
  StringCchPrintfW(targetPath, MAX_PATH, L"C:\\ProgramData\\USOPrivate\\UpdateStore\\%s", manifestName);

  // VULNERABILITY (CWE-59):
  // CreateFileW does NOT specify FILE_FLAG_OPEN_REPARSE_POINT!
  // If 'UpdateStore' is an NTFS junction to C:\Windows\System32,
  // this creates/overwrites files in System32 as NT AUTHORITY\SYSTEM!
  HANDLE hFile = CreateFileW(
      targetPath,
      GENERIC_WRITE,
      0,
      NULL,
      CREATE_ALWAYS,
      FILE_ATTRIBUTE_NORMAL, // Missing FILE_FLAG_OPEN_REPARSE_POINT
      NULL
  );

  WriteFile(hFile, data, size, &written, NULL);
  CloseHandle(hFile);
  return TRUE;
}
HARDENED: REPARSE POINT CHECK & TOKEN IMPERSONATION
// Fixed Windows Update Stack implementation
BOOL StageUpdateManifest(LPCWSTR manifestName, PBYTE data, DWORD size) {
  WCHAR targetPath[MAX_PATH];
  StringCchPrintfW(targetPath, MAX_PATH, L"C:\\ProgramData\\USOPrivate\\UpdateStore\\%s", manifestName);

  // FIX 1: Open directory with FILE_FLAG_OPEN_REPARSE_POINT to detect junctions
  HANDLE hDir = CreateFileW(
      L"C:\\ProgramData\\USOPrivate\\UpdateStore",
      GENERIC_READ,
      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
      NULL,
      OPEN_EXISTING,
      FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
      NULL
  );

  // Abort if target directory is a reparse point / junction
  BY_HANDLE_FILE_INFORMATION fileInfo;
  GetFileInformationByHandle(hDir, &fileInfo);
  if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
    CloseHandle(hDir);
    return FALSE; // Access Denied: Junction detected!
  }

  // FIX 2: Validate owner SID must be SYSTEM or Administrators
  if (!IsOwnerSystemOrAdmin(hDir)) {
    CloseHandle(hDir);
    return FALSE;
  }

  // Safe write strictly constrained to verified non-reparse path
  return SafeWriteVerifiedFile(targetPath, data, size);
}

検知およびエンドポイント監査ルール

# Sysmon Event ID 11: Detect junction point or symlink creation in USOPrivate EventID=11 AND TargetFilename="*\ProgramData\USOPrivate\*" # PowerShell: Audit reparse points under ProgramData Get-ChildItem -Path "C:\ProgramData" -Recurse -Force -ErrorAction SilentlyContinue | Where-Object { $_.LinkType -ne $null } # Sysmon Event ID 1: Detect unprivileged usoclient triggers EventID=1 AND CommandLine="*usoclient*StartInteractiveScan*"
Monitor EDR telemetry for any standard user creating symbolic links or reparse points under system directories, or triggering update orchestration scans outside of scheduled maintenance windows.

システム開発者の教訓と再発防止チェックリスト

情報源および公式アドバイザリ