
Prueba de concepto educativa para PrintNightmare (CVE-2021-1675/34527) con payload simulado no funcional, análisis del flujo de ataque, mapeo MITRE, guía de detección y pasos de remediación.
Tipo: Prueba de Concepto — Simulada (No Funcional) CVE: CVE-2021-1675 + CVE-2021-34527 CVSS: 7.8 (LPE) / 8.8 (RCE) Alias: PrintNightmare Parcheado: Junio/Julio 2021 — KB5004945 Añadido al CISA KEV: Julio 2021
⚠️ El payload de este PoC es explícitamente ficticio y no malicioso — solo 4 bytes de cabecera DCE/RPC seguidos del nombre de la función en ASCII. No ejecuta código, no instala controladores, no eleva privilegios. Uso exclusivo con fines de aprendizaje y desarrollo de detecciones.
Developed by: HKK$ cat ./vulnerability_summary.txtCVE-2021-1675, conocido como PrintNightmare, es una vulnerabilidad crítica de Ejecución Remota de Código y Escalada Local de Privilegios en el servicio Windows Print Spooler. La falla permite a los atacantes ejecutar código arbitrario con privilegios SYSTEM explotando la función RpcAddPrinterDriverEx(), utilizada para la instalación remota de controladores de impresora sin una validación adecuada del control de acceso.
Originalmente clasificada como LPE (CVSS 7.8) y parcheada en el Patch Tuesday de junio de 2021, Microsoft reclasificó la vulnerabilidad como RCE (CVSS 8.8) el 21 de junio. Para evitar confusiones, el vector RCE recibió un nuevo identificador, CVE-2021-34527 — ambos son comúnmente llamados PrintNightmare.
$ cat ./timeline.txtJun 08, 2021 Microsoft publica el parche inicial en el Patch Tuesday — CVE-2021-1675 (LPE, CVSS 7.8)
Jun 21, 2021 Microsoft reclasifica como RCE (CVSS 8.8)
Jun 29, 2021 Investigadores publican el PoC accidentalmente — creyendo que era la misma vuln ya parcheada
Jul 01, 2021 Se asigna CVE-2021-34527 para el vector RCE — distinto del LPE original
Jul 02, 2021 Microsoft lanza parche de emergencia out-of-band: KB5004945
Jul 2021 CISA lo añade al Known Exploited Vulnerabilities Catalog
Explotación activa por grupos de ransomware (Vice Society, Magniber, etc.)
$ cat ./architecture.txt┌──────────────────────────────────────────────────────────────────────────┐
│ PRINTNIGHTMARE — ATTACK FLOW │
│ │
│ ATACANTE (usuario autenticado) WINDOWS PRINT SPOOLER │
│ (spoolsv.exe) │
│ 1. Autenticarse con cualquier ┌────────────────────────────┐ │
│ cuenta de dominio válida │ Se ejecuta como SYSTEM │ │
│ │ │ Activo por defecto en todos │ │
│ 2. Conectarse vía RPC al │ los Windows, incluidos DCs │ │
│ named pipe \pipe\spoolss └──────────────┬─────────────┘ │
│ │ │ │
│ 3. Llamar a RpcAddPrinterDriverEx() │ │
│ con ruta a DLL maliciosa ──────────────────────►│ │
│ (UNC: \\attacker\share\evil.dll) │ │
│ ┌────────────▼────────────┐ │
│ │ Print Spooler carga el │ │
│ │ controlador (DLL) como │ │
│ │ SYSTEM sin verificar │ │
│ │ origen o integridad │ │
│ └────────────┬────────────┘ │
│ │ │
│ ◄── RCE / LPE como SYSTEM ───────────────────────────┘ │
│ Nuevo usuario admin, reverse shell, │
│ despliegue de ransomware, etc. │
│ │
│ ───────────────────────────────────────────────────────────────────── │
│ ESTE POC: solo TCP connect + 25 bytes → sin RPC real → sin exploit │
└──────────────────────────────────────────────────────────────────────────┘
$ cat ./design_decisions.mdfake_rpc_payload = b"\x05\x00\x0b\x03RpcAddPrinterDriverEx"
Este payload tiene 25 bytes y demuestra dos conceptos simultáneamente:
Bytes 0-3: Cabecera DCE/RPC legítima
| Byte | Valor | Significado |
|---|---|---|
\x05 | 5 | Versión del protocolo DCE/RPC (versión 5 — estándar de Windows) |
\x00 | 0 | Versión menor 0 |
\x0b | 11 | Tipo de PDU: BIND — primer paso de la negociación RPC |
\x03 | 3 | Flags: `PFC_FIRST_FRAG(0x01) |
Bytes 4-24: Nombre de la función en ASCII
RpcAddPrinterDriverEx — el nombre de la función vulnerable, en texto plano.
¿Por qué este payload no funciona como exploit real?
Un BIND RPC legítimo requeriría, después del header de 4 bytes:
- max_xmit_frag (2 bytes)
- max_recv_frag (2 bytes)
- assoc_group_id (4 bytes)
- num_ctx_items (1 byte)
- context_elem[] → UUID de interfaz MS-RPRN:
{12345678-1234-ABCD-EF00-0123456789AB}
- transfer_syntaxes → UUID NDR
Sin esta estructura, Windows rechaza el paquete inmediatamente. El payload es, efectivamente, solo una aserción de conectividad — "¿puedo alcanzar el puerto 445 con este payload ficticio?".
sock.connect((target_ip, 445))
¿Por qué 445 y no 135 (RPC Endpoint Mapper)?
PrintNightmare usa el named pipe SMB \pipe\spoolss como transporte — no el RPC directo. El flujo real es:
1. TCP connect → puerto 445 (SMB)
2. SMB negotiate + session setup (autenticación NTLM/Kerberos)
3. Tree connect → IPC$
4. Named pipe open → \pipe\spoolss
5. DCE/RPC BIND → interfaz MS-RPRN
6. Llamada a RpcAddPrinterDriverEx() con NDR marshaling
El PoC simula solo el paso 1 — la conexión TCP inicial — sin implementar los pasos 2-6.
sock.settimeout(5): el timeout de 5 segundos evita que el PoC se quede bloqueado en hosts que no responden. Útil para escaneo rápido de disponibilidad del puerto.
| Aspecto | CVE-2021-1675 | CVE-2021-34527 |
|---|---|---|
| Vector | Local (LPE) | Remoto (RCE) |
| CVSS | 7.8 | 8.8 |
| Autenticación | Cuenta local | Cuenta de dominio autenticada |
| Parche | Junio 2021 (Patch Tuesday) | Julio 2021 (out-of-band KB5004945) |
| Función vulnerable | RpcAddPrinterDriverEx | RpcAddPrinterDriverEx |
| Escenario | Escalada local | RCE remoto vía SMB named pipe |
La causa raíz en ambos es la misma: la función RpcAddPrinterDriverEx() no valida el origen de los archivos de controlador, no impone restricciones de privilegio adecuadas para la instalación de controladores, y no verifica la autenticidad o integridad de las DLL que se están cargando.
$ cat ./mitre_mapping.ymltactic: Initial Access / Lateral Movement
- T1210 # Exploitation of Remote Services
# Llamada RPC vía \pipe\spoolss a host remoto
# Requiere credencial de dominio válida
tactic: Privilege Escalation
- T1068 # Exploitation for Privilege Escalation
# usuario común → SYSTEM vía Print Spooler
# CVE-2021-1675 (LPE): proceso local eleva a SYSTEM