Why your cross-forest golden ticket authenticates but is not admin: SID filtering and the RC4 TGT_REVOKED trap

  • active-directory
  • kerberos
  • forest-trust
  • ticket-forgery
  • detection

Most offensive writing documents what works. This documents two things that do not, because they look like they should, they fail quietly, and the time they cost is spent convincing yourself the forge was malformed when the forge was fine. Learning why a thing fails is often worth more than another thing that works, because it draws the boundary of what is possible, and a boundary you understand you stop wasting time against. You hold Domain Admin in one forest, there is a bidirectional trust to a second, and the obvious move is to forge a ticket carrying the target forest's privileged SID through SID history. The ticket is accepted. You are not an administrator. Nothing is broken; a security boundary is doing its job. For the move that does cross a trust, see the over-privileged service-account chain; this is the map of the path you should stop retrying.

What you will learn

  • Why a golden ticket with an injected privileged SID authenticates but confers no privilege across a forest trust.
  • What SID filtering removes and the exact reason every built-in admin SID is on the removal list.
  • Why an RC4-forged ticket can fail with a misleading TGT_REVOKED on a patched DC, and what to forge with instead.
  • How to read both failures as evidence that a control is working rather than that your forge is broken.
  • The defensive posture that keeps both controls on.

Prerequisites and scope: you already hold the krbtgt key of a forest you own and a trust from the target forest to yours. Everything here is about what a trust boundary filters, not a bug to exploit, so the defensive takeaway is to keep the filtering on.

The mental model: a border that rewrites your paperwork

Crossing a forest trust is like crossing a national border with documents issued by your own country. The border guard (the trusting forest) will accept that you are who your passport says, that part works. But the guard also has a rule: any claim in your paperwork that asserts a rank in the destination country is crossed out at the border, because your country does not get to appoint officials in theirs. So you arrive, correctly identified, with every "I am a general here" stamp struck through. You are admitted as a visitor, not a general. SID filtering is that border rule, and the "I am a general" stamp is the injected Enterprise Admins SID.

Once you hold that picture, the confusing outcome stops being confusing: successful entry, zero authority, is exactly what the rule produces.

Forest-trust SID filtering strips the injected privileged SID A forged ticket carrying an Enterprise Admins SID crosses the forest trust. SID filtering removes any SID with a RID below 1000, so the ticket authenticates but the privileged SID is gone. Separately, an RC4-forged ticket is revoked by a patched DC while an AES-forged one is accepted. Forged ticket (CORP) user SID, RID 1104 Enterprise Admins, RID 519 Arrives at VENDOR user SID 1104, kept RID 519, removed SID filter: strips RID < 1000 authenticated, not admin Separate trap, same DC in your own domain: RC4-forged TGT gives KDC_ERR_TGT_REVOKED on a patched DC AES256-forged TGT is accepted, so forge with the AES key
The forged ticket authenticates, but SID filtering removes the injected Enterprise Admins SID (RID 519, below 1000), so you arrive with no privilege. Separately, PAC enforcement revokes an RC4-forged ticket on a patched DC; forge with the AES key instead. Both failures are controls working.

Failure 1: SID filtering strips the SID you injected

A golden ticket is a TGT you forge with a domain's krbtgt key. Into it you can place SID history: extra SIDs in the PAC that the KDC treats as additional group memberships. The cross-forest idea is to forge in the forest you own and inject a SID from the target forest, say Enterprise Admins, so you are treated as a member across the trust.

It does not work across a default forest trust, because of a boundary called SID filtering (also "quarantine"). When a ticket crosses, the trusting forest inspects the PAC's SIDs and discards any it should not honor from the other side. Two rules matter:

  • Only SIDs from the trusted forest survive. SIDs claiming to belong to a domain outside the trusted forest are removed, which stops a forest from asserting arbitrary memberships about the other.
  • SIDs with a RID below 1000 are stripped regardless. Every built-in and default privileged group lives below that line: Domain Admins is RID 512, Enterprise Admins 519, Administrators 544, and the built-in Administrator account is 500. The filter exists precisely so a trusted forest cannot inject a well-known privileged SID into the trusting one.

So the SID you most want to inject is exactly the SID the filter is built to remove. The ticket still authenticates, because the identity and the ordinary (RID at or above 1000) SIDs are fine; it simply arrives stripped of the privilege you tried to smuggle. A successful logon with no access is the most confusing possible result if you do not know the filter is there.

