ADTRUST-009: Orphaned Trust Detection

Plataforma
Active Directory
Categoría
AD Trust Relationships
Severidad
Medium
Pilar de Zero Trust
Identity (peso 1)
Fixtures de referencia
3
Cobertura de ramas
Observada: los fixtures prueban los veredictos que ejercitan
Procedencia
baseline

Qué comprueba

For every domain reachable in the forest, the check enumerates trustedDomain objects under CN=System,DC=<domain>,DC=<tld> using the LDAP filter (objectClass=trustedDomain) and reads the following attributes: - name / trustPartner / flatName (the partner DNS and NetBIOS names) - trustDirection (1 Inbound, 2 Outbound, 3 Bidirectional) - trustType (1 Downlevel, 2 Uplevel, 3 MIT, 4 DCE) - trustAttributes (NON_TRANSITIVE 0x1, QUARANTINED_DOMAIN 0x4, FOREST_TRANSITIVE 0x8, WITHIN_FOREST 0x20, USES_RC4_ENCRYPTION 0x80, TRUST_USES_AES_KEYS 0x100) - securityIdentifier (the trusted domain SID) - whenCreated, whenChanged, msDS-TrustForestTrustInfo For each trust the check then performs four liveness probes in order: 1. DNS resolution of trustPartner via Resolve-DnsName (A, AAAA, and SRV _ldap._tcp.dc._msdcs.<partner>). 2. SRV-discovered DC reachability over TCP 389 (LDAP) and TCP 88 (Kerberos), with a 3-second timeout. 3. nltest /sc_query:<partner> from the source DC to validate the Netlogon secure channel. 4. netdom trust <source> /domain:<partner> /verify (or Test-ComputerSecureChannel where Get-ADTrust permits) to validate the inter-realm trust key still authenticates. A trust is flagged as orphaned when (a) DNS resolution fails for both the partner name and any SRV-discovered DC, or (b) every discovered DC is unreachable on 389/88, or (c) the secure channel test returns ERROR_NO_LOGON_SERVERS / ERROR_NO_TRUST_SAM_ACCOUNT / 0x6FA. The check also records the age of the trust object (whenChanged) because trusts unmodified for years are disproportionately represented in the orphaned population.

Por qué importa

The trustedDomain object is not a stub. It carries the inter-realm trust key (the shared secret used to sign cross-realm TGTs) in trustAuthIncoming and trustAuthOutgoing, and it carries the partner domain SID in securityIdentifier. Three concrete risks follow from leaving an orphaned trust in place: - Namespace takeover. If the orphaned partner domain (for example acquired-co.local from a divested business unit) is no longer registered in your DNS infrastructure and no longer has live DCs, an attacker who can register that DNS namespace internally, or who can poison DNS via LLMNR/mDNS/NBT-NS, can stand up a rogue DC. Because your forest still trusts the SID range and accepts referrals signed with the trust key, the attacker can present forged TGTs to your trusting DCs. If the trust was bidirectional or if SID filtering was never enforced (common on pre-2003 external trusts and on legacy forest trusts where Quarantined was never set), the attacker can inject Enterprise Admin SIDs of your forest in ExtraSids and obtain Tier 0 access. - Trust-key exposure. The trust key is stored on every DC that holds a writable copy of the trust object and is retrievable by any principal with DCSync rights (Replicating Directory Changes) or local SYSTEM on a DC via mimikatz lsadump::trust /patch. A trust key from a forgotten partner is exactly as useful to an attacker as a current one: it produces valid inter-realm tickets that the trusting DC will honor. Stale trust keys are also less likely to be rotated, because nobody owns the trust on either side. - Audit and incident-response blind spot. During an investigation, an orphaned external trust to a long-dead namespace is the kind of artifact that breaks the analyst flow: the trust shows up in BloodHound and in Get-ADTrust output, no current employee can explain its purpose, no one knows whether the partner DC was ever decommissioned cleanly, and the team cannot quickly tell whether the trust was abused. The presence of the object alone forces work that would not exist if the trust had been removed when the relationship ended. The blast radius is forest-wide: any orphaned trust whose SID filtering is off (ADTRUST-002) or whose TGT delegation is on (ADTRUST-003) extends the entire forest authentication boundary into a namespace nobody is defending.

Ruta de ataque

