Sooner or later, during the pentest, the task of compromising the entire forest arises - provided that there are any rights in one of the domains. At such moments, a lot of questions arise about trusts, their properties and the attacks themselves. Let's try to figure it all out.
Trust between domains is used to authenticate users of one domain on the controller of another domain. In other words, so that users from domain A can have access to the resources of domain B. The domain structure can be of two types:
- Domain trees
- domain forests.
When creating a tree of domains between domains, by default transitive trusts are established. All computers have common:
- global catalog
- namespace
- scheme.
Domain trees can be combined into forests. When creating a domain forest, transitive trusts are established, and all computers in the forest share the following:
The table below shows the types of trust between domains and their properties.
More clearly, types of trusts between domains are illustrated in the image below.
Transitivity
Transitivity is needed to define trust outside the two domains between which it was formed, and is used to expand trust relationships with other domains. If we add a child domain to a domain, a two-way trust relationship is established between the parent and child domains. These relations are transitive, i.e. if domain A trusts domain D and domain D trusts domain E, then domain A also trusts domain E.
Nontransitive trust can be used to deny trust with other domains.
Direction
A trust relationship path is a series of trust relationships between domains to which authentication requests must be received. In other words, before authenticating a user, trust between domains is determined. For users of domain A to access the resources of domain D, domain D must trust domain A.
The direction of trust is of two types:
One-way trust is a one-way authentication path that is created between two domains. In unidirectional trust between domain A and domain B, users in domain B have access to resources in domain A. However, users in domain A do not have access to resources in domain B. This type of trust is not transitive.
Bilateral trust is a combination of two unidirectional trust relationships. In bidirectional trust between domains A and B, their users have access to the resources of both domains. This type of trust is transitive.
The direction of trust is always the opposite of the direction of access. Microsoft's representative diagram below:
Links for more in-depth trust types:
Kerberos between trusted domains
Consider an example. Client is trying to access Server.
From points 1 to 3, standard actions occur when using the Kerberos protocol. - The password is converted to an NTLM hash, the timestamp is encrypted with a hash and sent to KDC as an authenticator in the TGT ticket request (AS-REQ). The domain controller (KDC) checks the user information and creates a TGT ticket.
- The TGT ticket is encrypted, signed and sent to the user (AS-REP). Only the Kerberos service (KRBTGT) can open and read data from a TGT ticket.
- A user submits a TGT ticket to a domain controller when requesting a TGS ticket (TGS-REQ). The domain controller opens a TGT ticket and checks the PAC checksum.
Changes begin from point 4: an inter-realm TGT ticket appears, the so-called referral ticket, which is encrypted / signed with an inter-realm key generated from a trusted password. A trusted password is set when trusting is established and is known to both domain controllers. Using the inter-realm TGT ticket, a domain 1 user can request a TGS ticket to access domain 2 resources.
NTLM between trusted domains
- The client sends a request for authentication directly to the resource itself located in another domain to which it wants to access.
- The server receives a request from the client and sends it a CHALLENGE_MESSAGE response, which contains a random sequence of 8 bytes. It is called the Server Challenge.
- The client, having received the Server Challenge sequence from the server, encrypts this sequence with its password, and then sends the server a response that contains 24 bytes.
- The server sends a request and response to the controller of its domain B.
- In the case of authentication between trusts, the following logic is performed:
- Checked Direction Trust Relationships.
- Client credentials are sent to domain A to authenticate.
- If there is no trust relationship, then Transitivity is checked with domain A.
- Transitivity Verification Between Domains
- If there is transitivity between domains, an authentication request is sent to the next domain in the trust path. This domain controller repeats the process, checking the user credentials against its database of security accounts.
- If there is no transitivity, a denied access message is returned to the client.
6-8. The answer with the decision to authenticate the client.
Attacks between trusts between domains
So, to conduct an attack, we need information about trusting relationships in our domain.
Listing Trusts
There are 3 main methods for listing trusts in a domain:
- through the Win32 API;
- via .NET methods;
- through LDAP.
Win32 API
Enumeration is performed by calling the function DsEnumerateDomainTrusts , which returns the structure DS_DOMAIN_TRUSTSA . Using this method, the SID and GUID of the target domain, flags and attributes characterizing the current trust in the domain are returned.
BloodHound collects information using the Win32 API method.
.Net
The GetCurrentDomain method from the [System.DirectoryServices.ActiveDirectory.Domain] namespace is used, which returns an instance of the System.DirectoryServices.ActiveDirectory.Domain class. This class implements the GetAllTrustRelationships method, which returns all trusts for the current domain.
([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).GetAllTrustRelationships()
Using this method is implemented in the Get-DomainTrust module in PowerView .
One of the advantages of this method is its simplicity. Information is easy to read and understand, but its volume is much smaller than when doing the enumeration by other methods.
LDAP
Domain trust information is stored in Active Directory as an objectClass of the trustedDomain class.
Usage example:
dsquery * -filter "(objectClass=trustedDomain)" -attr *
PowerView uses this method by default.
With information about domains and types of trust, you can go directly to the attack itself. Consider 2 options:
- We managed to compromise the domain, and we have domain administrator rights.
- We do not have domain administrator rights.
With administrator rights to one of the domains
Depending on the domain that was compromised, several attack vectors can be distinguished:
It is worth noting that for the successful implementation of all vectors, bilateral trust between domains is necessary.
1. Operation SID History
SID History was introduced to facilitate the migration of users from one domain to another. The attribute contains the previous SID objects. Each time an object moves from one domain to another, a new SID is created, which becomes an objectSID. The previous SID is added to the sIDHistory property.
Each forest has a group of Enterprise Admins users that exists only in the root domain and has local administrator rights on the domain controllers of all Child domains in the forest. This attack was first demonstrated by Sean Metcalf at BlackHat USA 2015 . The essence of the attack is that we are releasing a Golden ticket with the addition of an additional SID from the Enterprise Admins group. This is done by adding ExtraSids in the structure KERB_SID_AND_ATTRIBUTES , which is sent in the structure KERB_VALIDATION_INFO .
Attack Demo:
Impacket has a script that automates all this.
2. Golden Ticket + Enterprise Admin Group
Having administrator rights in the Root domain, we can create a Golden Ticket with the addition of a user to the Enterprise Admins group (519).
Kerberos::golden /domain:<domain> /sid:<domain_SID> /krbtgt:<ntlm_hash_krbtgt_user> /user:<user> /groups:500,501,513,512,520,518,519 /ptt
As described above, Enterprise Admin has local administrator rights to DC Child domains. Thus, we will be able to compromise all Child domains in the forest.
3. Operation of trust tickets
To access a resource using the Kerberos protocol, a TGS ticket is required, which is encrypted with the NTLM hash of the service account password. The domain controller stores hashes of user passwords only for its domain, so when a user from domain A needs access to a resource in domain B, an inter-realm key is used. This key is created on the basis of a trusted password, which is set when creating trust relationships between domains in the same forest. In the password database (NTDS.dit) on the domain controller, you can find users with the $ sign at the end. Their password is also used to create inter-realm keys. To create an inter-realm TGT ticket, we need a password hash of this account.
Kerberos::golden /user:<user> /domain:<domain> /sid:<sid_domain> /sids:<extra_sid_entrprice_admin_group_from _another_domain> /aes256:<aes256_trust_user_password> /service:krbtgt /target:<target_domain> /ptt
Attack Demo:
The attack is especially relevant when the IS service noticed a threat and changed the password krbtgt 2 times. In this case, we will be able to create golden tickets using a trusted password between domains.
4. Printer Bug
Windows Print System Remote Protocol (MS-RPRN) has the RpcRemoteFindFirstPrinterChangeNotification (Ex) method enabled by default, which allows you to force authentication on any computer running the Spooler service on the specified host using Kerberos or NTLM protocol. In the case of c NTLM, we can run NTLM-relay, or start to crack the computer password (never untick). In the case of Kerberos, a compromised machine with unlimited delegation is needed. Then we can pick up a TGT ticket and develop an attack.
Attack Demo:
The figure below shows the steps shown in the video.
We do not have domain administrator rights
A bit of theory. Carlos Garsia in his report gave an excellent table that illustrates the properties of different types of groups.
Of the features, it is worth considering that groups of type AD Domain Local and AD Global are replicated without group members to the global catalog, and groups of type AD Universal are replicated together with users.
Because of the way that groups are enumerated by the Global Catalog, the results of a back-link [ie memb search can vary, depending on whether you search the Global Catalog (port 3268) or the domain (port 389), the kind of groups the user belongs to (global groups vs. domain local groups).
In the event that we do not have domain administrator rights, we enumerate the objects. We are interested in:
- Users of another domain who have local administrator rights on machines in our domain.
- Users from other domains that are members of user domain groups. Groups containing users from another domain.
- Foreign ACL Principals.
1. Users of another domain who have local administrator rights on machines in our domain
Search for users from another domain who are local administrators on hosts in our domain in BloodHound:
MATCH (c:Computer) OPTIONAL MATCH p1 = (u1)-[:AdminTo]->(c) WHERE NOT u1.domain = c.domain WITH p1,c OPTIONAL MATCH p2 = (u2)-[:MemberOf*1..]->(:Group)-[:AdminTo]->(c) WHERE NOT u2.domain = c.domain RETURN p1,p2
Command in PowerView :
Get-NetLocalGroupMember <server>
2. Users from other domains, consisting of user domain groups. Groups containing users from another domain
As mentioned above, users who are members of only Universal groups are replicated to the global catalog. To demonstrate this feature, we will query groups in the global catalog containing at least one user and a direct ldap request to the domain controller.
Get-DomainGroup -Properties name, grouptype, member, DistinguishedName -LDAPFilter '(member=*)' -SearchBase "GC://jet.lab"
When executing a request to the global catalog, we see only one Universal Group group with type AD Universal from the domain one.jet.lab.
If we execute a direct LDAP query to the one.jet.lab domain, we will see other groups with the type AD Domain local and AD Global.
This is important to consider when enumerating users and groups.
Commands in PowerView :
Get-DomainForeignUser -Domain <Domain> Get-DomainForeignGroupMember -Domain <Domain>
3. Foreign ACL Principals
The ntSecurityDescriptor security descriptor (https://docs.microsoft.com/en-us/windows/win32/adschema/a-ntsecuritydescriptor) is accessible to all users from trusted domains and is replicated to the global catalog. Thus, we can query all DACLs for all objects in trusting domains and filter users from other domains.
Get-DomainObjectAcl -Domain jet.lab -ResolveGuids | ?{$_.SecurityIdentifier -like 'SID_Domain*'}
So, we managed to identify the user Mike from the forestc.lab domain, which had the rights to the Global Group in the jet.lab domain.
PS SID Filtering and Selective Authentication are used for protection between forests. An attack between forests with SID Filtering enabled dirkjan on his blog . Also on July 9, Microsoft released an update that disables TGT delegation between forests by default. Now everything, the story with unlimited delegation and compromise of one forest from another using the Kerberos protocol no longer works.