Exploitation de RBCD SPN-less
Exploitation de RBCD SPN-less
Cet article vise à décrire de manière simple les étapes ainsi que les risques de l’exploitation RBCD (Resource-Based Constrained Delegation) sans avoir le droit enrôler une machine au sein d’un domaine Active Directory. Dans un premier temps, nous allons rapidement revenir sur ce qu’est RBCD, puis nous aborderons la variante consistant à se passer de l’un des pré-requis de l’attaque classique.
Des articles très complets sur les délégations et RBCD existent déjà, l’article présent vise plutôt à décrire les mécanismes d’exploitation de RBCD en mode SPN-less.
1. Rappel sur RBCD
1.1 L’objectif
L’exploitation de RBCD permet d’usurper l’identité de n’importe quelle ressource du domaine auprès des services exécutés par un compte ciblé.
Attention ! On ne peut pas usurper les utilisateurs ayant l’attribut
CannotBeDelegated
définit àTrue
! Cette information peut s’obtenir sur Bloodhound, en consultant les attributs de l’utilisateur ciblé. Depuis Windows Server 2012 R2 et Windows 8.1, les utilisateurs membres du groupeProtected Users
sont protégés des attaques par délégation du fait que cet attribut soit par défaut définit àTrue
.
1.2 Les délégations
Afin de comprendre au mieux cette attaque, il est nécessaire de comprendre les différentes délégations Kerberos, des mécanismes mis en place afin de répondre à des scénarios courants dans un environnement Active Directory. Au sein d’un AD, les délégations permettent à un compte (utilisateur, machine, ou de service) d’agir en tant qu’un autre compte et d’effectuer des actions en son nom.
Différents types de délégations existent. Ces types se différencient par les règles qui autorisent les acteurs à les utiliser.
1.2.1 Unconstrained delegation
Comme son nom l’indique, cette délégation n’impose pas de contrainte. Elle est matérialisée par un attribut, TrustedForDelegation
, qui, quand définit à True
sur un compte, permet de se faire passer pour n’importe quel utilisateur auprès de n’importe quel service de n’importe quelle machine.
Par exemple, si cet attribut est positionné sur le service A, la délégation permettra à un service A d’accéder à un second service B en se faisant passer pour n’importe quel utilisateur (e.g. un administrateur du domaine) :
1.2.2 Constrained delegation
Pour cette délégation, la contrainte est positionnée auprès du premier service de la chaîne. Celui-ci se voit posséder une liste des services vers lesquels il va pouvoir déléguer l’authentification reçue. Cette liste est matérialisée par un attribut, msDS-AllowedToDelegateTo
. Il ne pourra donc plus se faire passer pour n’importe quel utilisateur vers le service de son choix, il devra se cantonner aux services présents dans cette liste.
Par exemple, si le service A possède dans sa liste le service B, cela lui permettra de demander un TGS pour le service B en utilisant le TGS fournis par l’utilisateur. Le TGS doit être transférable.
1.2.3 Resource-based Constrained Delegation
A l’inverse de la Constrainted Delegation
, la contrainte est cette fois positionnée sur le service final de la chaîne. Celui-ci se voit posséder une liste des services autorisés à venir s’authentifier chez lui, en se faisant passer pour n’importe quel utilisateur. Cette liste est matérialisée par un attribut, msDS-AllowedToActOnBehalfOfOtherIdentity
. Le service A ne pourra s’authentifier sur le service B que s’il apparait dans la liste du service B.
1.3 Utilisation des délégations
Afin d’utiliser ces différentes délégations, des “extensions” (on peut voir ça comme des requêtes au format spécifique) sont mises à disposition. Pour utiliser la contrainte “Resource-Based Constrained Delegation” (RBCD), nous allons nous intéresser à S4U2Self, S4U2Proxy ainsi qu’à la transition de protocole.
1.3.1 S4U2Self
C’est une demande de TGS (KRB_TGS_REQ) qu’un service effectue pour obtenir un TGS pour son propre service. Toutefois, la requête diffère de celle attendue car au lieu de demander un TGS à son nom, il va inscrire dans le champ PA-FOR-USER
le nom d’un utilisateur arbitrairement choisi. Le ticket délivré sera donc pour le service, en tant qu’un autre utilisateur.
Cette extension existe notamment pour le cas où un utilisateur s’authentifie au service en passant par un moyen différent de Kerberos (sans présenter de TGT, e.g. NTLM, authentification par formulaire) et qu’un ticket de service doit tout de même être émis.
1.3.2 S4U2Proxy
C’est une demande de TGS (KRB_TGS_REQ) qu’un service A effectue pour obtenir un TGS auprès d’un second service B. La particularité de cette requête est qu’un TGS est ajouté dans le champ additional-tickets
(le TGS pour le service A). La particularité pour utiliser S4U2Proxy
est que le TGS du service A doit être transférable, sinon, la requête échouera (c.f. 1.3.3).
1.3.3 Protocol Transition
Afin de remplir le pré-requis mentionné précédemment (le fait qu’un ticket de service soit transférable), la transition de protocole existe. Cette fonctionnalité est matérialisée par un attribut, TrustedToAuthForDelegation
, pouvant être positionné sur des ressources. Si par exemple le service A possède cet attribut, alors les tickets émis via le mécanisme S4U2Self
seront transférables. Cette fonctionnalité a été mise en place pour permettre à un service A d’obtenir un TGS transférable en tant que l’utilisateur s’étant authentifié au préalable via une méthode autre que Kerberos, par NTLM ou par formulaire par exemple et d’ensuite pouvoir invoquer S4U2Proxy
.
1.4 Attaque sur RBCD
1.4.1 Les prérequis “standards”
Afin de pouvoir exploiter RBCD comme indiqué précédemment et ainsi compromettre une machine (i.e. obtenir les privilèges maximaux sur cet objet), les éléments suivants doivent être réunis :
- Disposer des droits d’éditer le champ
msDS-AllowedToActOnBehalfOfOtherIdentity
de la cible. Cela peut se réaliser de plusieurs manières :- Obtention d’un compte utilisateur possédant les droits
GenericAll
(ou bienGenericWrite, WriteProperty, WriteDacl ou encore WriteAccountRestrictions
) sur un compte considéré par Kerberos comme étant un compte de service, un compte ordinateur ou bien un utilisateur standard (SPN-less RBCD) ; - Attaques par relai (coerce via WebDav).
- Obtention d’un compte utilisateur possédant les droits
- Disposer d’un “compte de service” (compte machine ou compte avec SPN). Cela peut se réaliser de plusieurs manières :
- Avoir la permission d’ajouter des machines dans le domaine. Ce droit est traduit par l’attribut
MachineAccountQuota
, par défaut, il est positionné à 10 ; - Obtention d’un compte ayant un SPN associé.
- Avoir la permission d’ajouter des machines dans le domaine. Ce droit est traduit par l’attribut
1.4.2 Les étapes d’exploitation
Dans le scénario suivant, 4 acteurs sont présents :
- L’attaquant ;
- Le service A : il est contrôlé totalement par l’attaquant. C’est un compte machine créé ou bien compte de service compromis ;
- Le service B : c’est le service ciblé par l’attaquant ;
- Marc_adm : un compte administrateur à privilèges importants, c’est le compte ciblé par l’attaquant ;
L’exploitation de la délégation Kerberos RBCD est composée des différents mécanismes présentées ci-dessus, chaînées dans l’ordre suivant :
- Obtention d’un TGS pour le service A en tant que
Marc_adm
. Cette étape se réalise grâce à S4U2Self. - Modification de l’attribut
msDS-AllowedToActOnBehalfOfOtherIdentity
de la cible service B en spécifiant le SID du service A. - Obtention d’un TGS en tant que
Marc_adm
sur le service B. Cette étape se réalise via S4U2Proxy. - Le TGS obtenu pour le service B en tant que
Marc_adm
peut maintenant être utilisé par l’attaquant.
2. RBCD SPN-less, une variante de RBCD
2.1 Rappels de vocabulaire
Voici quelques termes utiles à se rappeler pour la suite :
- User Long Term Secret Key (= hash NTLM) : Clé dérivée du mot de passe de l’utilisateur ;
- Service Long Term Secret Key (= hash NTLM) : Clé dérivée du mot de passe du compte de service ;
- Clé de session TGT : Information permettant d’authentifier un utilisateur sur une période de temps. Elle est obtenue suite à une requête de demande TGT (
KRB_AS_REQ
) ;
2.2 Différence de prérequis
Cette variante de l’attaque permet de se passer du pré-requis nécessitant la permission d’enrôler un compte machine dans le domaine (c’est-à-dire avec l’attribut MachineAccountQuota=0
). A la place, il faut disposer d’un compte utilisateur standard n’ayant pas forcément de SPN, qu’on est prêts à sacrifier.
2.3 Les effets de bord
Comme mentionné précédemment, cette technique peut rendre le compte utilisateur inutilisable. En effet, lors du processus, l’empreinte du mot de passe du compte présent dans l’attribut msDS-AllowedToActOnBehalfOfOtherIdentity
est renouvelée avec une donnée aléatoire n’ayant pas forcément de clair connu, empêchant ce compte d’être utilisé. De plus, la clé long terme utilisateur et l’empreinte NTLM sont désynchronisées, pouvant causer des perturbations sur le réseau.
Pour pouvoir réutiliser le compte, il faut changer son mot de passe immédiatement après la manipulation sinon, l’utilisateur risque de ne plus être fonctionnel.
2.4 Les acteurs
Afin de simplifier la compréhension des parties suivantes, les acteurs suivants seront présents.
Les utilisateurs :
Alice_client
: Utilisateur “client”, à l’origine de la demande de ticket de service ;Bob_serveur
: Utilisateur “serveur”, proposant un service, sans être un compte de service ;Marc_adm
: Utilisateur à privilèges usurpé par un attaquant ;
Les services :
Service A
: service classique ;Service B
: service de “fin de chaîne”, maîtrisant les ressources autorisées à le contacter ;
2.5 Les concepts
2.5.1 TGS
Habituellement, un TGS émis suite à une demande (KRB_TGS_REQ) est chiffré avec la Service Long Term Secret Key
, c’est à dire le secret du service.
2.5.2 U2U
Avant de rentrer dans les différentes étapes impliquées par cette variante, il faut présenter un type d’authentification qui sera utile : l’User-to-user (U2U). Cette authentification client-serveur est un protocole applicatif de Kerberos qui **permet aux utilisateurs d’héberger des applications de manière sécurisée sur leur propre poste (e.g. nfs, ftp, etc.). **
De cette manière, un utilisateur (agissant comme un client) peut demander un ticket de service géré par un utilisateur (agissant comme un serveur), et non à un service comme habituellement.
Il n’y a pas de service, donc pas de service long term secret key
dans cette configuration ! C’est la particularité de cette authentification, le TGS généré est chiffré non pas avec la service long term secret key
du service ciblé mais avec la clé de session du TGT fourni en complément dans la requête.
Une authentification U2U est similaire à une demande de TGS (KRB_TGS_REQ
), mais diffère sur certains points :
additional-tickets
: ce champ ajouté dans la requête contient le TGT de l’utilisateur “serveur”,Bob_serveur
;kdc-options
: ce champ contient le flagENC-TKT-IN-SKEY
indiquant que le ticket de session généré doit être chiffré avec la clé de session du TGT ajouté (via le champadditional-tickets
).- le
sname
(service name) faisant habituellement référence à un UPC (User Principal Name) ayant un SPN, peut faire référence à un UPC n’ayant pas de SPN (un utilisateur sans spn donc).
Une demande de TGS U2U contient donc 2 TGT dans la requête : celui de l’utilisateur client (Alice_client
) et celui de l’utilisateur serveur (Bob_serveur
). C’est la clé de session ce dernier qui sera utilisée pour chiffrer le TGS émis.
2.5.3 S4U2Self + U2U
L’authentification U2U peut être couplée avec une délégation S4U2Self afin d’obtenir pour un utilisateur client (Alice_client
), un ticket de service transférable, usurpant l’identité d’un autre utilisateur (Marc_adm
) auprès de lui même (Alice_client
), sans avoir de service. Alice_client
est alors en possession d’un ticket de service pour un utilisateur à privilèges (Marc_adm
), qu’elle pourra utiliser sur le service ciblé (service B
) pour demander un ticket de service pour ce service, grâce à la délégation Kerberos mise en place.
En se rapportant aux exemples précédents, Alice_client
et Bob_serveur
ne font donc plus qu’un, il y a donc dans ce scénario une seule User Long Term Secret Key
.
2.6 Les étapes d’exploitation
Dans le scénario suivant, 3 acteurs sont présents :
- L’attaquant : c’est le compte à l’origine de la demande de TGS pour le service B ;
- Le service B : c’est le service ciblé par l’attaquant ;
- Marc_adm : un compte administrateur à privilèges importants, c’est le compte ciblé par l’attaquant ;
Les étapes d’exploitation de RBCD SPN-less diffère un peu d’une exploitation de RBCD classique, bien que très similaire :
- Obtention d’un TGS transférable en tant que
Marc_adm
, pour le “service” de l’attaquant. Cette étape se réalise par un S4U2Self + U2U, différant de l’exploitation classique ; - Récupération de la clé de session du TGT envoyé en supplément lors de la requête S4U2Self + U2U. Etant donné qu’il n’y a qu’un acteur dans le S4U2Self + U2U, la clé de session récupérée est celle du TGT du demandeur de ticket, c’est-à-dire du compte de l’attaquant. Cette étape n’est pas nécessaire dans l’exploitation classique ;
- Modification du hash NTLM de l’attaquant à sacrifier en cette clé de session. Cette étape n’est pas nécessaire dans l’exploitation classique ;
- Obtention d’un TGS en tant qu’utilisateur à privilèges (
Marc_adm
) sur le service B. Cette étape se réalise via S4U2Proxy. Cette étape est la même que lors de l’exploitation classique.
2.7 Les explications des étapes
Pourquoi modifier le hash NTLM du compte utilisateur avec la clé de session du TGT de l’utilisateur ? Pour comprendre la réponse à cette question, il faut s’intéresser au fonctionnement du KDC lorsqu’il reçoit une requête S4U2Proxy :
Comme vu précédemment, un TGS est habituellement chiffré, puis déchiffré, par le KDC avec la Service Long Term Secret Key
lorsqu’un compte de service est dans le processus. La variante étudiée ne faisant pas rentrer de SPN dans la danse, le KDC va essayer de déchiffrer le TGS fourni dans la requête S4U2Proxy avec la User Long Term Secret Key
de l’utilisateur “serveur” (ici l’attaquant). Nous avons notre réponse : il faut donc que le hash NTLM de l’utilisateur sacrifié (le compte de l’attaquant) soit égal à la clé de session de son TGT afin que le KDC arrive à bien déchiffrer le TGS additionnel fourni dans la requête S4U2Proxy :
3. Les commandes
3.1 Pour l’exploitation de RBCD standard
L’exécution de cette attaque à distance à l’avantage qu’elle ne nécessite pas d’exécution de commandes sur un poste. Le désavantage est qu’elle nécessite des informations de connexion (mot de passe, empreinte HTLM, empreinte AES).
1
2
3
4
5
6
7
8
9
# Ajout d'un ordinateur dans le domaine afin d'avoir un service A qu'on contrôle
impacket-addcomputer <DOMAINE>/<USER>:<MDP> -computer-name "MYCOMPUTER$" -computer-pass "R4nD0mPass123!" -dc-ip <IP_DC>
# Ajout du SID de notre ordinateur dans msDs-AllowedToActOnBehalfOfOtherIdentity (liste) de la ressource cible
# Ici, "USER" est l'utilisateur disposant d'une ACL permettant d'éditer l'attribut msDs-AllowedToActOnBehalfOfOtherIdentity de la ressource ciblée
impacket-rbcd -delegate-from 'MYCOMPUTER$' -delegate-to "<NOM_MACHINE_CIBLE>$" -dc-ip <IP_DC> -action 'write' <DOMAINE>/<USER>:<MDP>
# Récupération du ticket permettant d'usurper l'identité d'un utilisateur privilégié
impacket-getST -spn 'CIFS/TARGET' -impersonate <USER_A_USURPER> -dc-ip <IP_DC> '<DOMAINE>/MYCOMPUTER$:R4nD0mPass123!'
3.2 Pour l’exploitation de RBCD SPN-less
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Récupération d'un TGT de l'utilisateur
getTGT.py -hashes :$(pypykatz crypto nt '<MDP_COMPTE_ATTAQUANT_SANS_SPN>') '<DOMAINE>'/'<COMPTE_ATTAQUANT_SANS_SPN>'
# Récupération de la clé TGT de l'utilisateur
describeTicket.py 'TGT.ccache' | grep 'Ticket Session Key'
# Changement du hash NTLM du compte contrôlé par l'attaquant avec la clé de session du TGT
smbpasswd.py -newhashes :TGTSessionKey 'domain'/'COMPTE_ATTAQUANT_SANS_SPN':'<MDP_COMPTE_ATTAQUANT_SANS_SPN>'@'DC'
# Ajout du SID du compte attaquant dans msDs-AllowedToActOnBehalfOfOtherIdentity (liste) de la ressource cible
# Ici, "USER" est l'utilisateur disposant d'une ACL permettant d'éditer l'attribut msDs-AllowedToActOnBehalfOfOtherIdentity de la ressource ciblée
impacket-rbcd -delegate-from '<COMPTE_ATTAQUANT_SANS_SPN>' -delegate-to "<NOM_MACHINE_CIBLE>$" -dc-ip <IP_DC> -action 'write' <DOMAINE>/<USER>:<MDP>
# Récupération d'un ticket de service en tant qu'administrator (S4U2Self + U2U) puis récupération d'un TGS pour le service ciblé (S4U2Self)
export KRB5CCNAME='TGT.ccache'
getST.py -u2u -impersonate "Administrator" -spn "host/<SERVICE_CIBLE>" -k -no-pass 'DOMAINE'/'COMPTE_ATTAQUANT_SANS_SPN'
4. Les sources
Merci à tout les articles suivants m’ayant permis de comprendre le fonctionnement de l’attaque.
- RFC sur U2U
- RFC Kerberos
- Article du blog hackndo sur RBCD
- Article du blog thehacker.recipes sur le RBCD en SPN-less
- Article expliquant le RBCD en SPN-less
- Article sur la protection des utilisateurs et groupes
- Article sur les délégations Kerberos
- Article expliquant U2U
- Article décrivant les requêtes Kerberos
- Article sur les délégations