
NTLM 인증의 릴레이와 관련된 LDAP 보호 기능을 확인합니다.
DC(도메인 컨트롤러)에서 NTLM 인증 릴레이와 관련된 LDAP 서버 보호 기능이 적용되어 있는지 확인하는 도구입니다. 오류 기반 열거의 구체적인 내용에 관심이 있다면 아래를 참조하세요. LDAP 보호 기능이 없는 것을 확인했을 때 무엇을 할 수 있는지에 대한 자세한 내용은 참고 자료 섹션을 참조하세요.
DC(도메인 컨트롤러)에서 NTLM 인증을 LDAP으로 릴레이하려 할 때 적용되는 몇 가지 서버 측 보호 기능이 있습니다. 이 도구가 열거하려는 LDAP 보호 기능은 다음과 같습니다:
LDAP over SSL/TLS에 대한 채널 바인딩 적용 여부는 인증되지 않은 관점에서 확인할 수 있습니다. 그 이유는 채널 바인딩을 제대로 수행할 수 없는 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의 두 가지 방법이 있습니다. LDAPS는 인증 없이 수행할 수 있는 확인이므로 DC 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 이후 패치된 DC(도메인 컨트롤러)에서는 LDAPS 채널 바인딩을 적용하는 기능이 존재합니다. 해당 정책의 이름은 Domain Controller: LDAP server channel binding token requirements이며 Never, When supported, 또는 Always로 설정할 수 있습니다. 또한 (이 글을 작성하는 시점 기준으로) 기본적으로 요구되지는 않습니다.
DC에서 LDAP over SSL/TLS 트래픽을 복호화하고 모니터링하면 채널 바인딩이 적용될 때와 그렇지 않을 때 바인드 시도 중 발생하는 오류의 차이를 식별할 수 있었습니다. 잘못된 자격 증명을 사용하여 LDAP over SSL/TLS에 바인드를 시도하면 예상되는 resultCode 49를 받게 되며, 오류 메시지 내용에는 data 52e가 표시됩니다. 그러나 채널 바인딩이 적용되어 있고 LDAP 클라이언트가 CBT(Channel Binding Token)를 계산하고 포함하지 않으면 resultCode는 여전히 49이지만 오류 메시지 내용에는 data 80090346이 포함되며, 이는 SEC_E_BAD_BINDINGS 또는 클라이언트가 제공한 SSPI(Support Provider Interface) 채널 바인딩이 올바르지 않음을 의미합니다.

참고: 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 challenge/response 과정 중, 특히 Type 3 또는 AUTHENTICATE_MESSAGE 내에서 AV_PAIR 값으로 나타납니다. DC에서 복호화된 LDAPS 트래픽을 다시 한 번 살펴보면, 채널 바인딩을 지원하는 클라이언트의 바인드 시도가 어떻게 보이는지 확인할 수 있습니다:

해당 정책이 When supported로 설정된 경우, 이 값을 의도적으로 잘못 계산하면 동일한 data 80090346 오류가 발생합니다. 이를 통해 현재 존재하는 이 정책의 모든 가능한 설정을 인증되지 않은 관점에서 구분할 수 있습니다. 이 값이 의도적으로 어떻게 잘못 계산되는지가 중요한데, 단순히 challenge/response 중 값을 수동으로 교체하면 MIC가 무효화되기 때문입니다.
DC(도메인 컨트롤러)에서 Domain Controller: LDAP server signing requirements 정책은 None, Require signing으로 설정되거나 정의되지 않을 수 있습니다. 정의되지 않은 경우 기본값은 서명을 요구하지 않는 것입니다(이 글을 작성하는 시점 기준). 이 보호 기능이 요구됨을 식별하는 오류는 sicily NTLM 또는 simple 바인드 시도가 resultCode 8로 응답하여 strongerAuthRequired를 나타낼 때 발생합니다. 이는 LDAP 바인드 중 자격 증명이 검증된 경우에만 발생합니다.
이 자료의 맥락과 일반적인 공격 시나리오에 어떻게 적용되는지 이해하는 데 도움이 되는 몇 가지 귀중한 리소스입니다.