一个用于检查域控制器上关于 NTLM 认证中继的 LDAP 服务器保护措施的工具。如果你对基于错误的枚举的具体细节感兴趣,请参见下文。有关在发现缺少 LDAP 保护后可以采取哪些措施的详细信息,请参见参考部分。
在尝试将 NTLM 认证中继到域控制器的 LDAP 时,存在几个服务器端保护措施。本工具尝试枚举的 LDAP 保护措施包括:
对于基于 SSL/TLS 的 LDAP 的信道绑定执行情况,可以从未认证的角度进行判断。这是因为,无法正确执行信道绑定的 LDAP 客户端所关联的错误,会在 LDAP 绑定过程中凭据验证之前出现。
然而,要确定标准 LDAP 的服务器端保护(服务器签名完整性要求)是否被强制执行,必须首先在 LDAP 绑定期间验证客户端凭据。标识此保护是否强制执行的潜在错误需要从已认证的角度来识别。
建议在运行此项目时使用 Docker 或 Python 虚拟环境。
git clone https://github.com/zyn3rgy/LdapRelayScan.git && cd LdapRelayScandocker build -f docker/Dockerfile -t ldaprelayscan .docker run ldaprelayscan -hgit clone https://github.com/zyn3rgy/LdapRelayScan.git && cd LdapRelayScanvirtualenv envsource venv/bin/activatepython3 -m pip install -r requirements_exact.txtpython3 LdapRelayScan.py -h注意:DNS 必须正确解析。如果你通过 SOCKS 路由或在未加入域的机器上运行,请确保 DNS 正常工作。
该工具有两种方式:LDAPS(默认)和 BOTH。LDAPS 只需要域控制器 IP 地址,因为该检查可以在未认证的情况下执行。BOTH 方式需要用户名和密码或 NT 哈希。不需要提供 Active Directory 域,它会通过匿名 LDAP 绑定来确定。
arguments:
-h, --help show this help message and exit
-method method LDAPS or BOTH - LDAPS checks for channel binding, BOTH checks for LDAP signing and LDAP channel binding [authentication required]
-dc-ip DC_IP DNS Nameserver on network. Any DC's IPv4 address should work.
-u username Domain username value.
-timeout timeout The timeout for MSLDAP client connection.
-p password Domain username value.
-nthash nthash NT hash of password
python3 LdapRelayScan.py -method LDAPS -dc-ip 10.0.0.20
python3 LdapRelayScan.py -method BOTH -dc-ip 10.0.0.20 -u domainuser1
python3 LdapRelayScan.py -method BOTH -dc-ip 10.0.0.20 -u domainuser1 -p badpassword2
python3 LdapRelayScan.py -method BOTH -dc-ip 10.0.0.20 -u domainuser1 -nthash e6ee750a1feb2c7ee50d46819a6e4d25
注意:使用 SOCKS 的能力通过
PROXY_CONFIG环境变量传入。如果需要 SOCKS,还必须使用--network=host标志来正确路由流量。参见下面的示例。
docker run ldaprelayscan -h
docker run ldaprelayscan -dc-ip 10.0.0.20
docker run ldaprelayscan -dc-ip 10.0.0.20 -method BOTH -u domainuser1 -p secretpass
docker run -e PROXY_CONFIG='socks5 127.0.0.1 9050' --network=host ldaprelayscan -dc-ip 10.0.0.20 -method BOTH -u domainuser1 -p secretpass
在自 CVE-2017-8563 修复后打补丁的域控制器上,已经具备强制执行 LDAPS 信道绑定的能力。该特定策略称为Domain Controller: LDAP server channel binding token requirements,可设置为Never、When supported或Always。默认情况下也不是必需的(在编写本文时)。
对域控制器上基于 SSL/TLS 的 LDAP 流量进行解密和监控,使我们能够识别出在强制执行信道绑定与不强制执行信道绑定之间绑定尝试错误的差异。当使用无效凭据尝试绑定到基于 SSL/TLS 的 LDAP 时,你会收到预期的 resultCode 49,并且在错误消息内容中会看到data 52e。然而,当强制执行信道绑定,且 LDAP 客户端未计算并包含信道绑定令牌(CBT)时,resultCode 仍然为 49,但错误消息内容将包含data 80090346,这意味着SEC_E_BAD_BINDINGS或客户端的支持的提供程序接口(SSPI)信道绑定不正确。

注意:在基于 SSL/TLS 的 LDAP 绑定期间提及
data 8009034错误 [1] [2] [3] [4] [5]
这个特定错误使我们很容易处理当Domain Controller: LDAP server channel binding token requirements策略设置为Always时的情况。只需使用不支持信道绑定的客户端尝试基于 NTLM 的 LDAPS 绑定,并在响应错误中查找data 80090346。但如果是策略未设置为Always,而是设置为When supported时呢?答案是:使用基于 NTLM 的认证绑定到 LDAPS,并故意错误计算信道绑定信息。
首先,我们需要一个支持信道绑定的 LDAP 客户端。将使用 SkelSec's 在 msldap 中的实现来构建 PoC。信道绑定在 NTLM 质询/响应过程中作为 AV_PAIR 值出现,具体而言是在 Type 3 或 AUTHENTICATE_MESSAGE 中。再来看一下域控制器上的一些解密 LDAPS 流量,看看支持信道绑定的客户端的绑定尝试是什么样子的:

当相关策略设置为When supported时,故意错误计算该值将产生相同的data 80090346错误。这使我们能够从未认证的角度区分该策略目前存在的所有可能设置。如何故意错误计算该值很重要,因为仅仅在质询/响应过程中手动替换该值将使 MIC 失效。
在域控制器上,名为Domain Controller: LDAP server signing requirements的策略设置为None、Require signing,或者未定义。当未定义时,默认不要求签名(在编写本文时)。标识该保护被强制要求的错误是,当 sicily NTLM 或 simple 绑定尝试以 resultCode 8 响应时,表示strongerAuthRequired。这只有在 LDAP 绑定期间的凭据被验证后才会发生。
一些非常宝贵的资源,用于理解这些内容及其如何融入常见的攻击场景。