
タイプ: 概念実証 — シミュレーション(非機能) CVE: CVE-2021-1675 + CVE-2021-34527 CVSS: 7.8 (LPE) / 8.8 (RCE) 別名: PrintNightmare パッチ適用: 2021年6月/7月 — KB5004945 CISA KEV に追加: 2021年7月
⚠️ このPoCのペイロードは明示的に架空かつ非悪意のものです — DCE/RPCヘッダーの4バイトとASCIIの関数名のみで構成されています。コードを実行せず、ドライバーをインストールせず、権限を昇格させません。学習および検知開発目的のみに使用します。
Developed by: HKK$ cat ./vulnerability_summary.txtCVE-2021-1675、通称 PrintNightmare は、Windows Print Spooler サービスにおける重大なリモートコード実行およびローカル権限昇格の脆弱性です。この欠陥により、攻撃者はアクセス制御の検証が不十分なプリンタードライバーのリモートインストールに使用される RpcAddPrinterDriverEx() 関数を悪用して、SYSTEM 権限で任意のコードを実行できます。
当初はLPE(CVSS 7.8)として分類され、2021年6月のPatch Tuesdayでパッチが適用されましたが、Microsoftは6月21日にこの脆弱性をRCE(CVSS 8.8)として再分類しました。混乱を避けるため、RCEベクターには新しい識別子 CVE-2021-34527 が割り当てられました — 両者は一般的に PrintNightmare と呼ばれています。
$ cat ./timeline.txt2021年6月8日 MicrosoftがPatch Tuesdayで初期パッチを公開 — CVE-2021-1675 (LPE, CVSS 7.8)
2021年6月21日 MicrosoftがRCE (CVSS 8.8) として再分類
2021年6月29日 研究者が誤ってPoCを公開 — 既にパッチ済みの同じ脆弱性と誤認
2021年7月1日 CVE-2021-34527 がRCEベクターに割り当て — 元のLPEとは別
2021年7月2日 Microsoftが緊急の帯域外パッチを公開: KB5004945
2021年7月 CISAが既知の悪用された脆弱性カタログに追加
ランサムウェアグループ(Vice Society、Magniberなど)による活発な悪用
$ cat ./architecture.txt┌──────────────────────────────────────────────────────────────────────────┐
│ PRINTNIGHTMARE — 攻撃フロー │
│ │
│ 攻撃者 (認証済みユーザー) WINDOWS PRINT SPOOLER │
│ (spoolsv.exe) │
│ 1. 任意の有効なドメインアカウントで ┌────────────────────────────┐ │
│ 認証 │ SYSTEMとして実行 │
│ │ │ 全Windowsでデフォルト有効 │ │
│ 2. named pipe \pipe\spoolss 経由で │ DCを含む │ │
│ RPC接続 └──────────────┬─────────────┘ │
│ │ │ │
│ 3. RpcAddPrinterDriverEx() を呼び出し │ │
│ 悪意のあるDLLへのパスを指定 ──────────────────────►│ │
│ (UNC: \\attacker\share\evil.dll) │ │
│ ┌────────────▼────────────┐ │
│ │ Print Spoolerがドライバー│ │
│ │ (DLL) をSYSTEMとして │ │
│ │ 読み込み。発信元や整合性 │ │
│ │ を検証しない │ │
│ └────────────┬────────────┘ │
│ │ │
│ ◄── SYSTEMとしてのRCE / LPE ──────────────────────────┘ │
│ 新しい管理者ユーザー、リバースシェル、 │
│ ランサムウェア展開など │
│ │
│ ───────────────────────────────────────────────────────────────────── │
│ このPoC: TCP接続 + 25バイトのみ → 実際のRPCなし → エクスプロイトなし │
└──────────────────────────────────────────────────────────────────────────┘
$ cat ./design_decisions.mdfake_rpc_payload = b"\x05\x00\x0b\x03RpcAddPrinterDriverEx"
このペイロードは 25バイト で、2つの概念を同時に示しています:
バイト0〜3: 正当なDCE/RPCヘッダー
| バイト | 値 | 意味 |
|---|---|---|
\x05 | 5 | DCE/RPCプロトコルバージョン (バージョン5 — Windows標準) |
\x00 | 0 | マイナーバージョン0 |
\x0b | 11 | PDUタイプ: BIND — RPCネゴシエーションの最初のステップ |
\x03 | 3 | フラグ: `PFC_FIRST_FRAG(0x01) |
バイト4〜24: ASCIIの関数名
RpcAddPrinterDriverEx — 脆弱な関数名を平文で表記。
このペイロードが実際のエクスプロイトとして機能しない理由は?
正当なRPC BINDでは、4バイトのヘッダーの後に以下が必要です:
- max_xmit_frag (2バイト)
- max_recv_frag (2バイト)
- assoc_group_id (4バイト)
- num_ctx_items (1バイト)
- context_elem[] → MS-RPRNのインターフェースUUID:
{12345678-1234-ABCD-EF00-0123456789AB}
- transfer_syntaxes → NDR UUID
この構造がない場合、Windowsはパケットを即座に拒否します。このペイロードは実質的に接続性の表明に過ぎません — 「この架空のペイロードでポート445に到達できるか?」ということです。
sock.connect((target_ip, 445))
なぜ135 (RPC Endpoint Mapper) ではなく445なのか?
PrintNightmare はRPC直接ではなく、SMB named pipe \pipe\spoolss をトランスポートとして使用します。実際のフローは以下の通りです:
1. TCP接続 → ポート445 (SMB)
2. SMBネゴシエーション + セッションセットアップ (NTLM/Kerberos認証)
3. Tree connect → IPC$
4. Named pipeオープン → \pipe\spoolss
5. DCE/RPC BIND → MS-RPRNインターフェース
6. NDRマーシャリングによる RpcAddPrinterDriverEx() 呼び出し
PoCはステップ1のみをシミュレートします — 初期TCP接続 — ステップ2〜6は実装していません。
sock.settimeout(5): 5秒のタイムアウトにより、応答しないホストでPoCがブロックされるのを防ぎます。ポートの可用性を迅速にスキャンするのに役立ちます。
| 側面 | CVE-2021-1675 | CVE-2021-34527 |
|---|---|---|
| ベクター | ローカル (LPE) | リモート (RCE) |
| CVSS | 7.8 | 8.8 |
| 認証 | ローカルアカウント | 認証済みドメインアカウント |
| パッチ | 2021年6月 (Patch Tuesday) | 2021年7月 (帯域外 KB5004945) |
| 脆弱な関数 | RpcAddPrinterDriverEx | RpcAddPrinterDriverEx |
| シナリオ | ローカル権限昇格 | SMB named pipe経由のリモートRCE |
両者の根本原因は同じです: RpcAddPrinterDriverEx() 関数がドライバーファイルの発信元の検証に失敗し、ドライバーインストールに適切な権限制約を課さず、読み込まれるDLLの信頼性や整合性を検証しません。
$ cat ./mitre_mapping.ymltactic: Initial Access / Lateral Movement
- T1210 # Exploitation of Remote Services
# \pipe\spoolss 経由のRPC呼び出しでリモートホストへ
# 有効なドメイン資格情報が必要
tactic: Privilege Escalation
- T1068 # Exploitation for Privilege Escalation
# Print Spooler経由で一般ユーザー → SYSTEM
# CVE-2021-1675 (LPE): ローカルプロセスがSYSTEMに昇格
tactic: Execution
- T1569.002 # System Services: Service Execution
# spoolsv.exe がSYSTEMとして悪意のあるDLLを読み込む
# Windowsサービスのコード実行に相当
- T1055 # Process Injection
# spoolsv.exe (SYSTEM) プロセスのコンテキストにDLLが注入される
tactic: Persistence
- T1547.012 # Boot or Logon Autostart: Print Processors
# 登録されたドライバーが再起動後も持続
# 保存場所: HKLM\SYSTEM\CurrentControlSet\Control\Print\
tactic: Defense Evasion
- T1036.005 # Masquerading: Match Legitimate Name or Location
# 悪意のあるDLLが正規ドライバー名を装う (例: Canon_XP.dll)
$ cat ./detection_opportunities.md# イベントID 808 — Print Spoolerが疑わしいDLLの読み込みに失敗
# ソース: Microsoft-Windows-PrintService/Admin
条件:
EventID: 808
Log: Microsoft-Windows-PrintService/Admin
Level: Error
Description CONTAINS: "failed to load a plug-in module"
実際の証拠 (実環境で観測):
"The print spooler failed to load a plug-in module
C:\Windows\system32\spool\DRIVERS\x64\3\svch0st.dll"
# svchost.dll のタイポスクワッティング → 悪意のあるDLL
# イベントID 316 — RpcAddPrinterDriverEx経由でドライバーがインストールされた
# ソース: Microsoft-Windows-PrintService/Admin
条件:
EventID: 316
Log: Microsoft-Windows-PrintService/Admin
Message CONTAINS: "RpcAddPrinterDriverEx"
OR
Message CONTAINS: "\\\\*\\*" # UNCパス → リモートDLL
# Print Spoolerの疑わしい子プロセス
EventID: 1 (Process Creation)
条件:
ParentImage: C:\Windows\System32\spoolsv.exe
Image: cmd.exe OR powershell.exe OR wscript.exe OR mshta.exe
重大度: 重大 — spoolsv はシェルを生成すべきではない
# 非標準パスから読み込まれたDLL
EventID: 7 (Image Loaded)
条件:
Image: C:\Windows\System32\spoolsv.exe
ImageLoaded NOT STARTS WITH:
- C:\Windows\System32\spool\DRIVERS\
- C:\Windows\System32\
- C:\Windows\SysWOW64\
重大度: 高