PROTOCOLS-FUN . ATTACK & MITIGATION

Attack & Mitigation

the modern landscapeL3 → L7 · bots
rev 2026.08
scope volumetric · protocol · application · bots
lens detect → identify → mitigate
identity fingerprints > UA + IP

Hover a field to light its bytes; click a field marked + for its lookup table. Classes: volumetric (L3/4, bandwidth), protocol/state (L3/4, kernel tables), application (L7, CPU/backend), bots/abuse (L7, well-formed). Blocking keys on fingerprints (JA4+), not IP or UA.

classesvolumetric / protocol / application / abuselayers3, 4, 7

Sort by what exhausts first (bandwidth / kernel table / CPU-backend), layer, and whether it looks like real traffic. Volumetric drowns the link; protocol/state exhausts finite tables (half-open conns, conntrack); application is cheap requests triggering expensive work; abuse is well-formed traffic you identify, not rate-drop.

the map
classlayerruns outexamples
VolumetricL3/4bandwidthUDP flood, amplification/reflection, ICMP flood
Protocol / stateL3/4a kernel tableSYN flood, ACK/RST flood, fragmentation, conntrack fill
ApplicationL7CPU / backendHTTP flood, Slowloris, HTTP/2 Rapid Reset, cache-bust
Bots & abuseL7your business logiccredential stuffing, scraping, scalping, AI crawlers
cost asymmetry. Higher layer = cheaper to send, costlier to serve: one crafted L7 request is a few bytes for the attacker and a DB query + template render + backend round-trip for the server. So L7/bot defense is identification, not out-muscling volume.
SYN floodRFC 4987amplificationreflection off open UDP services

SYN flood: send the opening SYN, never complete the handshake; each pins a half-open-table slot until timeout. Amplification/reflection: small spoofed-source query to an open UDP service (DNS/NTP/memcached); the large reply lands on the spoofed victim.

a SYN segment - the half-open primitive

A real TCP SYN to port 443 (source/dest are RFC 5737 doc addresses). The whole attack is this one packet, sent by the million with spoofed sources so the SYN-ACKs go nowhere and the handshakes never finish.

SYN cookies. Store no half-open state; encode the connection into the SYN-ACK ISN (a MAC over the tuple + a slow timer). The client ACK returns it; the server recomputes and reconstructs the connection. Nothing to exhaust (RFC 4987).
a DNS amplification query - small in, huge out

A 36-byte ANY query with an EDNS0 option advertising a 4096-byte UDP buffer. Spoof the source to the victim and the multi-kilobyte answer is delivered to them, not you.

