**TL;DR** : This article will go over basics, as well as explaining some powerful attacks to use against trusts. I will then introduce Trustify, a Powershell tool I wrote to weaponize the presented methodologies. As for my [Forensike, or Forensics for bad guys](https://blog.y00ga.lol/PUBLISH/Forensike%2C+or+Forensics+for+bad+guys) article, nothing revolutionary here, just some automated stuff and my 2 cents on the matter. Also, don't worry if you feel lost when reading or trying to memorize AD trusts-related stuff, it is actually a dense and complex set of rules, just take a deep breath ;)
![[trust_morpheus.png]]
# I : Trust Basics
To start somewhere, let's look at the official definition from Microsoft :
> To accept another authority's statements for the purposes of authentication and authorization, especially in the case of a relationship between two domains. If domain A trusts domain B, domain A accepts domain B's authentication and authorization statements for principals represented by security principal objects in domain B ; for example, the list of groups to which a particular user belongs
Feeling lost already ? Let's rephrase this. An Active Directory Trust is (simply) the AD object that defines the link between two domains. **This link enable classic AD & Windows authentication mechanisms between those two domains**
This definition implies that a trust enables **AUTHENTICATION**. If an object from a domain needs to access another object in the other domain, it needs to be granted the right to do so in addition to the trust itself (authentication does not mean authorization). A trust does not guarantee that every object from one domain can access every object in the other domain.
A trust is mainly charactized by : its **type**, its **direction**, **transitivity** and **whereas the domains it links belong to the same forest or not**
### Types
Here are some types of trusts you might encounter along some visual representation. Not all of them are covered here, because I simply didn't encountered them all during real engagements.
![[adtrusts_usecase1.png]]
Source : https://www.techtarget.com/searchwindowsserver/definition/Active-Directory
**Parent-Child Trust**
A Parent-Child trust relationship forms between **a parent domain and its child domain within the same forest**. This trust is established automatically whenever a new child domain is created. It ensures mutual trust where the parent domain trusts the child domain and vice versa.
There is a Parent-Child relationship between **example.com** (parent) and **accounts.example.com** (child)
**Tree-Root Trust**
Tree-Root trust links the **root domain of one tree** to the **root domain of another tree within the same forest**. This type of trust is automatically set up when a new tree is created in the forest, facilitating seamless resource access across the different trees.
Don't know what an AD tree is ? It can be simply put this way :
> A tree is a collection of one or more domains and domain trees in a contiguous namespace and is linked in a transitive trust hierarchy. When you have multiple domains in the same namespace (e.g., `techdirect.local,` `zone.techdirect.local`), they are considered to be in the same tree. The tree also supports multiple levels of domains.
Source : [TechDArchive](https://techdirectarchive.com/2020/04/11/what-is-active-directory-forest-trees-and-domain/)
There is a Tree-Root relationship between **example.com** and **sample.com**
**Cross-Link Trust**
Shortcut trusts are formed between two child domains that belong to different trees or parent domains within the same forest. These trusts help reduce the number of authentication hops required between distant domains, enhancing performance. They can be either one-way or two-way transitive.
A Cross-Link Trust could be set up between **sales.example.com** and **hr.sample.com** for example
**External Trust**
![[adtrusts_usecase2.png]]
Source : https://learn.microsoft.com/en-us/entra/identity/domain-services/concepts-forest-trust
External trusts are established between a domain in one forest and a domain in another, separate forest. This type of trust is particularly useful when users need to access resources in a different forest where no existing trust relationships are in place.
**Forest Trust**
A Forest trust is created between two forests, specifically between the root domains of each forest. This type of trust enables users in one forest to access resources in the other forest, fostering collaboration and resource sharing across forests.
There is a Forest Trust between **Forest 1** and **2** respective **root domains** and between **Forest 2** and **3** respective **root domains**
### Direction & transitivity
This section is easier to process. As an AD object of its own, a Trust has attributes, especially the [trustDirection](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/5026a939-44ba-47b2-99cf-386a9e674b04) one.
Let's break it down as such :
- 0: Disabled
- 1: Inbound (One-Way) = Current Domain is trusted by the other domain
- 2: Outbound (One-Way) = Current Domain trusts the other domain
- 3: Bi-Directional (Two-Way) = Both Domains trust each other
Please note that the absence of any flag for the attribute (**0x00000000** value) does not show an absence of trust, but rather explicits that the trust is **NOT enabled** (the trust relationship exists as the object exists but has been disabled).
Transitivity can be defined this way :
> When a trust relationship is transitive, the trust extends beyond the directly trusted and the trusting domain to any other transitively trusted domain. For example if both the **europe.hp.com** and **us.hp.com** domains trust the **hp.com** domain, then--thanks to trust transitivity--the **europe.hp.com** domain implicitly trusts the us.hp.com domain. Transitive trust reduces the number of trusts that are needed for authentication interoperability between different domains.
Source : https://www.itprotoday.com/windows-8/understanding-trust-transitivity
In this case, only 3 trusts are needed so that authentication can seamlessly work between all 4 domains.
That was a lot to read, I know 😕 Here is a meme :
![[explain_adtrusts.jpg]]
# II : Attacking AD trusts
This section is the most interesting. It presents some well-known trust-related attacks as well as some other interesting tricks I like to use during engagements
### Unconstrained Delegation
Having non-DC systems configured for unconstrained delegation is a well-known risk, this is why I am not going to describe it all over again (others [did it better](https://en.hackndo.com/constrained-unconstrained-delegation/#constrained--unconstrained-delegation)). However, if configuring a computer for unconstrained delegation other than a Domain Controller results in the domain being compromised in case this specific computer is compromised (via [authentication relay](https://www.thehacker.recipes/a-d/movement/kerberos/delegations/unconstrained) for example) , **it is also possible to use this technique to attack another domain**, if the configured trust allows it.
For example, if a computer in **Child Domain B** (Domain Controller or not) configured for Unconstrained Delegation is compromised, it is possible to directly retrieve a TGT for the machine account of **Parent Domain A's Domain Controller** via the same technique ! This attack is made possible because the Parent-Child Relationship between Domain A and B induces **an automatic bidirectional trust** (each domain trusts each other). As the trust allow **Domain A's DC** to perform an authentication to the **Domain B compromised system** (configured for UCD), it means that **an attacker with his hands on the UCD machine account can take over both the Child and Parent Domain with the same trick**. However, Domain A's DC has to be able to talk to Domain B's UCD computer
If Child Domain is compromised, the easiest way to go remains adding your own machine and configuring it for UCD so that no AV/EDR prevents you from reading incoming TGT (probably the least stealthy method)
Please note that this attack can work outside of a classic Parent-Child / Intra-Forest relationship. As long as you are attacking a two-way trust, you're good. Almost good ...
This looks like a powerful trick, doesn't it ? Well it will only work if the trust does not enforce Selective Authentication AND enforce TGT Delegation. But that will be another topic for another article ...
![[meme_UCD.jpg]]
### Trust Account
When a one-way (outbound) trust is set up from **Forest-B** to **Forest-A**, a trust account named ``B
` is created in Forest-A. This trust account, ``B
` , can have its cleartext credentials and Kerberos keys extracted from any Domain Controller in either forest with admin privileges.
As an AD object of its own, each trust is given a **Trust Key** when created. Those keys are specifically used when forging inter-realm TGTs.
This attack consists in taking over the Trust account by leveraging the trust Key. It is made possible by the fact that the **trust key actually represents the password of the trust account**. Indeed, when Forest-B compromise is achieved, an attacker can extract the associated Trust Key on Forest-B root domain DC and use it to authenticate as the ``B
` account in Forest-A.
However, the B$ account only has the privileges of a regular domain user within Forest-A. While not allowing a direct Forest compromise via trust, this trick gives an access to enumerate and performs attacks that require an account in your next target domain, even though the initial trust configuration only allows for authentication from A to B
![[Pasted image 20240808161858.png]]
Source : https://blog.improsec.com/tech-blog/sid-filter-as-security-boundary-between-domains-part-7-trust-account-attack-from-trusting-to-trusted
In this case, B trusts A in a **one-way unidirectional relationship** (direction of trust). It means that only A can authenticate towards B (direction of access) and not the other way around.
The trust attack allows accessing A from B (direction of attack) using the trust account.
### Foreign ACLs
This one is actually not rocket science. Multiple tools allow you to check if objects in the domain you just compromised can perform operations on another object elsewhere (Bloodhound, dacledit.py, ...). Realizing that a user in your compromised domain can add ownership, or edit a security group in another domain is the first step to taking over your next target.
### Inter-Domain Password reuse
This one works a lot in multidomain environments. Admins with multiple forests often tend to **reuse passwords between accounts that serve identical purposes for simplicity** (this is not a blame btw, we all make mistakes). Using the same password is easier when setting up a specific service multiple times in different domains as well as for administration, but this is also my go-to method to quickly retrieve accounts when attacking multiple domains.
Please note that this trick also works between domains that aren't even linked via trusts. I once got the case of two almost perfectly identical domains but in different forest without any trust, with identical users accounts, security groups, services and of course... passwords
### Child-Parent ADCS abuse
This one is my favorite ever :
The Configuration Naming Context (NC) refers to a namespace within Active Directory that holds configuration information from the environment, including details about the configuration of the different applications running in the domain. **The NC is always automatically replicated to all Domain Controllers within the Active Directory**.
Simply put, the NC in Active Directory holds configuration information about the entire forest, **including information about ADCS**.
The ``Certificate Templates`` used by the Certificate Authority are held in a dedicated container as ``pKICertificateTemplate`` objects, which can then be published to an ADCS CA (the ``Certificate Templates`` container is located in : Configuration > Services > Public Key Services, you can access it via ADSI)
The ``Enrollment Services`` container holds one ``pKIEnrollmentService`` object for each CA. These objects list the templates that have been published to the CA via their ``certificateTemplates`` property
In the end, the NC is automatically replicated across all domain controllers in the forest, meaning that **if these objects were to be modified from a child domain as the DC SYSTEM user in its local replica, they would be replicated on the Parent Domain DC via NC**. By gaining write access on these objects (this is done by giving Full Control Access to the Child Domain DC SYSTEM user on the `Public Key Services` container + applying this security setting to the `Public Key Services` object and all descendants), **we can create a custom Certificate Template that is vulnerable to ESC1 from the Child Domain DC and publish it to the ADCS CA server.**
Once published, it is possible to **request a certificate for any account of the Parent Domain**, as long as the CA serves both domain in the forest.
This technique might appear a bit more complex to perform, it is greatly explained [here](https://posts.specterops.io/from-da-to-ea-with-esc5-f9f045aa105c) and [there](https://www.pkisolutions.com/escalating-from-child-domains-admins-to-enterprise-admins-in-5-minutes-by-abusing-ad-cs-a-follow-up/)
![[always_you_three.jpg]]
### ExtraSID
Originally, the SIDhistory attribute serves a purpose in migrating AD accounts from one domain to another. Indeed, when migrating a user account, Active Directory does not really perform a "transfert" : it actually creates a new account in the second domain. The original user's SID will be added to the new user's SID history attribute, so that the user can still access resources in the original domain.
SID History Injection consists in adding a new SID (Security Identifier) in the SID History attribute of Active Directory user accounts when requesting a Kerberos Ticket. Usually the SID of a high privilege group, so **that the target user that will receive the ExtraSID value can authenticate with access rights and privileges associated with the injected SID**.
When SID history is enabled between two forests, attackers can potentially execute an extra-SIDs attack. However, SID filtering is usually enabled by default between forests, filtering out any SID with a Relative Identifier (RID) below 1000. This limitation doesn't stop attackers; they can exploit SIDs with RIDs of 1000 or higher, especially those associated with high-privileged groups in the domain. By leveraging these SIDs, attackers can attempt to elevate their privileges or gain unauthorized access within the target domain.
This technique can be performed when attacking a domain in another forest, but also when attacking from a child domain and trying to take over the parent domain. In this case, the SID of the Entreprise Administrators group can be abused if no filtering has been setup.
Please note that forging a TGT with an ExtraSID requires the current domain krbtgt account's hash (krbtgt encrypts every generated TGT in the domain with its own hash), which usually means that you have to compromise the current domain before attacking the other domain (or retrieve the krbtgt hash, which means domain compromise anyway because of Golden Tickets).
# III : Introducing Trustify
![[automate_everything_pwsh.png]]
Because I tend to grow tired of manually exploiting stuff, I decided to take some time to develop a PowerShell script that would automate the tricks described above : **Trustify**
With it, you can automatically perform the following attacks from a domain-joined Windows machine :
- Trust enumeration
- Matching SAMacccountnames between two domains
- Child to Parent Domain ADCS abuse
- ExtraSID attack
- Foreign ACL & Shadow Principals checks
- Trust Account Attack
- Unconstrained Delegation Attack
Again, nothing revolutionary here, as Trustify actually mainly acts as a wrapper around other tools and scripts, mostly around the PowerShell porting of Rubeus. You just have to import it, call the right function and give it the right arguments !
However, please note that unless you compromise a machine without any AV/EDR protection, you'll have to disable it first or **add your own machine to the domain** if you wanna use Trustify (which is fine because most of the attacks requires privileges to attack a trusted/trusting domain).
Code and usage details are available on this [repo](https://github.com/y00ga-sec/Trustify)
PS : I know that trusts can be exploited via GPO-on-site attack but I chose not to talk about it/integrate it to Trustify because... just don't play with GPO's in production during pentests, please
Thank you for reading !