Incident Summary
| Parameter | Detail |
|---|---|
| Date | February 2020 |
| Peak Bandwidth | 2.3 Tbps |
| Attack Vector | CLDAP reflection / amplification |
| Protocol | UDP port 389 |
| Amplification Factor | 56–70x |
| Duration | 3-day attack campaign |
| Target | Undisclosed AWS customer |
| Mitigation | AWS Shield Advanced |
| Previous Record | 1.7 Tbps (Arbor/NETSCOUT, March 2018) |
| Disclosure | AWS Shield Threat Landscape Report, Q1 2020 |
What We Know
AWS disclosed this incident in their AWS Shield Threat Landscape Report for Q1 2020. The report confirmed that an AWS customer was targeted with a sustained CLDAP reflection attack peaking at 2.3 Tbps in February 2020. This surpassed the previous record of 1.7 Tbps observed by Arbor Networks/NETSCOUT in March 2018 (a memcached amplification attack against a US-based service provider) and stood as the largest publicly disclosed volumetric DDoS attack until Cloudflare and Microsoft reported multi-terabit attacks in late 2021.
The public details are deliberately limited. AWS did not name the target customer, the specific AWS region, or the exact number of reflectors involved. What we do know is that the attack lasted approximately three days, that it was a CLDAP reflection vector, and that AWS Shield Advanced mitigated it without customer-facing impact. The three-day duration suggests either a persistent adversary with substantial reflector infrastructure or an automated booter/stresser service with CLDAP capabilities.
The significance of this event goes beyond the raw bandwidth number. CLDAP reflection had been a known vector since 2016, but this attack demonstrated that the pool of exposed CLDAP reflectors on the internet was large enough to generate multi-terabit floods. That fact alone should have been a wake-up call for every organization running Active Directory with LDAP exposed to the internet.
The Q1 2020 report marked the first time AWS publicly disclosed a specific attack volume figure of this magnitude. Previous AWS Shield reports had discussed attack trends in aggregate without singling out individual incidents at this scale.
How CLDAP Reflection Works
CLDAP stands for Connection-less Lightweight Directory Access Protocol. It is defined in RFC 1798 (now historic, superseded by RFC 3352) and represents a UDP-based variant of LDAP. While standard LDAP operates over TCP port 389, CLDAP uses UDP port 389. Microsoft's Active Directory domain controllers have supported CLDAP since Windows 2000 and listen on UDP 389 by default to support domain controller location (the "DC locator" process that domain-joined clients use to find nearby DCs).
The reflection attack exploits a specific CLDAP operation: the rootDSE query. The rootDSE (Root DSA-Specific Entry) is a special entry at the root of a directory that describes the capabilities of the directory server. When a client sends a CLDAP SearchRequest for the rootDSE with an empty base DN and a scope of base, the server responds with a rich set of attributes describing the Active Directory environment: the domain name, forest name, domain GUID, supported LDAP versions, supported SASL mechanisms, supported capabilities OIDs, the DC's site name, and more.
Why the Response Is So Large
A rootDSE query is tiny. The CLDAP SearchRequest for the rootDSE can be as small as 56–84 bytes on the wire (including UDP and IP headers). The response, however, contains all of the rootDSE attributes, which are encoded in ASN.1 BER (Basic Encoding Rules) format. A typical Active Directory domain controller returns a rootDSE response of 3,000–5,900 bytes, depending on the domain configuration, the length of the domain name, the number of supported capabilities, and whether the DC supports extended attributes.
This gives CLDAP a practical amplification factor of 56x to 70x. In certain configurations — particularly domain controllers in forests with long DNS names, multiple supported SASL mechanisms, or extended attributes — the amplification factor can exceed 70x. Here is how CLDAP compares to other reflection vectors:
| Protocol | Port | Amplification Factor | Typical Response Size |
|---|---|---|---|
| Memcached | UDP 11211 | 10,000–51,000x | Up to several MB |
| CLDAP | UDP 389 | 56–70x | 3,000–5,900 bytes |
| NTP (monlist) | UDP 123 | 556x | ~48 KB (600 entries) |
| DNS (ANY) | UDP 53 | 28–54x | 2,000–4,096 bytes |
| SSDP | UDP 1900 | 30x | ~3,000 bytes |
| Chargen | UDP 19 | 358x | ~74 bytes per packet, sustained |
| SNMP v2 | UDP 161 | 6–10x | ~1,500 bytes |
CLDAP sits in a dangerous sweet spot. While its amplification factor is lower than memcached or NTP monlist, the number of available reflectors is far larger than memcached (which was patched quickly after the 2018 attacks), and the responses are large enough that even a moderate number of reflectors can produce terabit-scale floods. Unlike NTP monlist, which requires the server to have a populated monitoring list, every Active Directory domain controller with UDP 389 exposed to the internet is a ready-to-use reflector with no special configuration required.
Protocol-Level Mechanics
Understanding the exact packet structure of a CLDAP reflection attack is essential for building detection rules. The attacker sends a CLDAP SearchRequest encoded in ASN.1 BER to an exposed domain controller over UDP port 389, with the source IP spoofed to the victim's address.
The CLDAP SearchRequest
The minimal rootDSE query looks like this using ldapsearch:
# Simulating the rootDSE query that attackers use for amplification
# DO NOT run this against servers you do not own
$ ldapsearch -LLL -x -H ldap://dc.example.com:389 \
-b "" -s base "(objectClass=*)" \
currentTime defaultNamingContext dnsHostName \
domainControllerFunctionality domainFunctionality \
forestFunctionality dsServiceName highestCommittedUSN \
isGlobalCatalogReady isSynchronized \
ldapServiceName namingContexts rootDomainNamingContext \
schemaNamingContext serverName subschemaSubentry \
supportedCapabilities supportedControl \
supportedLDAPPolicies supportedLDAPVersion \
supportedSASLMechanisms
On the wire, the actual CLDAP request is far smaller than this command line suggests. The ASN.1 BER encoding of the SearchRequest consists of:
# CLDAP SearchRequest structure (ASN.1 BER)
# Total wire size: ~56-84 bytes (including IP + UDP headers)
30 [length] # SEQUENCE (LDAP Message)
02 01 01 # INTEGER messageID = 1
63 [length] # APPLICATION 3 (SearchRequest)
04 00 # OCTET STRING baseObject = "" (empty = rootDSE)
0a 01 00 # ENUMERATED scope = 0 (baseObject)
0a 01 00 # ENUMERATED derefAliases = 0 (neverDerefAliases)
02 01 00 # INTEGER sizeLimit = 0 (unlimited)
02 01 00 # INTEGER timeLimit = 0 (unlimited)
01 01 00 # BOOLEAN typesOnly = FALSE
87 0b # CONTEXT 7 (Filter: present)
6f 62 6a 65 63 # "objectClass" (present filter = wildcard match)
74 43 6c 61 73
73
30 00 # SEQUENCE attributes = empty (return all)
The critical detail is that the query fits in a single UDP datagram and the base DN is empty. An empty base DN with scope baseObject is the standard way to query the rootDSE in any LDAP implementation. The (objectClass=*) filter matches any entry, and with the rootDSE scope, it returns exactly one result: the root entry with all its operational attributes.
IP Spoofing and UDP
The entire attack depends on the fact that CLDAP runs over UDP. Unlike TCP, UDP has no three-way handshake. The attacker crafts raw UDP datagrams with the source IP field set to the victim's address and sends them to thousands of exposed domain controllers. Each DC processes the request, generates the large rootDSE response, and sends it to the "source" IP — which is actually the victim. The victim receives thousands of 3–6 KB responses per second from legitimate domain controllers worldwide.
# Simplified attack flow:
Attacker (84 bytes) Reflector (DC) Victim
| | |
|--- UDP src=VICTIM:rand dst=DC:389 -->| |
| SearchRequest(rootDSE) | |
| |--- UDP src=DC:389 dst=VICTIM:rand -->|
| | SearchResponse (~4,800 bytes) |
| | |
| (repeat x 100,000 reflectors) | |
| | = 2.3 Tbps at victim |
To reach 2.3 Tbps with a 56x amplification factor, the attacker needed to generate approximately 41 Gbps of spoofed query traffic. With a small botnet or a handful of servers on networks that do not implement BCP38, this is entirely achievable.
The Reflector Landscape
CLDAP reflectors are, almost without exception, Windows Server machines running Active Directory Domain Services with LDAP accessible on UDP port 389 from the public internet. This happens more often than it should, for several reasons:
- Default configuration: Active Directory's LDAP service binds to all interfaces on both TCP 389 and UDP 389 by default. Administrators who intend to expose only TCP LDAP for legitimate directory queries often overlook that UDP 389 is also open.
- Cloud migrations: Organizations migrating domain controllers to public cloud infrastructure (AWS EC2, Azure VMs, GCP Compute Engine) sometimes misconfigure security groups or firewall rules, exposing UDP 389 to 0.0.0.0/0.
- Legacy infrastructure: Older Windows Server deployments (2008, 2012) may have been deployed before CLDAP reflection was a known threat, and their firewall configurations were never updated.
- VPN/remote access: Some organizations intentionally expose LDAP to support remote domain joins or legacy applications that require direct LDAP access.
Shodan queries for UDP 389 have historically revealed between 250,000 and 800,000 CLDAP-responding hosts on the public internet. While the number has decreased from its peak, there remain hundreds of thousands of usable reflectors. At 70x amplification with 400,000 reflectors, an attacker can theoretically generate massive floods with only moderate query bandwidth. The math is straightforward:
# Back-of-envelope calculation for 2.3 Tbps CLDAP attack: # # Target output: 2,300 Gbps (2.3 Tbps) # Amplification: ~56x average # Required input: 2,300 / 56 = ~41 Gbps of spoofed queries # # If using 400,000 reflectors: # 41 Gbps / 400,000 = ~102 Kbps per reflector # Each reflector receives ~1,200 queries/sec (at 84 bytes each) # Each reflector sends ~1,200 responses/sec (at ~4,800 bytes each) # Per-reflector output: ~5.76 Mbps # # This is well within what a single DC can handle without # triggering any rate limiting or performance degradation.
The low per-reflector load is what makes CLDAP reflection particularly insidious. Each individual domain controller is handling a perfectly normal query rate — a few thousand rootDSE queries per second is not enough to trigger alerts on the reflector side. The attack only becomes visible at the victim, where hundreds of thousands of these responses converge.
Reflector responsibility: If you operate Active Directory domain controllers, verify that UDP port 389 is not accessible from the public internet. A simple nmap -sU -p 389 YOUR_DC_IP from an external host will confirm. If it is open, close it immediately — there is no legitimate reason for internet-facing CLDAP access.
Detection at the Target
If you are on the receiving end of a CLDAP reflection attack, the traffic has several distinctive characteristics that make it identifiable at the packet level, even before you examine the payload.
Traffic Signatures
- Source port 389 (UDP): All reflected CLDAP responses originate from UDP source port 389. Unless your server actively queries external LDAP servers, any inbound UDP traffic from port 389 is suspicious.
- Packet sizes of 3,000–5,900 bytes: CLDAP rootDSE responses cluster in this range. This is larger than most legitimate UDP traffic except DNS with EDNS0 or video streaming.
- Thousands of distinct source IPs: Each source is a real domain controller, so the source IPs are diverse, globally distributed, and resolve to legitimate organizations. This diversity can fool naive defenses that only look for single-source floods.
- Unsolicited responses: Your server never sent CLDAP queries, so these are entirely unsolicited SearchResponse messages. There are no matching outbound requests in your connection tracking tables.
tcpdump Capture and Filtering
# Capture CLDAP reflection traffic # Matches inbound UDP from source port 389 $ tcpdump -nn -i eth0 'udp src port 389' -c 20 -v 16:41:03.221 IP 203.0.113.50.389 > 198.51.100.10.47231: UDP, length 4847 16:41:03.221 IP 192.0.2.12.389 > 198.51.100.10.47231: UDP, length 5102 16:41:03.222 IP 198.51.100.200.389 > 198.51.100.10.47231: UDP, length 3891 16:41:03.222 IP 203.0.113.77.389 > 198.51.100.10.47231: UDP, length 4673 16:41:03.222 IP 192.0.2.45.389 > 198.51.100.10.47231: UDP, length 5344 # Save to pcap for analysis $ tcpdump -nn -i eth0 'udp src port 389' -w /tmp/cldap-attack.pcap # Count packets per second to gauge attack volume $ tcpdump -nn -i eth0 'udp src port 389' -c 1000 2>&1 | tail -1 1000 packets captured in 0.043 seconds # = ~23,000 pps
PPS and Bandwidth Signatures
CLDAP reflection produces a specific PPS-to-bandwidth ratio. Because each packet is relatively large (3–6 KB), you see high bandwidth with comparatively modest packet rates. A 2.3 Tbps CLDAP attack at an average packet size of 4,800 bytes would produce approximately 60 million packets per second. Compare this to a SYN flood, where 2.3 Tbps at 60-byte packets would require 4.8 billion PPS. This distinction is critical for detection: if your bandwidth spikes dramatically but your PPS is not proportionally extreme, you are likely dealing with an amplification vector rather than a volumetric flood of small packets.
Flowtriq's detection engine monitors both PPS and bandwidth simultaneously. When it detects a bandwidth spike where the average packet size exceeds 2,000 bytes and source port entropy drops (clustering on port 389), it classifies the attack as CLDAP reflection within seconds — no manual analysis required.
Mitigation Approaches
Host-Level Filtering
If your server never needs to receive LDAP responses from external hosts, you can block all inbound UDP from source port 389. This is the simplest and most effective host-level mitigation:
# Block all inbound CLDAP responses
iptables -A INPUT -p udp --sport 389 -j DROP
# If you need to log before dropping (for evidence collection):
iptables -A INPUT -p udp --sport 389 -j LOG \
--log-prefix "CLDAP-REFLECTION: " --log-level 4
iptables -A INPUT -p udp --sport 389 -j DROP
# Rate-limit instead of hard block (if you have legitimate LDAP needs):
iptables -A INPUT -p udp --sport 389 \
-m limit --limit 10/sec --limit-burst 20 -j ACCEPT
iptables -A INPUT -p udp --sport 389 -j DROP
# nftables equivalent:
nft add rule inet filter input udp sport 389 counter drop
The limitation of host-level filtering is that it only protects the server's CPU from processing the packets. The traffic still consumes your network link. If the attack exceeds your port capacity (as a 2.3 Tbps attack certainly would for any single server), host-level rules are insufficient because the packets never reach your NIC in the first place — they are dropped at the upstream router or switch due to link saturation.
Upstream Scrubbing and Cloud Mitigation
For attacks at the scale of the 2020 AWS incident, only upstream mitigation is viable. This is exactly what AWS Shield Advanced did: it absorbed and scrubbed the 2.3 Tbps of CLDAP traffic at AWS's edge network before it reached the customer's VPC. Cloud-based scrubbing services (AWS Shield, Cloudflare, Akamai Prolexic, etc.) have aggregate network capacity in the tens of terabits and can absorb even the largest reflection attacks.
For organizations running bare-metal infrastructure, options include:
- Transit provider scrubbing: Many Tier 1 and Tier 2 ISPs offer DDoS scrubbing services that can filter attack traffic before it reaches your network.
- On-demand scrubbing centers: Services like Cloudflare Magic Transit or Akamai Prolexic can be activated during an attack to tunnel your traffic through their scrubbing infrastructure.
- Remote triggered blackhole (RTBH): As a last resort, BGP blackhole routing can be used to null-route traffic to the targeted IP at your upstream provider. This stops the attack but also makes the target unreachable.
ACL Filtering at the Network Edge
If you control your border routers, you can deploy ACLs to drop UDP traffic with source port 389 before it enters your network:
# Cisco IOS example - drop inbound CLDAP responses at the border ip access-list extended ANTI-CLDAP deny udp any eq 389 any permit ip any any interface GigabitEthernet0/0 ip access-group ANTI-CLDAP in
This is more effective than host-level filtering because it drops the traffic at the network edge, protecting all hosts behind the router and preserving internal bandwidth.
BCP38: Stopping the Attack at Its Source
Every reflection attack — CLDAP, DNS, NTP, memcached, all of them — depends on source IP spoofing. BCP38 (RFC 2827) describes network ingress filtering: ISPs and network operators should verify that packets leaving their network have source IPs that belong to their address space. If every network on the internet implemented BCP38, reflection attacks would be impossible.
The reality is that BCP38 adoption, while improving, remains incomplete. Projects like the CAIDA Spoofer Project track adoption rates and estimate that approximately 25–30% of autonomous systems on the internet still allow source IP spoofing. Until BCP38 is universal, reflection attacks will remain viable.
Detect before you mitigate: Flowtriq gives you per-second visibility into attack traffic the moment it arrives. Even if you rely on upstream scrubbing for mitigation, knowing the exact attack vector, volume, and source port distribution within seconds lets you validate that your scrubbing service is actually filtering the right traffic. Start your free 7-day trial — detection starts at $9.99/mo per node.
Timeline of Record-Breaking DDoS Attacks
The 2020 AWS attack did not happen in isolation. It was part of a years-long escalation of volumetric DDoS records driven primarily by reflection/amplification vectors:
OVH: 1.1 Tbps — Mirai botnet IoT-powered DDoS. Not a reflection attack but a direct volumetric flood from ~145,000 compromised IoT devices.
Dyn DNS: ~1.2 Tbps (est.) — Mirai botnet again. Took down major internet services including Twitter, Reddit, Netflix, and GitHub by targeting a DNS infrastructure provider.
GitHub: 1.35 Tbps — Memcached amplification. The first major memcached reflection attack, using the then-new vector's 51,000x amplification factor.
Arbor/NETSCOUT: 1.7 Tbps — Memcached amplification. Set the volumetric record that would stand for nearly two years.
AWS: 2.3 Tbps — CLDAP reflection. The subject of this post. Broke the record by 35% using a less-amplified but more available vector.
Microsoft Azure: 3.47 Tbps — UDP reflection from multiple vectors. Eclipsed the AWS record using a multi-vector approach combining UDP amplification protocols.
Lessons from the 2.3 Tbps Attack
1. Reflection Attacks Do Not Need Botnets
The Mirai attacks of 2016 required infecting hundreds of thousands of IoT devices. The 2020 CLDAP attack required zero compromised hosts — only a handful of servers capable of sending spoofed UDP packets and hundreds of thousands of unwitting reflectors (domain controllers) that were already on the internet. Reflection attacks are cheaper, simpler, and more scalable than botnet-driven floods.
2. The Amplification Arms Race Continues
Each new protocol that offers amplification over UDP becomes a potential DDoS vector. CLDAP was described as an amplification risk by Akamai researchers in 2016, but it took four years for the largest attack to materialize. The delay between discovery and weaponization at scale gives defenders a window, but that window closes faster with each new vector as attacker tooling becomes more automated.
3. Closing Reflectors Is a Collective Responsibility
The 2.3 Tbps attack was only possible because hundreds of thousands of domain controllers were exposed to the internet on UDP 389. Every one of those reflectors was a misconfigured server in someone's network. If even half of them had been firewalled, the attack's maximum capacity would have been halved. Organizations have a responsibility to ensure their infrastructure is not being weaponized against others.
4. Bare-Metal Servers Need Per-Second Detection
AWS Shield absorbed this attack because AWS has terabits of aggregate edge capacity and automated detection systems that operate at network scale. If you are running bare-metal servers in a colocation facility, you do not have that luxury. A 2.3 Tbps attack — or even a 23 Gbps attack — will saturate your uplinks long before traditional monitoring (which polls at 5-minute intervals via SNMP) even notices. Per-second PPS and bandwidth monitoring is not optional for bare-metal infrastructure. It is the only way to detect and respond to attacks before they cause extended downtime.
5. Multi-Layered Defense Is Non-Negotiable
Even organizations behind cloud providers like AWS should not assume they are fully protected. AWS Shield Standard covers basic DDoS protection, but Shield Advanced (which mitigated this attack) is a paid service. Understanding your attack surface, having detection at the host level, maintaining relationships with upstream providers for emergency filtering, and keeping firewall rules current across your infrastructure — all of these layers matter.
Cloud providers protect their network, not yours: AWS Shield Advanced mitigated this attack for the targeted customer, but only because that customer was using Shield Advanced. Default protections (Shield Standard) may not stop attacks of this magnitude. Flowtriq provides the detection layer that tells you exactly what is hitting your infrastructure, whether you are in the cloud, on bare metal, or in a hybrid setup. Start your free trial — no credit card required.