Impacket Deep Dive Part 8: Forging Tickets with ticketer.py
Part 7 ended with secretsdump.py -just-dc-user krbtgt handing over the NT hash and AES keys belonging to the krbtgt account. This post is why that specific account, out of everything on the domain, is worth an entire post of its own: krbtgt’s key is what the domain controller uses to encrypt and sign every single TGT it ever issues. Whoever holds that key can produce a valid TGT for any account, with any group memberships, without asking the domain controller for anything at all.
Why krbtgt is different from every other account in this series
Every technique in Parts 3 through 7 involves talking to a domain controller — requesting a ticket, walking LDAP, replicating a hash. Forging a ticket with krbtgt’s key involves none of that. The TGT is constructed entirely offline, encrypted and signed with a key the attacker already has, and only touches a domain controller the moment it’s presented — at which point the DC decrypts it with the same key, finds a well-formed ticket signed correctly, and has no way to distinguish it from one it issued itself. This is the mechanism behind the two ticket-forging attacks ticketer.py implements.
Golden Tickets: forging a TGT directly
A Golden Ticket is a forged TGT for an arbitrary username, with arbitrary group memberships baked directly into its PAC (Privilege Attribute Certificate — the structure inside the ticket that actually carries authorization data like group SIDs). ticketer.py’s syntax, verified against v0.13.1:
usage: ticketer.py [-h] [-spn SPN] [-request] -domain DOMAIN -domain-sid
DOMAIN_SID [-aesKey hex key] [-nthash NTHASH]
[-keytab KEYTAB] [-groups GROUPS] [-user-id USER_ID]
[-extra-sid EXTRA_SID] [-extra-pac] [-old-pac]
[-duration DURATION] [-ts] [-debug] [-user USER]
[-password PASSWORD] [-hashes LMHASH:NTHASH]
[-dc-ip ip address] [-impersonate IMPERSONATE]
target
Creates a Kerberos golden/silver tickets based on user options
Two things it needs that this series has already produced: the domain’s SID (lookupsid.py, Part 2 — S-1-5-21-1957667318-3765306688-1889875232) and krbtgt’s NT hash (secretsdump.py, Part 7):
$ ticketer.py -nthash 8846f7eaee8fb117ad06bdd830b7586c \
-domain-sid S-1-5-21-1957667318-3765306688-1889875232 \
-domain CONTOSO.LOCAL \
-groups 512,518,519,520 \
fake.admin
Impacket v0.13.1 - Copyright Fortra, LLC and its affiliated companies
[*] Creating basic skeleton ticket and PAC Infos
[*] Customizing ticket for CONTOSO.LOCAL/fake.admin
[*] PAC_LOGON_INFO
[*] PAC_CLIENT_INFO_TYPE
[*] EncTicketPart
[*] EncAsRepPart
[*] Signing/Encrypting final ticket
[*] Saving ticket in fake.admin.ccache
fake.admin is not a real account in CONTOSO.LOCAL — that’s the point. -groups 512,518,519,520 bakes in Domain Admins, Schema Admins, Enterprise Admins, and Group Policy Creator Owners RIDs directly into the ticket’s PAC, and by default ticketer.py sets a ten-year validity window (-duration’s default). Loading the resulting fake.admin.ccache (export KRB5CCNAME=fake.admin.ccache) and authenticating anywhere in the domain with -k (Kerberos auth mode, used by every tool in this series) now presents as a fully privileged Domain Admin — for up to ten years, or until krbtgt’s password is rotated, whichever comes first, and no domain controller has any record of fake.admin’s account ever having authenticated normally, because there is no fake.admin account.
Silver Tickets: forging a single service ticket instead
Silver Tickets scope the forgery down: rather than needing krbtgt’s key (which requires DCSync-level access or a compromised DC to obtain), a Silver Ticket needs only the target service account’s own NT hash — exactly what Part 4’s Kerberoasting technique against svc-backup already produced. -spn is the flag that switches the tool from Golden to Silver mode:
$ ticketer.py -nthash <svc-backup-nthash> \
-domain-sid S-1-5-21-1957667318-3765306688-1889875232 \
-domain CONTOSO.LOCAL \
-spn MSSQLSvc/FS01.CONTOSO.LOCAL:1433 \
-groups 512 \
fake.dba
The forged ticket here is only valid for the one service named in -spn — in this case, the SQL Server on FS01 — because it’s encrypted with that service’s own key, not the domain-wide krbtgt key. That’s a materially smaller blast radius than a Golden Ticket, but it also means a Silver Ticket never touches the domain controller during authentication at all: the target service validates it locally using its own copy of the key, with no KDC round-trip. That makes it, in a specific and important sense, quieter than a Golden Ticket even though it’s less powerful — there’s no DC-side Kerberos event generated by its use, only whatever logging the target service itself produces.
Sapphire Tickets: the newest variant
-impersonate in the --help output above is worth naming even briefly: it implements what’s been termed a “Sapphire Ticket” — using S4U2Self plus U2U to request a real service ticket for a target user, extract its genuine PAC, and splice that legitimate PAC into the forged ticket rather than fabricating one from scratch. The practical effect is a forged ticket whose PAC matches exactly what the real domain controller would have produced for that user, closing a specific detection gap that some newer PAC-validation tooling relies on (comparing a presented PAC’s structure against what the DC would generate). It’s a reminder that this specific arms race — forged ticket vs. PAC validation vs. better forgery — is still actively moving, years after Golden Tickets were first disclosed.
Why krbtgt rotation is the actual fix, and why it’s usually done wrong
krbtgt’s password should be rotated twice, several hours apart — once is not enough, because the account keeps its previous password’s key valid for exactly this reason (to avoid breaking in-flight tickets during a routine rotation), which means a single rotation still leaves the old key valid for existing forged tickets until the second rotation invalidates it too. Microsoft’s own guidance, and every credible AD security hardening framework, calls for krbtgt rotation on a regular schedule (commonly annually, and always immediately after any suspected or confirmed compromise) using the double-rotation approach specifically. In practice, this is one of the most consistently skipped pieces of AD hygiene across real environments — CONTOSO.LOCAL’s own krbtgt, per this series’ lab notes back in Part 1, was “rotated once at domain creation, never since,” which is unfortunately closer to the median real-world state than the exception.
Defensive notes
Rotate krbtgt on a schedule, using the double-rotation method, not just after an incident. Reset-KrbtgtKeyInteractive.ps1 (Microsoft’s supported script for this) exists specifically because manual, careless rotation risks operational disruption if done wrong — automate it, schedule it, and treat “we’ve never rotated krbtgt” as a finding on its own, independent of whether a Golden Ticket has ever actually been used against the domain.
A ten-year forged ticket doesn’t survive a rotation, so rotation is the actual remediation for a suspected compromise. If DCSync or krbtgt exposure is ever suspected, the double rotation invalidates every previously forged Golden Ticket immediately, regardless of how long ago it was created or how privileged it claims to be — this is precisely why it’s the standard first remediation step after any confirmed domain-wide compromise.
Monitor for PAC anomalies and impossible account activity. A ticket presented for an account that shows no corresponding logon history, or whose PAC group memberships don’t match what LDAP shows for that account right now, is the core signature multiple detection tools (Microsoft Defender for Identity chief among them) use to catch Golden Ticket use — the forged ticket is internally consistent, but it’s inconsistent with the actual state of the directory it claims to represent.
Treat Silver Ticket risk as a reason to rotate service account passwords, not just krbtgt. Since a Silver Ticket only needs the target service’s own hash, every service account whose password was ever exposed (via Kerberoasting in Part 4, or via secretsdump.py in Part 7) remains a Silver Ticket risk against that specific service until its password is changed, independent of anything done to krbtgt.
Next: Part 9, where every technique from Parts 2 through 8 runs in sequence, in the order a real intrusion actually uses them — from j.reyes’s phished workstation to a forged Domain Admin ticket that outlives the assessment itself.