LDAP Relay Scan: check Domain Controllers for LDAP server protections
LDAP Relay Scan
A tool to check Domain Controllers for LDAP server protections regarding the relay of NTLM authentication. If you’re interested in the specifics of the error-based enumeration.
There are a couple server-side protections when attempting to relay NTLM authentication LDAP on Domain Controllers. The LDAP protections this tools attempts to enumerate include:
- LDAPS – channel binding
- LDAP – server signing requirements
The enforcement of channel binding for LDAP over SSL/TLS can be determined from an unauthenticated perspective. This is because the error associated with an LDAP client lacking the ability to conduct channel binding properly will occur before credentials are validated during the LDAP bind process.
However, to determine if the server-side protection of standard LDAP is enforced (server signing integrity requirements) the clients credential’s must first be validated during the LDAP bind. The potential error in identifying the enforcement of this protection is identified from an authenticated perspective.
Error-Based Enumeration Specifics
[LDAPS] Channel Binding Token Requirements
On a Domain Controller that has been patched since CVE-2017-8563, the capability to enforce LDAPS channel binding has existed. The specific policy is called Domain Controller: LDAP server channel binding token requirements and can be set to either Never, When supported, or Always. This is also not required by default (at the time of writing this).
Decrypting and monitoring LDAP over SSL/TLS traffic on a Domain Controller allowed for the identification of a difference in errors during bind attempts when channel binding is enforced versus when it’s not. When attempting a bind to LDAP over SSL/TLS using invalid credentials, you will receive the expected resultCode 49, and in the error message contents, you will see data 52e. However, when channel binding is enforced and the LDAP client does not calculate and include the Channel Binding Token (CBT), the resultCode will still be 49, but the error message contents will contain data 80090346 meaning SEC_E_BAD_BINDINGS or that the client’s Supplied Support Provider Interface (SSPI) channel bindings were incorrect.
Note: Mentions of the data 8009034 error during LDAP over SSL/TLS binding [1] [2] [3] [4] [5]
[LDAP] Server Signing Requirements
On a Domain Controller, the policy called Domain Controller: LDAP server signing requirements is set to None, Require signing, or it’s just not defined. When not defined, it defaults to not requiring signing (at the time of writing this). The error which identifies this protection as required is when a sicily NTLM or simple bind attempt responds with a resultCode of 8, signifying strongerAuthRequired. This will only occur if credentials during the LDAP bind are validated.
Install
git clone https://github.com/zyn3rgy/LdapRelayScan.git
Use
Note: DNS needs to resolve properly. If you are routing through SOCKS or running on a non-domain-joined host, ensure this is working.
The tool has two methods, LDAPS (the default), and BOTH. LDAPS only requires a domain controller IP address, because this check can be performed unauthenticated. The BOTH method will require a username and password or NT hash. The Active Directory domain is not required, it will be determined via anonymous LDAP bind.
Example
Note: Tested using python3.9 on client-side, targeting unpatched Windows Server 2016 and up-to-date Windows Server 2022
python3.9 LdapRelayScan.py -method BOTH -dc-ip 10.0.0.20 -u domainuser1
python3.9 LdapRelayScan.py -method BOTH -dc-ip 10.0.0.20 -u domainuser1 -p badpassword2
python3.9 LdapRelayScan.py -method BOTH -dc-ip 10.0.0.20 -u domainuser1 -nthash e6ee750a1feb2c7ee50d46819a6e4d25