The narrow cases where cross-forest SID history does yield privilege depend on the filtering being weakened or off: a trust configured without SID filtering (older or deliberately relaxed), or an injected SID at RID 1000 or above that happens to be privileged in the target (a custom group granted admin, not a built-in). On a default modern trust, the built-in-group injection is dead.

Failure 2: the RC4 golden ticket that revokes itself

The second trap is unrelated to trusts and bites even against a DC in your own domain. Forge a golden ticket with only the account's RC4 key (the NT hash), present it to a patched modern DC, and you can get a hard KDC_ERR_TGT_REVOKED, as if the ticket were explicitly revoked. It was not. What changed is PAC signature enforcement.

The November 2022 updates (tracked as CVE-2022-37967, delivered in the KB5020805 family) added an extended PAC signature, and as enforcement rolled out, DCs began requiring it. A ticket forged the old RC4-only way does not carry a PAC the enforcing DC accepts, and the rejection surfaces as TGT_REVOKED rather than anything mentioning signatures, which is why it reads like a revocation. On the offensive side the fix is to forge with the account's AES256 key instead of its RC4/NT hash, so the ticket carries material the enforcing DC validates. If you dumped the directory you already have the AES keys next to the NT hashes; use them.

The defensive reading is the more important one: the error is a hardening control refusing a forged ticket. An RC4 golden ticket failing against a patched DC is the system telling you it is patched.

What this leaves you

  • Forging built-in privileged SIDs across a default forest trust is filtered out. Stop retrying it.
  • RC4-forged tickets fail on patched DCs; forge with AES if you forge at all.
  • The crossing that works is almost always a real credential the trust legitimately lets you request, such as a service ticket for a weak-password account in the target forest (cross-forest Kerberoasting), which is the first link of the over-privileged chain. The trust is not the hole; an unlocked account on the other side of it is.

Detection

  • Golden-ticket anomalies in general. Forged TGTs often carry lifetimes, encryption types, or PAC contents that violate policy. A request whose encryption type is RC4 in an AES-first domain, or a ticket lifetime beyond your maximum, is worth surfacing.
  • Cross-trust logons asserting privilege. Authentications arriving across a forest trust that then try to use a privileged group membership are exactly what SID filtering drops; where available, the filtered-SID events show the attempt.
  • Make the failure loud. TGT_REVOKED and filtered-SID outcomes are the controls working. Ensure DCs are patched to PAC enforcement and that forest-trust SID filtering has not been disabled, because a quiet success here is the dangerous case.

Prevention

  • Keep forest-trust SID filtering (quarantine) enabled. It is the default; the failure mode is an administrator disabling it to make a legacy cross-forest scenario work. Do not, or scope it tightly and temporarily.
  • Use selective authentication across trusts where the relationship does not need forest-wide access, so principals from the other forest reach only the resources you explicitly allow.
  • Patch DCs to full PAC-signature enforcement (the CVE-2022-37967 line) and keep AES as the preferred encryption, so RC4-forged tickets have nowhere to land.
  • Protect and rotate krbtgt. Golden tickets of any kind require the krbtgt key; on suspected leak, rotate it twice with the required interval, in both forests if the trust is involved.

Check yourself

  1. In the border analogy, what is accepted and what is crossed out, and which AD mechanism is the "crossing out"?
  2. Why is Enterprise Admins (RID 519) specifically unusable as an injected cross-forest SID, while a custom group might not be?
  3. Your RC4 golden ticket returns TGT_REVOKED against a DC in your own domain. What actually happened, and what do you change?
  4. Why should a defender be pleased, not alarmed, to see these two failures in a red-team report?

Answers:

  1. Your identity is accepted; any claim of privilege in the destination forest is crossed out. The crossing-out is forest-trust SID filtering (quarantine).
  2. Because RID 519 is below 1000, so the filter strips it regardless of source. A custom group with a RID at or above 1000 is not automatically stripped, so if it was granted admin it can survive, which is the narrow exception.
  3. PAC signature enforcement on the patched DC rejected a ticket forged without the required signature; the error is misleading. Forge with the account's AES256 key instead of the RC4/NT hash.
  4. Because both failures mean controls are on and working: SID filtering is enabled and the DCs are patched to PAC enforcement. The report is confirming the boundary held.

Use

Authorized and educational use only: your own lab, a directory you own, or an engagement with written permission. This is a defensive write-up of two security boundaries refusing a forged ticket, published so operators recognize the controls working rather than mistake them for a broken forge, and so defenders confirm the controls are actually on. It is not a runbook for use against systems you do not own.

References

Back to all techniques