amplification factors (why UDP reflection scales)
serviceportbandwidth factor
DNS (ANY)53~28-54x
NTP (monlist)123~557x
SSDP1900~30x
CLDAP389~56-70x
memcached11211~10,000-51,000x
root cause: source spoofing. Reflection works only because the source IP is forgeable and the reflector answers anyone. BCP 38 / RFC 2827 edge ingress filtering (drop packets whose source can't come from that link) starves every amplification attack; not universally deployed.
slow attackshold connections openRapid ResetCVE-2023-44487

Packets are valid HTTP; cost is server-side work. Floods hit uncached/expensive endpoints (search, login). Slow attacks (Slowloris, slow-read, slow-POST) pin worker threads/connections with a trickle of bytes, starving the pool at near-zero bandwidth. HTTP/2 multiplexing added a vector:

HTTP/2 Rapid Reset - a frame that cancels itself

The client opens a stream (HEADERS) then immediately cancels it with an RST_STREAM. The request is fully processed server-side but never counts against the max-concurrent-streams limit, so one connection can churn tens of thousands of requests/second. This is the RST_STREAM frame: a 9-byte HTTP/2 frame header + a 4-byte error code.

Rapid Reset (CVE-2023-44487, 2023). The largest L7 DDoS on record at the time - it exploited a spec-legal behavior, not a bug, so every HTTP/2 implementation was affected at once. Mitigation is counting resets and reused streams per connection and killing abusive ones, plus capping request rate independent of the stream-concurrency limit. Its cousin, the CONTINUATION flood (2024), abuses unbounded header CONTINUATION frames the same way.
slow attacks. Slowloris drops a thread-per-connection server from one laptop. Defense: event-driven servers, aggressive header/body timeouts, a reverse proxy that fully buffers the request before origin.
the hard partit looks like real trafficyou can't drop by volume

Well-formed, low-rate, distributed across residential proxy pools (real home IPs rented via malware/SDK networks), so IP reputation and rate limits barely dent it. Defense = distinguishing automated from human.

the abuse catalog
credential stuffingreplaying leaked user/pass pairs to find reuse -> account takeover (ATO)
cardingtesting stolen card numbers against a checkout, cents at a time
scrapingharvesting content/prices; now includes the surge of AI training crawlers
scalpingbots hoarding limited inventory (tickets, drops, GPUs) faster than humans
API abuseusing an API exactly as designed, just far too much / not as intended
AI crawlers. LLM training/retrieval bots scrape at soft-DDoS volumes: ignore robots.txt, rotate residential IPs, forge browser UAs. The clearest current case for fingerprint-based ID -- UA says "Chrome," the TLS/HTTP fingerprint says "Python library."
problemIP is shared, UA is a free-text lieanswerJA4+ fingerprints

IP is unreliable (CGNAT, proxies, shared cloud) and the User-Agent is client-set free text. Fingerprint how the client speaks instead: TLS handshake shape, HTTP/2 settings, TCP options -- revealed by the library regardless of what it claims.

a JA4 fingerprint, decomposed

JA4 (the TLS ClientHello half of JA4+) hashes the negotiated capabilities into a stable, human-skimmable string. This is real Chrome:

t13d1516h2_8daaf6152771_02713d6af862
t13d1516h2the readable part: t=TCP, 13=TLS 1.3, d=SNI present, 15 cipher suites, 16 extensions, ALPN h2
8daaf6152771sha256[:12] of the sorted cipher-suite list
02713d6af862sha256[:12] of the sorted extensions + signature algorithms
JA4 vs JA3. JA3 hashed raw order-sensitive fields into one MD5 -- perturbed by GREASE + extension-shuffling, so a client could randomize its own fingerprint. JA4 sorts before hashing (defeats shuffling), strips GREASE, keeps a readable prefix -> stable + skimmable. JA4+ suite: JA4H (HTTP), JA4T/JA4TS (TCP), JA4S (ServerHello), JA4X (cert).
fingerprints spoof too. curl-impersonate / utls reproduce a real browser's ClientHello -- a match is strong evidence, not proof. State of the art combines fingerprint + behavior (timing, ordering, challenge-solving); no single signal is trusted alone.
capture it: pick these ClientHellos out of live traffic in capture & filter -- display filter tls.handshake.type == 1.
principledefense in deptheach layer removes work before the next

Stack cheap filters ahead of expensive ones so each layer sheds load first. Outside-in:

the layers
edge / networkAnycast spreads the load across many sites; scrubbing centers absorb volume; BGP flowspec + RTBH (remote-triggered blackhole) drop floods upstream; CDNs serve cached bytes so attacks never reach origin
transportSYN cookies, connection + rate caps, conntrack tuning - survive the state-exhaustion class
applicationWAF rules, rate limiting (token-bucket / sliding-window), challenges (JS, CAPTCHA, proof-of-work), fingerprint + reputation blocking, bot management
architecturalcache everything cacheable, degrade gracefully under load, tarpit + honeypot the obvious offenders, autoscale with a cost ceiling
proof-of-work challenges (Anubis, mCaptcha) make every client burn CPU-ms before service -- negligible per human, ruinous per bot at scale. Inverts the L7 asymmetry: the attacker pays per request.
rate limiting. Token-bucket allows bursts then throttles; sliding-window smooths; per-fingerprint / per-account beats per-IP against proxy pools. Honeypot endpoints/addresses (the ipv6-fun canary) turn any hit into a high-confidence hostile signal.
attack costrentable by the hourthe loopspoof ↔ detect, forever

Asymmetric economics. DDoS-as-a-service: booter/stresser rentals by the hour; residential-proxy pools of millions of real IPs. Defense = anycast capacity + scrubbing contracts + engineering time. Attacker pays cents; defender pays a retainer.

obscurity is not a control. Hiding an address/subdomain/fingerprint buys time and cuts noise, but anything discoverable is found and anything static is predicted. The controls are the ones you can reason about: rate, identity, challenge, capacity.
the loop doesn't converge. Better fingerprinting (JA4) -> better spoofing (uTLS) -> behavioral/multi-signal detection -> ... Durable posture: raise attacker cost + your observability faster than they adapt. Detect -> identify -> mitigate -> observe -> repeat.