
NTLM認証のリレーに関するLDAP保護をチェックします
LDAP サーバーの保護機能に関するドメインコントローラーのチェックと、NTLM 認証のリレーに関する問題を確認するためのツールです。エラーベースの列挙の詳細については、こちらを参照してください。LDAP の保護機能が不足している場合に何ができるかの詳細については、リファレンスのセクションを参照してください。
ドメインコントローラー上の LDAP に対して NTLM 認証をリレーしようとする際には、いくつかのサーバー側の保護機能があります。このツールが列挙しようとする 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 経由でルーティングしている場合や、ドメイン非参加ホストで実行している場合は、これが機能していることを確認してください。
このツールには、LDAPS(デフォルト)と BOTH の 2 つのメソッドがあります。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 のいずれかに設定できます。これは(この記事の執筆時点では)デフォルトでは必須ではありません。
ドメインコントローラー上の LDAP over SSL/TLS トラフィックを復号化して監視することで、チャネルバインディングが適用されている場合とされていない場合のバインド試行時のエラーの違いを特定できました。無効な資格情報を使用して LDAP over SSL/TLS へのバインドを試みると、予想どおりの resultCode 49 を受け取り、エラーメッセージの内容に data 52e が表示されます。ただし、チャネルバインディングが適用されており、LDAP クライアントがチャネルバインディングトークン(CBT)を計算して含めない場合、resultCode は依然として 49 ですが、エラーメッセージの内容には data 80090346 が含まれます。これは SEC_E_BAD_BINDINGS、つまりクライアントの提供されたサポートプロバイダーインターフェイス(SSPI)チャネルバインディングが正しくないことを意味します。

注: LDAP over SSL/TLS バインディング中の
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 チャレンジ/レスポンスプロセス中、特に Type 3 または AUTHENTICATE_MESSAGE 内の AV_PAIR 値として表示されます。チャネルバインディングをサポートするクライアントからのバインド試行がどのように見えるかを確認するために、ドメインコントローラー上の復号化された LDAPS トラフィックをもう一度見てみましょう。

この値を意図的に誤って計算すると、問題のポリシーが When supported に設定されている場合、同じ data 80090346 エラーが発生します。これにより、現在存在するこのポリシーのすべての可能な設定を、非認証の視点から区別できるようになります。この値を意図的に誤って計算する方法は重要です。チャレンジ/レスポンス中に値を手動で置き換えるだけでは、MIC が無効になるためです。
ドメインコントローラーでは、Domain Controller: LDAP server signing requirements というポリシーは、None、Require signing に設定されるか、または定義されていない場合があります。定義されていない場合、デフォルトでは署名は必須ではありません(この記事の執筆時点)。この保護が必須であることを示すエラーは、sicily NTLM または simple バインド試行が resultCode 8 で応答し、strongerAuthRequired を示す場合です。これは、LDAP バインド中の資格情報が検証された場合にのみ発生します。
この資料を文脈に沿って理解し、一般的な攻撃シナリオにどのように適合するかを理解するための貴重なリソースがいくつかあります。