
Proof-of-concept educativo per PrintNightmare (CVE-2021-1675/34527) con payload simulato non funzionale, analisi del flusso di attacco, mappatura MITRE, indicazioni di rilevamento e passaggi di remediation.
Tipo: Proof of Concept — Simulato (Non Funzionale) CVE: CVE-2021-1675 + CVE-2021-34527 CVSS: 7.8 (LPE) / 8.8 (RCE) Alias: PrintNightmare Patchato: Giugno/Luglio 2021 — KB5004945 Aggiunto al CISA KEV: Luglio 2021
⚠️ Il payload di questo PoC è esplicitamente fittizio e non dannoso — solo 4 byte di header DCE/RPC seguiti dal nome della funzione in ASCII. Non esegue codice, non installa driver, non eleva privilegi. Uso esclusivo per scopi di apprendimento e sviluppo di rilevamenti.
Developed by: HKK$ cat ./vulnerability_summary.txtCVE-2021-1675, noto come PrintNightmare, è una vulnerabilità critica di Remote Code Execution e Local Privilege Escalation nel servizio Windows Print Spooler. La falla consente agli attaccanti di eseguire codice arbitrario con privilegi SYSTEM sfruttando la funzione RpcAddPrinterDriverEx(), usata per l'installazione remota di driver di stampante senza un'adeguata validazione del controllo di accesso.
Originariamente classificata come LPE (CVSS 7.8) e patchata nel Patch Tuesday di giugno 2021, Microsoft ha riclassificato la vulnerabilità come RCE (CVSS 8.8) il 21 giugno. Per evitare confusione, il vettore RCE ha ricevuto un nuovo identificatore, CVE-2021-34527 — entrambi sono comunemente chiamati PrintNightmare.
$ cat ./timeline.txtGiu 08, 2021 Microsoft pubblica la patch iniziale nel Patch Tuesday — CVE-2021-1675 (LPE, CVSS 7.8)
Giu 21, 2021 Microsoft riclassifica come RCE (CVSS 8.8)
Giu 29, 2021 I ricercatori pubblicano il PoC accidentalmente — credendo fosse la stessa vuln già patchata
Lug 01, 2021 CVE-2021-34527 assegnato per il vettore RCE — distinto dall'LPE originale
Lug 02, 2021 Microsoft rilascia patch d'emergenza out-of-band: KB5004945
Lug 2021 CISA aggiunge al Known Exploited Vulnerabilities Catalog
Sfruttamento attivo da parte di gruppi ransomware (Vice Society, Magniber, ecc.)
$ cat ./architecture.txt┌──────────────────────────────────────────────────────────────────────────┐
│ PRINTNIGHTMARE — ATTACK FLOW │
│ │
│ ATTACCANTE (utente autenticato) WINDOWS PRINT SPOOLER │
│ (spoolsv.exe) │
│ 1. Autenticarsi con qualsiasi ┌────────────────────────────┐│
│ account di dominio valido │ Gira come SYSTEM ││
│ │ │ Attivo di default su tutti││
│ 2. Connettersi via RPC al │ i Windows, inclusi i DC ││
│ named pipe \pipe\spoolss └──────────────┬─────────────┘│
│ │ │ │
│ 3. Chiamare RpcAddPrinterDriverEx() │ │
│ con path verso DLL dannosa ──────────────────────────►│ │
│ (UNC: \\attacker\share\evil.dll) │ │
│ ┌──────────────▼────────────┐ │
│ │ Print Spooler carica il │ │
│ │ driver (DLL) come SYSTEM │ │
│ │ senza verificare origine │ │
│ │ o integrità │ │
│ └──────────────┬────────────┘ │
│ │ │
│ ◄── RCE / LPE come SYSTEM ──────────────────────────────┘ │
│ Nuovo utente admin, reverse shell, │
│ distribuzione ransomware, ecc. │
│ │
│ ───────────────────────────────────────────────────────────────────── │
│ QUESTO POC: solo TCP connect + 25 byte → nessun RPC reale → nessun exploit
└──────────────────────────────────────────────────────────────────────────┘
$ cat ./design_decisions.mdfake_rpc_payload = b"\x05\x00\x0b\x03RpcAddPrinterDriverEx"
Questo payload ha 25 byte e dimostra due concetti simultaneamente:
Byte 0-3: Header DCE/RPC legittimo
| Byte | Valore | Significato |
|---|---|---|
\x05 | 5 | Versione del protocollo DCE/RPC (versione 5 — standard Windows) |
\x00 | 0 | Minor version 0 |
\x0b | 11 | PDU Type: BIND — primo passo della negoziazione RPC |
\x03 | 3 | Flags: `PFC_FIRST_FRAG(0x01) |
Byte 4-24: Nome della funzione in ASCII
RpcAddPrinterDriverEx — il nome della funzione vulnerabile, in testo semplice.
Perché questo payload non funziona come exploit reale?
Un BIND RPC legittimo richiederebbe, dopo l'header di 4 byte:
- max_xmit_frag (2 byte)
- max_recv_frag (2 byte)
- assoc_group_id (4 byte)
- num_ctx_items (1 byte)
- context_elem[] → Interface UUID del MS-RPRN:
{12345678-1234-ABCD-EF00-0123456789AB}
- transfer_syntaxes → NDR UUID
Senza questa struttura, Windows rifiuta il pacchetto immediatamente. Il payload è, effettivamente, solo un'asserzione di connettività — "riesco a raggiungere la porta 445 con questo payload fittizio?".
sock.connect((target_ip, 445))
Perché 445 e non 135 (RPC Endpoint Mapper)?
PrintNightmare usa il SMB named pipe \pipe\spoolss come trasporto — non l'RPC diretto. Il flusso reale è:
1. TCP connect → porta 445 (SMB)
2. SMB negotiate + session setup (autenticazione NTLM/Kerberos)
3. Tree connect → IPC$
4. Named pipe open → \pipe\spoolss
5. DCE/RPC BIND → interfaccia MS-RPRN
6. Chiamata RpcAddPrinterDriverEx() con NDR marshaling
Il PoC simula solo il passo 1 — la connessione TCP iniziale — senza implementare i passi 2-6.
sock.settimeout(5): il timeout di 5 secondi impedisce al PoC di bloccarsi su host che non rispondono. Utile per uno scanning rapido della disponibilità della porta.
| Aspetto | CVE-2021-1675 | CVE-2021-34527 |
|---|---|---|
| Vettore | Locale (LPE) | Remoto (RCE) |
| CVSS | 7.8 | 8.8 |
| Autenticazione | Account locale | Account di dominio autenticato |
| Patch | Giugno 2021 (Patch Tuesday) | Luglio 2021 (out-of-band KB5004945) |
| Funzione vulnerabile | RpcAddPrinterDriverEx | RpcAddPrinterDriverEx |
| Scenario | Escalation locale | RCE remoto via SMB named pipe |
La causa principale in entrambi è la stessa: la funzione RpcAddPrinterDriverEx() non riesce a validare l'origine dei file driver, non impone adeguate restrizioni di privilegio per l'installazione dei driver e non verifica l'autenticità o l'integrità delle DLL che vengono caricate.
$ cat ./mitre_mapping.ymltactic: Initial Access / Lateral Movement
- T1210 # Exploitation of Remote Services
# Chiamata RPC via \pipe\spoolss verso host remoto
# Richiede credenziale di dominio valida
tactic: Privilege Escalation
- T1068 # Exploitation for Privilege Escalation
# utente comune → SYSTEM via Print Spooler
# CVE-2021-1675 (LPE): processo locale eleva a SYSTEM