Enumeración de Active Directory
Con cualquier usuario del dominio (aunque no tenga privilegios) se puede leer casi todo el directorio por LDAP: usuarios, grupos, equipos, permisos y configuraciones peligrosas. Es lo primero que hago al tener credenciales.
Desde Kali
# Comprobar credenciales y ver a qué tengo acceso
nxc smb 10.10.10.0/24 -u usuario -p 'Password'
nxc smb dc01 -u usuario -p 'Password' --users --groups --shares
# Usuarios sin credenciales (sesión nula) o por fuerza bruta de RID
enum4linux -a dc01
impacket-lookupsid corp.local/invitado@dc01 -no-pass
# Usuarios válidos por Kerberos, sin contraseña
kerbrute userenum -d corp.local --dc dc01 usuarios.txt
# Recolectar todo para BloodHound
bloodhound-python -d corp.local -u usuario -p 'Password' -ns <IP-DC> -c AllDesde un beacon (CRTO)
En el CRTO se enumera con ldapsearch (un BOF que hace consultas LDAP desde memoria, sin lanzar procesos nuevos). Filtros que más uso:
| Busco | Filtro LDAP |
|---|---|
| Todos los usuarios | (samAccountType=805306368) |
| Todos los equipos | (samAccountType=805306369) |
| Grupos | (samAccountType=268435456) |
| Cuentas con SPN (Kerberoasting) | (&(samAccountType=805306368)(servicePrincipalName=*)) |
| Unconstrained delegation | (userAccountControl:1.2.840.113556.1.4.803:=524288) |
| Constrained delegation | (msDS-AllowedToDelegateTo=*) |
| Trusts | (objectClass=trustedDomain) |
beacon> ldapsearch (&(samAccountType=805306368)(servicePrincipalName=*)) --attributes samAccountName,servicePrincipalNameBloodHound con BOFHound
En lugar de lanzar SharpHound (muy detectado), se hacen consultas ldapsearch amplias, se descargan los logs de Cobalt Strike y BOFHound los convierte en JSON para BloodHound.
beacon> ldapsearch (|(objectClass=domain)(objectClass=organizationalUnit)(objectClass=groupPolicyContainer)) --attributes *,ntsecuritydescriptor
beacon> ldapsearch (|(samAccountType=805306368)(samAccountType=805306369)(samAccountType=268435456)) --attributes *,ntsecuritydescriptorbofhound -i logs/ # genera los JSON a partir de los logs del team serverEn BloodHound, consultas Cypher útiles:
MATCH (n:User) WHERE n.hasspn=true RETURN n // cuentas kerberoasteables
MATCH p=shortestPath((u:User {name:'USUARIO@CORP.LOCAL'})-[*1..]->(g:Group {name:'DOMAIN ADMINS@CORP.LOCAL'})) RETURN pGPOs: quién es admin dónde
Los administradores locales de cada equipo muchas veces se asignan por GPO ("Restricted Groups"). El archivo GptTmpl.inf de la GPO en SYSVOL dice qué grupo es admin; con eso se puede añadir a mano la relación AdminTo en BloodHound si no aparece.
Cómo se defiende
- Limitar qué pueden leer los usuarios normales en LDAP no es práctico; lo importante es no tener configuraciones peligrosas que encontrar.
- Detectar consultas LDAP masivas y herramientas como SharpHound.
- Revisar periódicamente con BloodHound las rutas hacia Domain Admins (lo mismo que haría un atacante).
