AD-DEL-001: Unconstrained delegation outside domain controllers¶
high Delegation MITRE ATT&CK T1558, T1187 Reads: LDAP
Enabled accounts other than domain controllers are trusted for unconstrained delegation, so they keep the TGT of everyone who authenticates to them.
Also known as: unconstrained-delegation
Why it matters¶
An account with Trust this computer for delegation to any service (Kerberos only) receives a copy of the forwardable TGT of every user who authenticates to one of its services. The TGT sits in memory (LSASS) on that host, and whoever has local admin there can extract it and act as that user anywhere in the domain.
The attacker does not have to wait for an admin to log on:
- They take over the delegating host (or, for a user account, its password).
- They force a domain controller to authenticate to it, for example through the Print Spooler (AD-INF-009) or another RPC coercion method.
- The DC's own TGT arrives on the host; with it the attacker runs DCSync and has every hash in the domain.
AD-CHAIN-002 reports the coercion path as well: at high when the scan finds the Print Spooler running on a DC, otherwise at medium with coercion assumed possible.
How ad-doctor detects it¶
From the LDAP snapshot: every enabled account (computer, user or managed service
account) with the TRUSTED_FOR_DELEGATION bit (0x80000) in userAccountControl,
except registered domain controllers and RODCs (accounts with SERVER_TRUST_ACCOUNT,
0x2000, or PARTIAL_SECRETS_ACCOUNT, 0x4000000, and an nTDSDSA object when the snapshot
holds that data; see AD-INF-014), which need the flag. One finding lists the
accounts by sAMAccountName, for example APP01$.
Attributes and probes read
userAccountControl
Severity¶
Always high: one such host is enough. Coercing a domain controller to authenticate to it gives the attacker the DC's TGT, and with it the domain.
False positives and limits¶
- None in the usual sense. Some old applications were set up this way because it was the easiest option. They almost always work with constrained or resource-based delegation instead. If one truly cannot, isolate the host as tier 0 and record it in an accepted-risk file.
Fix¶
-
List the accounts (read-only):
-
Find out what the delegation is for. Usually it is a web front end that passes users through to a database or file share.
-
Replace it with constrained delegation to the specific SPNs the service needs, or with resource-based delegation configured on the back end, then remove the flag:
-
Protect privileged accounts so their TGTs are never delegated: set Account is sensitive and cannot be delegated (AD-PRIV-002) or put them in Protected Users (AD-PRIV-010).
-
Reduce coercion: disable the Print Spooler on DCs (AD-INF-009).
Verify¶
To accept the risk instead, add an entry to the file passed with --accept (see accepted risks):
[[accept]]
check = "AD-DEL-001"
objects = ["..."] # optional; without it the whole check is accepted
reason = "..."
expires = 2027-03-31
Related checks¶
References¶
Microsoft and vendors
Research
- Active Directory Security Risk #101: Kerberos Unconstrained Delegation (Sean Metcalf)
- Hunting in Active Directory: Unconstrained Delegation & Forests Trusts (SpecterOps)
- The Hacker Recipes: Unconstrained delegation
MITRE ATT&CK
Available since 0.1.0.