Table des matières
Cette série de blogs a été rédigée par Megan Nilsen, consultante en sécurité, et Andrew Schwartz, responsable de la pratique TAC.
1 Introduction
Dans ce troisième et dernier volet, nous poursuivons notre exploration des attaques par objet et par attribut et de leur détection. Tout comme la première partie s’est concentrée sur l’étude des organigrammes fournis dans le document DACL des Hacker Recipes, et la partie 2 s’est concentrée sur les attributs modifiables à l’aide de PowerMadLa partie 3 se concentrera sur une collection d’attributs supplémentaires qui n’entrent pas dans le cadre des parties 1 et 2, mais que nous avons identifiés comme présentant un intérêt pour la construction de détections.
Bien que ce billet utilise différents outils d' »attaque », il convient de noter que l’outil est un moyen d’exécuter l’attaque, mais que nous nous concentrons davantage sur les techniques sous-jacentes d’attributs modifiables et sur les détections qui les entourent.
Tout comme les deux (2) premiers messages, voici quelques rappels :
- Nous partons du principe que l’adversaire a déjà un pied dans le domaine et qu’il a acquis l’accès nécessaire pour apporter des modifications aux objets dont nous allons parler.
- La post-exploitation n’est pas une priorité.
- Le renseignement appliqué à l’attribution de l’adversaire n’a pas été cartographié.
- Un sous-ensemble de la journalisation des événements Windows a été utilisé et tous les points de données télémétriques possibles dans cet ensemble de données n’ont pas été analysés.
2 Configuration de l’enregistrement
Comme indiqué dans la partie 1, à des fins de télémétrie, nous nous appuierons sur l’établissement d’une liste de contrôle d’accès au système (SACL) « Audit » pour chacun de ces attributs et les ID d’événements Windows suivants :
La configuration d’une SACL est une étape supplémentaire qui doit être réalisée même si les événements Windows énumérés ci-dessus sont en cours d’acquisition.
Veuillez vous reporter à la partie 1A pour savoir comment activer et configurer la configuration de la journalisation du SACL et comment activer ou ingérer les ID d’événements Windows ci-dessus.
3 Format du blog
En raison de la longueur de ce billet et du nombre d’attributs couverts, il est important de se rappeler quelques règles de formatage clés de la partie 1 au fur et à mesure que nous avançons dans ce billet.
- Chaque section contiendra les titres suivants :
- Nom de l’attribut (nom commun (CN) de l’attribut)
- Contexte
- Cette page donne un bref aperçu de ce qu’est l’attribut (LDAP-Display-Name) et les liens pertinents vers la documentation de Microsoft.
- Modifier l’attribut (Attaque)
- Couvre la façon dont l' »attaque » a été réalisée, y compris la configuration pertinente pour modifier l’attribut en question, les captures d’écran/commandes et les outils utilisés.
- Si un audit supplémentaire a été activé pour la mise en place de la détection, il sera probablement également couvert ici – ou, si la configuration supplémentaire était plus complexe, elle sera répartie dans une rubrique précédente ou suivante.
- Construction des détections
- Couvrira une variété de détections qui incluront une gamme de complexité
- Comme indiqué dans l’introduction, tous les points de données télémétriques possibles de cet ensemble de données n’ont pas été analysés. Cependant, nous avons fait de notre mieux pour couvrir les ID d’événements les plus accessibles et les plus importants pour l’élaboration de détections.
- Si nécessaire, nous fournirons un flux logique pour les détections qui impliquent une plus grande complexité ou des informations supplémentaires pour interpréter ce qui est affiché. Toutefois, la plupart des détections suivront un format similaire et ne seront pas expliquées plus en détail.
4 Attributs
4.1 AdminSDHolder
4.1.1 Contexte
Le AdminSDHolder L’objet AdminSDHolder agit comme un conteneur qui est rempli avec des autorisations par défaut. Ce conteneur est ensuite utilisé comme modèle pour les comptes protégés afin d’empêcher toute altération ou modification involontaire/non autorisée. Les utilisateurs protégés peuvent être définis par la politique du domaine, mais comprennent aussi généralement par défaut des utilisateurs appartenant à des groupes tels que Admins de domaine, Administrateurs, Admins d’entreprise et Admins de schéma.
Les attaquants qui ont obtenu des privilèges suffisants peuvent utiliser ce conteneur pour maintenir la persistance des listes de contrôle d’accès (ACL) à l’espace de stockage. AdminSDHolder sont réappliqués par défaut toutes les 60 minutes.
4.1.2 Modification de l’objet (attaque)
Add-DomainObjectAcl -TargetIdentity ‘CN=AdminSDHolder,CN=System,DC=BREAKFASTLAND,DC=local’ -PrincipalIdentity dacled.egg -Rights All -verbose
Chiffre 1 – Modifier l’objet
4.1.3 Construction de la détection
4.1.3.1 Détection avec les ID d’événements 5136 et 4662
index=main ((EventCode=5136 Class=container DN="CN=AdminSDHolder,CN=System,DC=BREAKFASTLAND,DC=LOCAL" LDAP_Display_Name=nTSecurityDescriptor) OR (index=main Account_Name!=*$ Object_Type="%{19195a5b-6da0-11d0-afd3-00c04fd930c9}" Object_Name="%{754fb287-55d2-4d68-b7fc-0332e1746740}" EventCode=4662 Access_Mask = 0x40000))
| eval Logon_ID=if(EventCode==4662,mvindex(Logon_ID,-1), mvindex(Logon_ID,-1))
| eval user=if(EventCode==4662,mvindex( Account_Name,-1), mvindex( Account_Name,-1))
| eval DACL=if(EventCode==5136,mvindex( Value,-1), mvindex( Value,-1))
| join type=outer Logon_ID
[ search index=main Account_Name!=*$ Object_Type="%{19195a5b-6da0-11d0-afd3-00c04fd930c9}" Object_Name="%{754fb287-55d2-4d68-b7fc-0332e1746740}" EventCode=4662 Access_Mask = 0x40000
| eval Props=Properties
| eval AccessMask=Access_Mask
| eval ObjectType=Object_Type
| eval ObjectName=Object_Name
|table Account_Name,Logon_ID,Props,AccessMask,ObjectType, ObjectName]
| table _time, Logon_ID, Account_Name, Props, AccessMask, ObjectType, ObjectName, DN, GUID, DACL, Class, Type, LDAP_Display_Name
|stats values by _time, Logon_ID, DACL
Chiffre 2 – Détection à l’aide d’identifiants d’événements multiples (1)
Chiffre 3 – Détection à l’aide d’identifiants d’événements multiples (2)
4.2 ms-DS-Supported-Encryption-Types
4.2.1 Contexte
Le msDS-SupportedEncryptionTypes définit les algorithmes de chiffrement que Kerberos est autorisé à utiliser pour le chiffrement des tickets Kerberos.
4.2.2 Modification de l’attribut (Attaque)
Avant de pouvoir modifier l’attribut msDS-SupportedEncryptionTypes nous devons d’abord comprendre comment les valeurs hexagonales et/ou décimales sont associées aux types de chiffrement. afin de pouvoir correctement modifier l’attribut avec notre cmdlet PowerMad.
Le graphique lié ici indique la valeur décimale, la valeur hexadécimale et les types de chiffrement pris en charge par le msDS-SupportedEncryptionTypes peut être défini comme suit. Pour nos besoins, nous allons utiliser la valeur décimale 24 (valeur hexagonale 0x18) pour modifier l’attribut afin d’activer la fonction support pour les types de cryptage AES 128 et AES 256. Cette valeur a été choisie arbitrairement.
Chiffre 4 – Modification de l’attribut
Chiffre 5 – Validation du changement de modification d’attribut
4.2.3 Construction de la détection
4.2.3.1 Détection avec les ID d’événements 5136, 4624 et 4662
index=main ((EventCode=5136 AND LDAP_Display_Name=msDS-SupportedEncryptionTypes) OR (EventCode=4624 AND Account_Name!="*$" AND Account_Name!="ANONYMOUS LOGON" AND Account_Name!="SYSTEM") OR (EventCode=4662 AND Access_Mask=0x20))
| eval Logon_ID=if(EventCode==4624,mvindex(Logon_ID,-1), mvindex(Logon_ID,-1))
| eval Mod_Account=if(EventCode==4624,mvindex(Account_Name,-1), mvindex(Account_Name,-1))
| eval Mod_Value=if(EventCode==5136,mvindex(Value,-1), mvindex(Value,-1))
| join type=outer Logon_ID
[ search (EventCode=5136) OR (EventCode=4624)
| stats count by Logon_ID, Account_Name, Source_Network_Address
| table Account_Name,Logon_ID, Source_Network_Address ]
| join type=outer Logon_ID
[ search index=main Account_Name!=*$ EventCode=4662 Access_Mask = 0x20
| eval Props=Properties
| eval AccessMask=Access_Mask
| eval ObjectType=Object_Type
| eval ObjectName=Object_Name
| rex field=Message "(?<Object_Properties>(?ms)(?<=)Properties:(.*?)(?=Additional\s+))"
|table Account_Name,Logon_ID,Props,AccessMask,ObjectType, ObjectName, Object_Properties]
| table _time, Mod_Account, Source_Network_Address , Class, DN, Logon_ID, Type, LDAP_Display_Name, Mod_Value, AccessMask, Props, Object_Properties
| where len(Class)>0
| stats values by _time, Mod_Value
Chiffre 6 – Détection à l’aide de plusieurs ID d’événements (1)
Chiffre 7 – Détection à l’aide de plusieurs ID d’événements (2)
4.3 ms-DS-Reveal-On-Demand-Group (en anglais)
Pour cette section, nous ferons référence au blog À la limite du niveau zéro : le cas curieux du RODC par Elad Shamir (@elad_shamir). L’article de blog susmentionné est un excellent outil pour comprendre les RODC et l’importance de l’interface d’administration. msds-RevealOnDemandGroup attribut.
Toutefois, pour résumer dans le cadre de ce billet, l’attribut msds-RevealOnDemandGroup L’attribut msds-RevealOnDemandGroup stocke les objets (c’est-à-dire les utilisateurs, les ordinateurs, les groupes) dont les mots de passe sont autorisés à être mis en cache sur un contrôleur de domaine en lecture seule (RODC).
4.3.1 Modifier les attributs (Attaque)
Set-ADObject -Identity ‘CN=BREAKFAST-DC-03,OU=Domain Controllers,DC=BREAKFASTLAND,DC=LOCAL’ -Add @{‘msDS-RevealOnDemandGroup’=@(‘CN=Allowed RDOC Password Replication Group,CN=Users,DC=BREAKFASTLAND,DN=LOCAL’, ‘CN=dacled.egg,CN=Users,DC=BREAKFASTLAND,DC=LOCAL’)} -Server 10.0.2.4
Figure 8 – Modification de l’attribut
Figure 9 – Validation de la modification de l’attribut
4.3.2 Construction de la détection
4.3.2.1 Détection à l’aide des ID d’événements 5136, 4624 et 4662
index=main ((EventCode=5136 AND LDAP_Display_Name=msDS-RevealOnDemandGroup) OR (EventCode=4624 AND Account_Name!="*$" AND Account_Name!="ANONYMOUS LOGON" AND Account_Name!="SYSTEM") OR (EventCode=4662 AND Access_Mask=0x20 AND {303d9f4a-1dd6-4b38-8fc5-33afe8c988ad}))
| eval Logon_ID=if(EventCode==4624,mvindex(Logon_ID,-1), mvindex(Logon_ID,-1))
| eval Mod_Account=if(EventCode==4624,mvindex(Account_Name,-1), mvindex(Account_Name,-1))
| join type=outer Logon_ID
[ search (EventCode=5136) OR (EventCode=4624)
| stats count by Logon_ID, Account_Name, Source_Network_Address
| table Account_Name,Logon_ID, Source_Network_Address ]
| join type=outer Logon_ID
[ search index=main Account_Name!=*$ EventCode=4662 Access_Mask = 0x20
| eval Props=Properties
| eval AccessMask=Access_Mask
| eval ObjectType=Object_Type
| eval ObjectName=Object_Name
| rex field=Message "(?<Object_Properties>(?ms)(?<=)Properties:(.*?)(?=Additional\s+))"
|table Account_Name,Logon_ID,Props,AccessMask,ObjectType, ObjectName, Object_Properties]
| table _time, Mod_Account, Source_Network_Address , Class, DN, Logon_ID, Type, LDAP_Display_Name, Value, AccessMask, Props, Object_Properties
| where len(Class)>0
| stats values by _time, Value, Logon_ID
Figure 10 – Détection avec les ID d’événements 5136, 4662 et 4624 (1)
Figure 11 – Détection avec les ID d’événements 5136, 4662 et 4624 (2)
4.4 GPC-Machine-Extension-Names
4.4.1 Contexte
Le gPCMachineExtensionName maintient une liste d’identifiants uniques globaux (GUID) pour lesquels les extensions côté client des objets de stratégie de groupe (GPO) et les snap-ins de la console de gestion Microsoft (MMC) sont requis par les paramètres de la stratégie machine.
En modifiant les GUIDS stockés dans l’attribut, un attaquant pourrait potentiellement utiliser GPO pour extraire un fichier d’un hôte contrôlé à distance et le télécharger vers un contrôleur de domaine.
4.4.2 Modification de l’attribut (Attaque)
Pour cette séquence d’attaque particulière, nous suivrons de très près le chemin de l’attaque tel qu’il est décrit dans ce billet de blog de TrustedSec.
Tout d’abord, nous allons effectuer une reconnaissance pour identifier le nom du GPO que nous allons modifier.
Figure 12 – Effectuer une reconnaissance
Comme vous pouvez le voir, le « DisplayName » de la GPO est AttackGPO, mais son nom, et la valeur dont nous aurons besoin pour effectuer nos modifications, est « {7ECE4273-CEEB-44BA-B777-C5FE3DBES 257} ».
$objs= Get-ADObject -SearchBase “CN=Policies,CN=System,DC=BREAKFASTLAND,DC=LOCAL” -LDAPFilter “(objectclass=*)” -Credential $creds -Server 10.0.2.4 -Properties displayName,gPCMachineExtensionNames
$dcgpos =$objs | ?{$_.displayName -like “Attack”}
$dcgpos
Figure 13 – Effectuer une reconnaissance
Avec un nom de GPO et un GUID en main, nous pouvons maintenant lancer notre attaque.
Note : Pour mener cette attaque correctement, il faut remplacer l’élément gPCMachineExtensionNames avec la chaîne [{GUID}{GUID}] ne fonctionnera évidemment pas correctement. Cependant, étant donné que nous ne nous intéressons qu’à la détection des modifications apportées à l’objet, et pas nécessairement à la conception d’une attaque fonctionnelle, cela suffit à générer les données de journalisation dont nous aurons besoin pour la détection au sein de notre SIEM. Pour exécuter correctement cette attaque, nous vous recommandons de lire les références liées à cette section (ou les liens courts ci-dessus), car elles font un travail fantastique en vous guidant à travers la séquence d’attaque désignée. Il est également important de noter quee GPO a été créé dans le but d’effectuer ces modifications, soyez prudent si vous exécutez l’attaque suivante dans un environnement de production.
$dcgomain = $dcgpos | ?{$_.Name -eq “{7ECE4273-CEEB-44BA-B777-C5FE3DBE5257}”}
$gpcme = “[{GUID}{GUID}]” + $dcgpomain.gPCMachineExtensionNames
Set-ADObject -Replace @{gPCMachineExtensionNames=$gpcme} -Server 10.0.2.4 -Credential $creds -Identity $dcgpomain.DistinguishedName
Get-ADObject -Credential $creds -Server 10.0.2.4 -Identity $dcgpomain.DistinguishedName -Properties displayName, gPCMachineExtensionNames
Figure 14 – Modification de la GPO
Et nous pouvons confirmer par Active Directory Service Interface Editor (ADSI) que la modification a été apportée au bon GPO :
Figure 15 – Validation des modifications
4.4.3 Construction de la détection
4.4.3.1 Détection avec les ID d’événements 5136 et 4624
index=main ((EventCode=5136 AND LDAP_Display_Name=gPCMachineExtensionNames) OR (EventCode=4624 AND Account_Name!="*$" AND Account_Name!="ANONYMOUS LOGON" AND Account_Name!="SYSTEM"))
| eval Logon_ID=if(EventCode==4624,mvindex(Logon_ID,-1), mvindex(Logon_ID,-1))
| eval Mod_Account=if(EventCode==4624,mvindex(Account_Name,-1), mvindex(Account_Name,-1))
| join type=outer Logon_ID
[ search (EventCode=5136) OR (EventCode=4624)
| stats count by Logon_ID, Account_Name, Workstation_Name
| table Account_Name,Logon_ID, Workstation_Name ]
| table _time, EventCode, Mod_Account, Workstation_Name , Class, DN, Logon_ID, Type, LDAP_Display_Name, Value
| where len(Class)>0
Figure 16 – Requête finale pour la modification de gPCMachineExtensionName (1)
Chiffre 17 – Requête finale pour la modification de gPCMachineExtensionName (2)
4.5 GPC-File-Sys-Path
4.5.1 Contexte
gpC-File-Sys-Path est un autre attribut basé sur les GPO qui, comme l’attribut gPCMachineExtensionNamepeut donner accès aux « droits clonés dans le dossier spécifique au GPO sur le système de fichiers où se trouve le SYSVOL associé » (Un atout dans la manche, p. 30) lorsqu’un utilisateur se voit accorder un accès en écriture pour un GPO.
Vous pouvez voir dans l’image ci-dessous que l’élément gPCFileSysPath renvoie à l’emplacement du Sysvol.
Figure 18 – gPCFileSysPath avant modification
4.5.2 Modification de l’attribut (Attaque)
En utilisant exactement le même chemin d’attaque que nous avons fait pour l’attaque gPCMachineExtension nous pouvons utiliser la reconnaissance déjà effectuée et créer simplement une nouvelle variable avec laquelle stocker notre changement. Ensuite, nous effectuons et confirmons la modification avec la même commande PowerShell, en ajustant la commande pour ajouter notre nouvelle variable.
$gpfsp = \\imposter.LOCAL\SysVol\imposter.LOCAL\Policies\{7ECE4273-CEEB-44BA-B777-C5FE3DBE5257} + $dcgpomain.gPCMachineExtensionNames
Set-ADObject -Replace @{gPCFileSysPath=$gpfsp} -Server 10.0.2.4
-Credential $creds -Identity $dcgpomain.DistinguishedName
Get-ADObject -Credential $creds -Server 10.0.2.4 -Identity $dcgpomain. DistinguishedName -Properties displayName, gPCFileSysPath
Figure 19 – Modification de l’attribut gPCFileSysPath
4.5.3 Construction de la détection
4.5.3.1 Détection avec les ID d’événements 5136 et 4624
index=main ((EventCode=5136 AND LDAP_Display_Name=gpcFileSysPath) OR (EventCode=4624 AND Account_Name!="*$" AND Account_Name!="ANONYMOUS LOGON" AND Account_Name!="SYSTEM"))
| eval Logon_ID=if(EventCode==4624,mvindex(Logon_ID,-1), mvindex(Logon_ID,-1))
| eval Mod_Account=if(EventCode==4624,mvindex(Account_Name,-1), mvindex(Account_Name,-1))
| join type=outer Logon_ID
[ search (EventCode=5136) OR (EventCode=4624)
| stats count by Logon_ID, Account_Name, Workstation_Name
| table Account_Name,Logon_ID, Workstation_Name ]
| table _time, EventCode, Mod_Account, Workstation_Name , Class, DN, Logon_ID, Type, LDAP_Display_Name, Value
| where len(Class)>0
Figure 20 – Détection finale de gPCFileSysPath (1)
Figure 21 – Détection finale de gPCFileSysPath (2)
4.6 NT-Security-Descriptor
4.6.1 Contexte
Le NTSecurityDescriptor stocke les données relatives à un objet, telles que la propriété et les autorisations, dans un attribut « Format de la chaîne du descripteur de sécurité. »
4.6.2 Activation de l’audit
Pour ces détections particulières, nous devrons activer l’audit à deux (2) endroits. Tout d’abord, vous devrez activer l’audit à partir de certsrvqui peut être ouvert via le gestionnaire de serveur sur votre contrôleur de domaine.
Chiffre 22 – Activation de l’audit de certsrv
Pour l’audit de l’accès aux objets, nous devons également naviguer vers nos modèles dans ADSI edit et activer l’audit pour le modèle de certificat dont nous souhaitons suivre les événements – dans ce cas, le modèle de certificat Utilisateur modèle.
Chiffre 23 – Activation de l’audit des objets
4.6.3 Modification de l’attribut (Attaque)
Pour cette attaque, nous utiliserons un modèle de certificat vulnérable à une attaque ESC4 en utilisant l’outil Certipy pour trouver et localiser tous les modèles de certificats disponibles sur le domaine. Pour plus d’informations sur les vulnérabilités et les exploits liés aux modèles de certificats, veuillez consulter le document Certipy GitHub.
certipy find -u [email protected] -p <yourpassword> -scheme ldap -dc-ip 10.0.2.4
Chiffre 24 – Recherche de modèles AD CS
Dans ce cas, nous pouvons rapidement identifier que le Utilisateur est vulnérable à l’ESC4.
Remarque : En règle générale, dans la nature, nous recherchons le groupe qui dispose des « autorisations dangereuses », à savoir les utilisateurs du domaine, les utilisateurs authentifiés ou les ordinateurs du domaine. Dans le cas présent, le seul groupe disposant des autorisations nécessaires pour rétrograder le modèle vulnérable à l’ESC4 est le groupe Domain Admins, ce qui est suffisant pour exécuter l’attaque visant à modifier l’attribut.
Chiffre 25 – Modèle vulnérable ESC4
Nous rétrogradons ensuite le modèle ESC4 pour qu’il soit vulnérable à ESC1 et sauvegardons l’ancienne configuration du modèle dans le dossier User.json.
certipy template -username [email protected] -p <yourpassword> -template ‘User’ -scheme ldap -save-old -dc-ip 10.0.2.4
Chiffre 26 – Déclassement de ESC4 en ESC1
Ensuite, nous demandons un certificat en utilisant le modèle ESC1. Dans ce cas, l’utilisateur demandeur est sous.chefun utilisateur non privilégié, qui demande le certificat au nom d’un compte d’administrateur de domaine, head.chef. Ceci est spécifié à l’aide de l’option UPN drapeau.
certipy req -username [email protected] -p <> -upn head.chef.breakfastland.local -template ‘User’ -ca BREAKFASTLAND-BREAKFAST-DC-01-CA -target BREAKFAST-DC-01.BREAKFASTLAND.LOCAL -dc-ip 10.0.2.4
Chiffre 27 – Demande de certificat
Et maintenant, nous restaurons le certificat, toujours en utilisant Certificat. Comme vous pouvez le voir dans la sortie, il modifie le fichier ntSecurityDescriptor . Selon le article de Rapid7 qui a inspiré cette section, c’est la spécification de l’UPN qui déclenche la procédure d’appel d’offres. ntSecurityDescriptor à mettre à jour.
certipy template -username [email protected] -p <yourpassword> -template -User -configuration User.json -dc-ip 10.0.2.4
Chiffre 28 – Restaurer le certificat/modifier l’attribut ntSecurityDescriptor
4.6.4 Construction des détections
4.6.4.1 Détection à l’aide de l’ID d’événement 4898
index=main EventCode=4898
| table time, EventCode, host, DomainController, Security_Descriptor, Message
Chiffre 29 – Détection du changement de ntSecurityDescriptor via l’ID d’événement 4898 (1)
Figure 30 – Détection du changement de ntSecurityDescriptor via l’ID d’événement 4898 (2)
4.6.4.2 Détection à l’aide des ID d’événements 5136, 4662 et 4624
index=main ((EventCode=5136 AND LDAP_Display_Name=ntSecurityDescriptor) OR (EventCode=4624 AND Account_Name!="*$" AND Account_Name!="ANONYMOUS LOGON" AND Account_Name!="SYSTEM") OR (EventCode=4662 AND Access_Mask=0x20))
| eval Logon_ID=if(EventCode==4624,mvindex(Logon_ID,-1), mvindex(Logon_ID,-1))
| eval Mod_Account=if(EventCode==4624,mvindex(Account_Name,-1), mvindex(Account_Name,-1))
| join type=outer Logon_ID
[ search (EventCode=5136) OR (EventCode=4624)
| stats count by Logon_ID, Account_Name, Source_Network_Address
| table Account_Name,Logon_ID, Source_Network_Address ]
| join type=outer Logon_ID
[ search index=main Account_Name!=*$ EventCode=4662 Access_Mask = 0x20
| eval Props=Properties
| eval AccessMask=Access_Mask
| eval ObjectType=Object_Type
| eval ObjectName=Object_Name
| rex field=Message "(?<Object_Properties>(?ms)(?<=)Properties:(.*?)(?=Additional\s+))"
|table Account_Name,Logon_ID,Props,AccessMask,ObjectType, ObjectName, Object_Properties]
| table time, ModAccount, Source_Network_Address , Class, DN, Logon_ID, Type, LDAP_Display_Name, Value, AccessMask, Props, Object_Properties
| where len(Class)>0
| stats values by time, Value, LogonID
Figure 31 – Détection avec les ID d’événements 5136, 4624 et 4662 (1)
Chiffre 32 – Détection avec les ID d’événements 5136, 4624 et 4662 (2)
4.6.4.3 Détection à l’aide des ID d’événements 5136, 4662 et 4624 – ICP
Dans ce cas, des modifications d’attributs supplémentaires sont initiées lors de l’exécution de cette attaque. Pour les prendre en compte, vous pouvez également créer une détection qui ajoute les attributs supplémentaires de l’infrastructure à clé publique (PKI) à la détection.
index=main ((EventCode=5136 AND (LDAP_Display_Name="*pki*" OR LDAP_Display_Name=ntSecurityDescriptor)) OR (EventCode=4624 AND Account_Name!="*$" AND Account_Name!="ANONYMOUS LOGON" AND Account_Name!="SYSTEM") OR (EventCode=4662 AND Access_Mask=0x20))
| eval Logon_ID=if(EventCode==4624,mvindex(Logon_ID,-1), mvindex(Logon_ID,-1))
| eval Mod_Account=if(EventCode==4624,mvindex(Account_Name,-1), mvindex(Account_Name,-1))
| join type=outer Logon_ID
[ search (EventCode=5136) OR (EventCode=4624)
| stats count by Logon_ID, Account_Name, Source_Network_Address
| table Account_Name,Logon_ID, Source_Network_Address ]
| join type=outer Logon_ID
[ search index=main Account_Name!=*$ EventCode=4662 Access_Mask = 0x20
| eval Props=Properties
| eval AccessMask=Access_Mask
| eval ObjectType=Object_Type
| eval ObjectName=Object_Name
| rex field=Message "(?<Object_Properties>(?ms)(?<=)Properties:(.*?)(?=Additional\s+))"
|table Account_Name,Logon_ID,Props,AccessMask,ObjectType, ObjectName, Object_Properties]
| table time, ModAccount, Source_Network_Address , Class, DN, Logon_ID, Type, LDAP_Display_Name, Value, AccessMask, Props, Object_Properties
| where len(Class)>0
| stats values by time, LDAPDisplay_Name, Value, Logon_ID
Chiffre 33 – Détections de changements d’objets supplémentaires (objets ICP) (1)
Chiffre 34 – Détections de changements d’objets supplémentaires (objets ICP) (2)
4.7 Certificat CA
4.7.1 Contexte
Le cACertificat L’attribut cACertificate stocke les certificats qui ont été enregistrés auprès d’autorités de certification (CA) de confiance.
4.7.2 Activation de l’audit/mauvaise configuration du domaine
Pour l’attaque suivante, nous suivrons l’article de blog réalisé par décodeur (@décodeur_it).
Note : Nous ne suivrons pas la séquence complète de l’attaque, car la modification de l’attribut est effectuée dans les premières étapes du post. Pour simuler le patch complet de l’attaque, veuillez suivre la marche à suivre complète ici.
Pour préparer notre attaque, nous devrons d’abord donner à un utilisateur standard « GenericAll » les privilèges sur le fichier NTAuthCertificates . Cette opération peut être effectuée via ADSI edit ou via PowerShell.
Dans ce cas, nous utilisons imposter.oatmeal comme notre compte mal configuré.
Chiffre 35 – Mauvaise configuration de l’objet
Ensuite, nous devrons construire l’entrée SACL pour l’objet NTAuthCertificates afin de recevoir les données d’enregistrement dans Splunk.
Chiffre 36 – Mise en place du SACL
Une fois cette étape franchie, nous pouvons lancer notre attaque pour modifier l’attribut.
4.7.3 Modification de l’attribut (Attaque)
Pour commencer, nous allons créer une fausse autorité de certification auto-signée.
Chiffre 37 – CA Création (1)
Comme indiqué dans le blog du décodeur, vous pouvez laisser tous les champs vides, à l’exception de « Common Name ».
Chiffre 38 -Création de la CCA (2)
Une fois la fausse autorité de certification créée, nous pouvons maintenant déplacer le fichier faux.crt créé sur un hôte Windows connecté à un domaine et utiliser le fichier binaire natif certutil pour mettre à jour le cACertificat avec la valeur de la clé publique supplémentaire.
Il est important de noter ici que nous sommes connectés à l’hôte Windows en tant que compte imposter.oatmeal, qui est le compte que nous avons « mal configuré » pour avoir des autorisations spéciales sur l’objet que nous modifions.
Chiffre 39 – Pousser la fausse autorité de certification vers le domaine
Et maintenant, si nous jetons un coup d’œil à notre cACertificat nous pouvons voir qu’il a été modifié avec la valeur du faux certificat.
Chiffre 40 – Attribut Post Modification
4.7.4 Construction des détections
4.7.4.1 Détection avec les ID d’événements 5136, 4662 et 4624
index=main ((EventCode=5136 AND LDAP_Display_Name=cACertificate) OR (EventCode=4624 AND Account_Name!="*$" AND Account_Name!="ANONYMOUS LOGON" AND Account_Name!="SYSTEM") OR (EventCode=4662 AND Access_Mask=0x20))
| eval Logon_ID=if(EventCode==4624,mvindex(Logon_ID,-1), mvindex(Logon_ID,-1))
| eval Mod_Account=if(EventCode==4624,mvindex(Account_Name,-1), mvindex(Account_Name,-1))
| eval Changed_Value=if(EventCode==5136,mvindex(Value,-1), mvindex(Value,-1))
| join type=outer Logon_ID
[ search (EventCode=5136) OR (EventCode=4624)
| stats count by Logon_ID, Account_Name, Source_Network_Address
| table Account_Name,Logon_ID, Source_Network_Address ]
| join type=outer Logon_ID
[ search index=main Account_Name!=*$ EventCode=4662 Access_Mask = 0x20
| eval Props=Properties
| eval AccessMask=Access_Mask
| eval ObjectType=Object_Type
| eval ObjectName=Object_Name
| rex field=Message "(?<Object_Properties>(?ms)(?<=)Properties:(.*?)(?=Additional\s+))"
|table Account_Name,Logon_ID,Props,AccessMask,ObjectType, ObjectName, Object_Properties]
| table _time, Mod_Account, Source_Network_Address , Class, DN, Logon_ID, Type, LDAP_Display_Name, Changed_Value, AccessMask, Props, Object_Properties
| where len(Class)>0
| stats values by _time, Changed_Value
Figure 41 – Détection avec les ID d’événements 5136, 4662 et 4624 (1)
Chiffre 42 – Détection avec les ID d’événements 5136, 4662 et 4624 (2)
4.8 Primary-Group-ID
4.8.1 Contexte
Le primaryGroupID contient l’identifiant du groupe primaire (RID) auquel appartient l’utilisateur ou l’objet informatique.
4.8.2 Modification de l’attribut (Attaque)
Les primaryGroupID est facile à modifier via l’interface graphique d’ADUC.
- Naviguez d’abord vers ADUC
- Ouvrez la fenêtre des propriétés de l’objet ordinateur/utilisateur que vous modifiez
- Naviguez jusqu’à l’onglet « Membre de
- Cliquez sur « Ajouter »
- Sélectionnez le nom du groupe dont vous souhaitez faire le groupe principal.
- Cliquez sur ok, puis sur appliquer.
- Sélectionnez le groupe nouvellement ajouté dans la case « Membre de ».
- Cliquez sur le bouton situé sous la case « Définir le groupe principal ».
- Cliquez sur Appliquer
Chiffre 43 – Changement de primaryGroupID de COFFEEPOT-PC
4.8.3 Construction des détections
Pour les détections suivantes, nous nous appuyons sur les ID d’événement 4738 et 4742 pour les objets utilisateur et ordinateur respectivement. Veillez à configurer votre SACL sur l’objet que vous essayez d’auditer pour vous assurer que les journaux seront générés et envoyés à votre SIEM.
4.8.3.1 Détection à l’aide de l’ID d’événement 4738 et de l’ID d’événement 4624
index=main AND (EventCode=4738 AND Primary_Group_ID!="-") OR EventCode=4624
| eval logon_id=if(EventCode=4624,mvindex(Logon_ID,1),mvindex(Logon_ID,0))
| eventstats values(EventCode) values(Source_Network_Address) by logon_id
| rename values(*) as *
| eval account_name=mvindex(Account_Name,1)
| sort _time
| where isnotnull(Primary_Group_ID)
| table _time, account_name, logon_id, Source_Network_Address, Primary_Group_ID
| stats values by logon_id, account_name
Chiffre 44 – Détection avec ID d’événement 4738 et 4624
4.8.3.2 Détection à l’aide de l’ID d’événement 4742 et de l’ID d’événement 4624
index=main AND (EventCode=4742 AND Primary_Group_ID!="-") OR EventCode=4624
| eval logon_id=if(EventCode=4624,mvindex(Logon_ID,1),mvindex(Logon_ID,0))
| eventstats values(EventCode) values(Source_Network_Address) by logon_id
| rename values(*) as *
| eval account_name=mvindex(Account_Name,1)
| sort _time
| where isnotnull(Primary_Group_ID)
| table _time, account_name, logon_id, Source_Network_Address, Primary_Group_ID
| stats values by logon_id, account_name
Chiffre 45 – Détection avec ID d’événement 4742 et 4624
4.8.3.3 Détections de primaryGroupID avec filtrage RID
Il est important de noter que les requêtes précédentes ne filtrent que les Primary Group ID qui ne sont pas égaux à « – » (null). Cependant, pour les organisations qui peuvent rencontrer des volumes élevés d’événements pour ces EventID, vous pouvez ajuster votre filtrage pour rechercher ou exclure certains groupes RID.
Par exemple, vous pourriez modifier la détection ci-dessous de manière à ce que seuls les comptes d’utilisateurs ayant leur primaryGroupID modifié en 512 (Domain Admins) repris par la requête :
index=main AND (EventCode=4738 AND Primary_Group_ID="512") OR EventCode=4624
| eval logon_id=if(EventCode=4624,mvindex(Logon_ID,1),mvindex(Logon_ID,0))
| eventstats values(EventCode) values(Source_Network_Address) by logon_id
| rename values(*) as *
| eval account_name=mvindex(Account_Name,1)
| sort _time
| where isnotnull(Primary_Group_ID)
| table _time, account_name, logon_id, Source_Network_Address, Primary_Group_ID
| stats values by logon_id, account_name
5 Conclusion
Nous espérons que cette série d’articles de blog permettra aux professionnels et aux organisations non seulement de prendre conscience de l’étendue de la surface d’attaque d’Active Directory (AD), mais aussi de savoir comment détecter les attaques courantes dont abusent les testeurs d’intrusion, les membres de l’équipe rouge et les acteurs de la menace.
Du point de vue de la sécurité, nous espérons également que l’un des principaux enseignements de ces articles est l’importance d’auditer fréquemment les autorisations de lecture ou d’écriture de ces attributs. Des outils tels que Bloodhound, PingCastleet PurpleKnight peut aider à identifier et à vérifier un grand nombre de ces problèmes faciles à résoudre.
Un autre point essentiel à retenir lorsque vous essayez de mettre en œuvre les détections fournies dans ces trois (3) articles de blog dans votre propre environnement SIEM est que toutes les détections ont été élaborées dans un environnement de laboratoire. Un environnement de production réel nécessitera des réglages supplémentaires pour éliminer les faux positifs.
Bien que la meilleure pratique et la préférence soient d’auditer tous les attributs, nous reconnaissons, comprenons et opérons avec les contraintes des coûts de licence SIEM. Nous avons voulu mettre en évidence et donner la priorité à certaines des attaques/abus les plus importants et n’avons donc pas couvert tous les attributs. Nous reconnaissons que nous n’avons pas utilisé de « renseignements » pour déterminer la priorité des attributs dans les différents articles. Nous avons plutôt commencé par les attributs les plus « communs » (en commençant par le tableau des abus de DACL de Hacker Recipes) que les équipes rouges et les testeurs de pénétration peuvent abuser, et nous avons terminé par les attributs les moins communs ou « oubliés ».
Comme les détections n’ont pas été construites pour toutes les attaques/abus possibles, les modèles de détection contenus dans ces articles peuvent être utilisés pour développer les cas d’utilisation décrits au fur et à mesure que de nouvelles attaques/techniques sont publiées, ou pour couvrir des objets que nous n’avons pas abordés.
Enfin, un grand merci à tous ceux qui ont participé à l’analyse, à la révision et aux suggestions afin de rendre cette série de blogs aussi bonne que possible :
Charlie Bromberg (@_nwodtuhs)
Jonathan Johnson (@jsecurity101)
Jim Sykora (@jimsycurity)
Kevin Clark (@GuhnooPlusLinux)
6 Références :
https://www.thehacker.recipes/ad/movement/dacl
https://stackoverflow.com/questions/73107061/convert-datetime-in-a-command
https://www.youtube.com/watch?v=ExO535CITXs
https://specterops.io/wp-content/uploads/sites/3/2022/06/an_ace_up_the_sleeve.pdf
Événements Windows :
https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4662
https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4624
https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-5145
https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4742
https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4738
AdminSDHolder :
msDS-SupportedEncryptionTypes :
https://learn.microsoft.com/en-us/windows/win32/adschema/a-msds-supportedencryptiontypes
msds-RevealOnDemandGroup :
https://eladshamir.com/2023/01/25/RODCs.html
gPCMachineExtensionNames :
https://www.trustedsec.com/blog/weaponizing-group-policy-objects-access/
https://labs.withsecure.com/tools/sharpgpoabuse
https://sdmsoftware.com/security-related/sending-gpos-down-the-wrong-track-redirecting-the-gpt/
gPC-File-Sys-Path :
https://specterops.io/wp-content/uploads/sites/3/2022/06/an_ace_up_the_sleeve.pdf
https://learn.microsoft.com/en-us/windows/win32/adschema/a-gpcfilesyspath
NTSecurityDescriptor :
https://learn.microsoft.com/en-us/windows/win32/adschema/a-ntsecuritydescriptor
https://github.com/ly4k/Certipy
https://www.rapid7.com/blog/post/2023/06/02/metasploit-weekly-wrap-up-12/
cACertificat :
https://decoder.cloud/2023/09/05/from-ntauthcertificates-to-silver-certificate/
https://learn.microsoft.com/en-us/windows/win32/adschema/a-cacertificate
https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/certutil
primaryGroupID :
https://learn.microsoft.com/en-us/windows/win32/adschema/a-primarygroupid
https://www.qomplx.com/blog/primary-group-id-attacks/
https://dovestones.com/changing-primary-group-primarygroupid/
https://www.semperis.com/blog/how-attackers-can-use-primary-group-membership-for-defense-evasion/