
Preuve de concept pédagogique pour PrintNightmare (CVE-2021-1675/34527) avec charge utile simulée non fonctionnelle, analyse du flux d’attaque, correspondance MITRE, conseils de détection et étapes de remédiation.
Type: Proof of Concept — Simulated (Non-Functional) CVE: CVE-2021-1675 + CVE-2021-34527 CVSS: 7.8 (LPE) / 8.8 (RCE) Alias: PrintNightmare Patched: Juin/Juillet 2021 — KB5004945 Ajouté au CISA KEV: Juillet 2021
⚠️ Le payload de ce PoC est explicitement fictif et non-malveillant — seulement 4 octets d'en-tête DCE/RPC suivis du nom de la fonction en ASCII. Il n'exécute pas de code, n'installe pas de pilote, n'élève pas de privilèges. Usage exclusif à des fins d'apprentissage et de développement de détections.
Developed by: HKK$ cat ./vulnerability_summary.txtCVE-2021-1675, connu sous le nom de PrintNightmare, est une vulnérabilité critique d'exécution de code à distance et d'élévation de privilèges locaux dans le service Windows Print Spooler. La faille permet aux attaquants d'exécuter du code arbitraire avec les privilèges SYSTEM en exploitant la fonction RpcAddPrinterDriverEx(), utilisée pour l'installation à distance de pilotes d'imprimante sans validation adéquate du contrôle d'accès.
Initialement classée comme LPE (CVSS 7.8) et corrigée lors du Patch Tuesday de juin 2021, Microsoft a reclassé la vulnérabilité comme RCE (CVSS 8.8) le 21 juin. Pour éviter toute confusion, le vecteur RCE a reçu un nouvel identifiant, CVE-2021-34527 — les deux sont communément appelés PrintNightmare.
$ cat ./timeline.txtJun 08, 2021 Microsoft publie le correctif initial lors du Patch Tuesday — CVE-2021-1675 (LPE, CVSS 7.8)
Jun 21, 2021 Microsoft reclasse en RCE (CVSS 8.8)
Jun 29, 2021 Des chercheurs publient un PoC accidentellement — croyant qu'il s'agissait de la même vuln déjà corrigée
Jul 01, 2021 CVE-2021-34527 attribué pour le vecteur RCE — distinct du LPE d'origine
Jul 02, 2021 Microsoft publie un correctif d'urgence hors bande : KB5004945
Jul 2021 La CISA l'ajoute au Known Exploited Vulnerabilities Catalog
Exploitation active par des groupes de ransomware (Vice Society, Magniber, etc.)
$ cat ./architecture.txt┌──────────────────────────────────────────────────────────────────────────┐
│ PRINTNIGHTMARE — FLUX D'ATTAQUE │
│ │
│ ATTAQUANT (utilisateur authentifié) WINDOWS PRINT SPOOLER │
│ (spoolsv.exe) │
│ 1. S'authentifier avec n'importe quel ┌────────────────────────────┐ │
│ compte de domaine valide │ S'exécute en tant que │ │
│ │ │ SYSTEM │ │
│ 2. Se connecter via RPC au │ Actif par défaut sur tous │ │
│ named pipe \pipe\spoolss │ les Windows, y compris DCs│ │
│ │ └──────────────┬─────────────┘ │
│ 3. Appeler RpcAddPrinterDriverEx() │ │
│ avec le chemin vers une DLL malveillante ──────────►│ │
│ (UNC : \\attacker\share\evil.dll) │ │
│ ┌────────────▼────────────┐ │
│ │ Print Spooler charge le │ │
│ │ pilote (DLL) en tant que│ │
│ │ SYSTEM sans vérifier │ │
│ │ l'origine ou l'intégrité│ │
│ └────────────┬────────────┘ │
│ │ │
│ ◄── RCE / LPE en tant que SYSTEM ────────────────────┘ │
│ Nouvel utilisateur admin, reverse shell, │
│ déploiement de ransomware, etc. │
│ │
│ ───────────────────────────────────────────────────────────────────── │
│ CE POC : uniquement TCP connect + 25 octets → pas de RPC réel → pas │
│ d'exploit │
└──────────────────────────────────────────────────────────────────────────┘
$ cat ./design_decisions.mdfake_rpc_payload = b"\x05\x00\x0b\x03RpcAddPrinterDriverEx"
Ce payload fait 25 octets et démontre deux concepts simultanément :
Octets 0-3 : En-tête DCE/RPC légitime
| Octet | Valeur | Signification |
|---|---|---|
\x05 | 5 | Version du protocole DCE/RPC (version 5 — standard Windows) |
\x00 | 0 | Version mineure 0 |
\x0b | 11 | Type de PDU : BIND — première étape de la négociation RPC |
\x03 | 3 | Flags : `PFC_FIRST_FRAG(0x01) |
Octets 4-24 : Nom de la fonction en ASCII
RpcAddPrinterDriverEx — le nom de la fonction vulnérable, en texte clair.
Pourquoi ce payload ne fonctionne pas comme un véritable exploit ?
Un BIND RPC légitime exigerait, après l'en-tête de 4 octets :
- max_xmit_frag (2 octets)
- max_recv_frag (2 octets)
- assoc_group_id (4 octets)
- num_ctx_items (1 octet)
- context_elem[] → UUID d'interface MS-RPRN :
{12345678-1234-ABCD-EF00-0123456789AB}
- transfer_syntaxes → UUID NDR
Sans cette structure, Windows rejette immédiatement le paquet. Le payload n'est, en réalité, qu'une assertion de connectivité — « puis-je atteindre le port 445 avec ce payload fictif ? ».
sock.connect((target_ip, 445))
Pourquoi 445 et non 135 (RPC Endpoint Mapper) ?
PrintNightmare utilise le named pipe SMB \pipe\spoolss comme transport — pas le RPC direct. Le flux réel est :
1. TCP connect → port 445 (SMB)
2. SMB negotiate + session setup (authentification NTLM/Kerberos)
3. Tree connect → IPC$
4. Ouverture du named pipe → \pipe\spoolss
5. DCE/RPC BIND → interface MS-RPRN
6. Appel RpcAddPrinterDriverEx() avec marshaling NDR
Le PoC ne simule que l'étape 1 — la connexion TCP initiale — sans implémenter les étapes 2-6.
sock.settimeout(5) : un délai d'expiration de 5 secondes empêche le PoC de rester bloqué sur des hôtes qui ne répondent pas. Utile pour un scan rapide de la disponibilité du port.
| Aspect | CVE-2021-1675 | CVE-2021-34527 |
|---|---|---|
| Vecteur | Local (LPE) | Remote (RCE) |
| CVSS | 7.8 | 8.8 |
| Authentification | Compte local | Compte de domaine authentifié |
| Correctif | Juin 2021 (Patch Tuesday) | Juillet 2021 (hors bande KB5004945) |
| Fonction vulnérable | RpcAddPrinterDriverEx | RpcAddPrinterDriverEx |
| Scénario | Élévation locale | RCE à distance via named pipe SMB |
La cause racine des deux est la même : la fonction RpcAddPrinterDriverEx() ne parvient pas à valider l'origine des fichiers de pilote, n'impose pas de restrictions de privilèges adéquates pour l'installation de pilotes, et ne vérifie pas l'authenticité ou l'intégrité des DLL chargées.
$ cat ./mitre_mapping.ymltactic: Initial Access / Lateral Movement
- T1210 # Exploitation of Remote Services
# Appel RPC via \pipe\spoolss vers un hôte distant
# Nécessite des identifiants de domaine valides