Step 1: Discovery. From any authenticated user, the attacker enumerates trusts with Get-ADTrust -Filter * or nltest /domain_trusts /all_trusts. For each trust they attempt DNS resolution of the partner namespace and a TCP probe of port 389. Trusts where the partner cannot be resolved, or where every discovered DC is offline, are orphaned-trust candidates. Step 2: Namespace acquisition. The attacker chooses an attack consistent with their access level: (a) If the orphaned partner namespace is a public domain that was allowed to lapse (for example a divested subsidiary), the attacker registers the domain externally. Any DNS server in the target forest that resolves the partner name via public DNS will now resolve it to attacker infrastructure. (b) If the partner namespace is internal (.local, .corp, etc.), the attacker uses LLMNR / NBT-NS / mDNS poisoning (Responder, Inveigh) on a network segment that reaches a DC, or compromises an internal DNS zone to add A and SRV records pointing _ldap._tcp.dc._msdcs.<partner> at attacker-controlled hosts. Step 3: Rogue DC. The attacker stands up a minimal Kerberos KDC that speaks the inter-realm protocol. If the attacker also has the trust key (extracted via DCSync or lsadump::trust /patch from a current or backup DC of either side), they can sign valid inter-realm TGTs directly. If they do not, they attempt to negotiate a new trust handshake from the rogue side, which succeeds only against trusts configured with weak settings. Step 4: Cross-forest ticket forgery. With the trust key in hand, the attacker uses mimikatz kerberos::golden /domain:<orphaned-partner> /sid:<partner-sid> /rc4:<trust-key> /sids:<target-forest-EA-SID> /service:krbtgt /target:<target-forest> /ticket:cross.kirbi or the impacket ticketer.py equivalent to craft an inter-realm TGT containing an Enterprise Admin SID of the target forest in ExtraSids. The trusting DC, having no SID filtering on the orphaned trust, accepts the SID and issues service tickets accordingly. Step 5: Tier 0 reach. The attacker uses the forged ticket to DCSync against the target forest, dump krbtgt, and establish forest-wide persistence. The orphaned trust is the pivot; the rest of the chain is conventional krbtgt abuse. Step 6: Persistence by neglect. Because the orphaned trust has no owner on either side, the attack is unlikely to be noticed through routine trust review. The trust key has often never been rotated since trust creation, and no monitoring alerts on referrals from a namespace nobody recognizes.

Cómo lo evalúa Guerrilla

Guerrilla enumerates the forest with Get-ADForest, iterates every domain, and for each domain binds to CN=System,<domain DN> over LDAP to read trustedDomain objects with (objectClass=trustedDomain). For every trust object the collector reads trustPartner, flatName, trustDirection, trustType, trustAttributes, securityIdentifier, whenCreated, and whenChanged. The collector then runs the liveness probes against the source DC using PowerShell remoting or local execution: Resolve-DnsName -Name $trustPartner -Type A; Resolve-DnsName -Name "_ldap._tcp.dc._msdcs.$trustPartner" -Type SRV; Test-NetConnection -ComputerName $dc -Port 389 -InformationLevel Quiet; nltest /sc_query:$trustPartner; netdom trust $source /domain:$trustPartner /verify. The collector classifies each trust as Healthy, Stale (DNS resolves but secure channel fails), or Orphaned (DNS resolution and all DC probes fail). Orphaned and Stale rows are emitted with the trust attributes, the SID, the trust age in days, and the specific probe that failed (DNS, TCP, Netlogon, NetDom) so the operator can act on the right primitive. The check requires no elevated rights to read trustedDomain (Authenticated Users have read), but the secure channel and netdom probes require execution on a DC of the source domain or PowerShell remoting to one.

Valor recomendado

No orphaned or unresolvable trust relationships present

Remediación

Enumerate all trusts and attempt to validate each by resolving the trusted domain name and testing the trust with 'netdom trust /verify'. Remove orphaned trusts where the partner domain no longer exists or is unreachable using 'netdom trust /Remove' or Active Directory Domains and Trusts

Veredictos probados con fixtures

Cada veredicto de esta tabla está probado por un fixture de referencia en la suite de pruebas que valida el módulo. La tabla se deriva de la última ejecución en verde; no puede editarse a mano.

Escenarios de veredicto de ADTRUST-009
EscenarioVeredicto esperado
cleanPASS
known-badWARN
throttledNot Assessed

Mapeos a marcos de referencia

NIST SP 800-53
CM-6, AC-20
CIS AD Benchmark
3.4.1
MITRE ATT&CK
T1482