Varol Cagdas Tok

Personal notes and articles.

Resource Exhaustion as an Attack Primitive

Every system that processes work maintains a finite pool of resources to do it. CPU cycles, memory, file descriptors, socket buffers, thread pool slots, database connections, kernel routing table entries, all of these are bounded by hardware, operating system limits, and configuration. A denial of service attack does not need to break any of these resources. It needs to fill them.

Volumetric floods, protocol state exhaustion, application-layer amplification, algorithmic complexity attacks, infrastructure reflection, all of these are the same idea expressed differently: find a resource the target must spend to handle a request, and spend it faster than the target can reclaim it.

The primitive is simple; the design space it opens is enormous. Choosing which resource to attack, at which layer, through which mechanism, and at what rate is where the creativity in offensive security research actually lives.


The Formal Model

A service stays up as long as two things remain true: it has capacity to accept new work, and it completes existing work fast enough to free that capacity before it runs out. An attacker disrupts availability by violating one or both.

Let C be the total capacity of some finite resource pool. Let a(t) be the rate at which incoming requests consume that resource, and r(t) be the rate at which processing completes and resources are reclaimed. The resource pool at time t is approximately:

P(t) = C - ∫(a(τ) - r(τ))dτ

The service fails when P(t) ≤ 0. An attacker needs a(t) > r(t) for a sustained period. How long that period needs to be depends on C and on the ratio between arrival and completion rates.

A few things follow from this. First, an attacker does not need a(t) to be large in absolute terms, they need it to exceed r(t). If the attacker can find a mechanism that makes r(t) small, by slowing the processing of each request, they can exhaust resources at a modest arrival rate. This is the basis of slow-rate attacks. Second, C matters: a smaller resource pool is easier to fill. Attacks that target the most constrained resource in a system are more efficient than attacks that target resources that happen to be plentiful. Third, the time to exhaustion scales with C. A system with generous resource pools requires a sustained attack; a system with tight limits can be taken offline briefly.

If the attacker's cost per unit of a(t) is low and the defender's cost per unit of C is high, the attacker has structural leverage. This asymmetry is why the problem persists.


Asymmetry as the Design Principle

The most effective DoS attacks maximize the ratio of attacker cost to defender cost. This ratio is the core design criterion for attack construction, though it rarely appears in those terms in the literature.

Bandwidth asymmetry: An attacker sends a 46-byte UDP payload to port 19 of a host running the chargen service, spoofing the source address as the target. The chargen service generates a continuous stream of characters back to the apparent source. A single small packet creates a sustained stream to the victim. The attacker's outbound cost is one packet; the victim receives a stream until the connection times out. The amplification factor depends on how long the chargen session runs, but it is substantial. This class of attack exploits the asymmetry between packet cost and session cost.

State asymmetry: An attacker sends a TCP SYN to a server. The server allocates a connection record, initializes timer structures, and sends a SYN-ACK. The attacker sends nothing further. The connection record occupies memory and a slot in the connection state table for approximately 60–120 seconds in typical default configurations. The attacker's cost: one packet. The server's cost: memory allocated for the duration of the timeout, plus the CPU for timeout processing. The attacker repeats this at high frequency. When the connection table fills, new connections from legitimate clients are rejected.

Computation asymmetry: An attacker sends an HTTP GET request for a resource that triggers a regex match against a pathological pattern. A regex like (a+)+ applied to a long string of 'a' characters followed by a character that fails to match causes backtracking that is exponential in the length of the string. The attacker's cost: one HTTP request. The server's cost: CPU time that grows exponentially with input length. An input string of 40 characters may consume seconds of CPU time. The attacker can saturate a server with modest request rates.

The asymmetry is not incidental, it is the property being exploited. Attack research in this space is largely the work of finding new sources of asymmetry in deployed systems.


The Layer Taxonomy

DoS attacks target different resource types at different layers of the network stack. The usual taxonomy, volumetric, protocol, application, is operationally useful because different defenses apply at each layer. But it obscures the underlying unity. All three categories are resource exhaustion attacks; they differ only in which resource they exhaust and where in the processing chain they act.

Bandwidth: The Volumetric Layer

Bandwidth is the most physical of the resources. If the traffic directed at a network link exceeds its capacity, the excess is dropped. No software mitigation at the target addresses this, the packets do not arrive. The target cannot distinguish between legitimate and attack traffic because neither reaches it.

Volumetric attacks operate at this layer. The goal is to generate traffic in excess of the target's uplink capacity. The constraint is that the attacker must either possess or aggregate equivalent outbound bandwidth. This constraint drove the development of amplification techniques and of distributed attack infrastructure.

The bandwidth of the modern internet is asymmetric in ways that matter here. Content delivery networks and large hosting providers have uplink capacity measured in terabits per second. Organizations hosting their own infrastructure typically have far less. An attacker who can direct several hundred gigabits per second at a target with a 10 Gbps uplink achieves the goal regardless of anything the target does at the software layer.

Connection State: The Protocol Layer

Connection-oriented protocols require the server to maintain state across multiple packets. This state has a cost, memory, CPU for state machine transitions, and timer infrastructure. Attacks at this layer exploit the period before the protocol has verified that the remote party is legitimate.

TCP is the most studied example. The server transitions to the SYN-RECEIVED state after receiving the first packet of the handshake, before the client has demonstrated it can receive a response at the claimed source address. This design predates any consideration of hostile traffic at the scale that became possible as the internet grew. The server's state commitment happens too early in the exchange.

The same pattern appears repeatedly in protocol design. TLS performs asymmetric cryptographic operations before client authentication. DTLS introduces cookies specifically to defer state commitment, acknowledging the lesson from TCP. Many application protocols allocate sessions for unauthenticated users. Each of these represents a point where the server commits resources before trust is established.

The connection state resource is bounded by the operating system's socket table and the memory allocated for pending connections. Default limits in many operating systems were set for workloads that did not anticipate hostile traffic. Tuning these limits, increasing the backlog queue, reducing timeouts, enabling SYN cookies, addresses the specific vulnerability without addressing the general principle.

Computation: The Application Layer

Application-layer attacks exploit the gap between the cost of issuing a request and the cost of fulfilling it. The attack surface is the application logic itself: which operations are computationally expensive, which resources they consume, and whether those operations can be triggered by unauthenticated or minimally authenticated requests.

The cost asymmetry in application processing can arise from several sources:

Database operations: queries involving full-table scans, missing index coverage, or expensive joins are common examples. An attacker who can trigger such queries repeatedly exhausts database CPU and connection pool resources.

Cryptographic operations: asymmetric cryptography is significantly more expensive than symmetric. A server performing RSA or elliptic curve operations for each connection establishment is more vulnerable to application-layer exhaustion than one where the expensive operations are rate-limited or deferred.

Parsing and deserialization: complex structured formats, XML, JSON with deep nesting, compressed data, impose parsing costs that can be much larger than the size of the input. The XML "billion laughs" attack achieves enormous expansion through entity reference nesting.

Business logic: operations that aggregate data, send notifications, write to multiple tables, or call external services are more expensive than simple reads. Applications that expose these operations without rate limiting or authentication provide high-value targets.


Statefulness as Structural Vulnerability

Statefulness and DoS vulnerability are structurally linked. Stateful protocols give the server memory of incomplete exchanges, and an attacker fills that memory. The state exists because stateful abstractions are useful: they let servers cache context, optimize repeated operations, and provide guarantees like ordered delivery. But holding state for connections that may never complete is exactly what an attacker exploits.

The SYN cookie mechanism illustrates the design trade-off involved in addressing this. The server encodes connection parameters, source and destination address and port, timestamp, and other fields, into the initial sequence number of the SYN-ACK using a cryptographic function keyed to a server secret. If the client completes the handshake, the server reconstructs connection state from the ACK by verifying the sequence number. If the client never responds, no state was allocated on the server side.

The cost of this approach is that TCP options negotiated during the handshake cannot be stored in the cookie. Window scaling, selective acknowledgment, and timestamps are lost for connections established via SYN cookies. These options matter for performance. SYN cookies degrade throughput under normal conditions in exchange for resilience under attack conditions. Removing the statefulness that creates vulnerability typically requires giving up functionality that depends on that state.

This pattern, deferred state commitment at the cost of functionality, appears in DTLS cookies, in HTTP challenge-response mechanisms, and in TCP Fast Open's security considerations. Not a general solution, but a recurring engineering response to the same structural problem.


Queue Theory and Why Defaults Fail

The queue formed by incoming connection requests, pending packets, or unprocessed work items follows standard queuing theory. Under normal load, the queue remains bounded because processing completes faster than items arrive. Under attack load, the queue grows because items arrive faster than they are processed or expired.

Little's Law states that in a stable system, the average number of items in a queue equals the average arrival rate multiplied by the average time each item spends in the system. For a TCP SYN backlog queue with a maximum size of 128 entries and a timeout of 60 seconds, the maximum sustainable arrival rate of half-open connections is approximately 2 per second before the queue fills. This is an extraordinarily low threshold against any deliberate flooding attempt.

Default values in many operating systems reflect workloads from the early internet where such attacks were not anticipated or were less feasible. FreeBSD prior to version 4 used a syncache of 128 half-open connections. Linux defaults for the TCP backlog have increased over time but the increases often lag behind the growth of attack traffic. The tcp_max_syn_backlog parameter in Linux can be increased, and the combination of increased backlog with SYN cookies provides reasonable resilience, but the defaults remain low.

The deeper issue is that tuning individual parameters does not address the architectural problem. A system with a SYN backlog of 65536 takes longer to fill than one with a backlog of 128, but it fills. Any finite limit can be exceeded given sufficient attack traffic. The parameter tuning buys time; it does not eliminate the vulnerability.


The Economic Structure of the Problem

The economics favor the attacker.

Infrastructure costs: Cloud computing has made outbound bandwidth cheap and renting computational capacity for short durations easy. An attacker can rent enough capacity to generate tens of gigabits per second for the duration of an attack at costs measured in tens of dollars. The defender pays for infrastructure continuously, regardless of whether it is under attack.

Information asymmetry: the attacker knows what the attack is. The defender must observe the attack, characterize it, and respond, all while the attack is ongoing. This response time gives the attacker a window of effectiveness even when the defender ultimately deploys an effective countermeasure.

Legal and jurisdictional friction: effective mitigation often requires coordination across autonomous system boundaries, between organizations in different jurisdictions, and with infrastructure providers. The time required for this coordination is time during which the attack is effective.

Asymmetric skill requirements: generating high-volume DoS traffic does not require sophisticated technical knowledge. Stresser services and booter platforms have commoditized attack traffic to the point where purchasing a denial of service attack requires less technical sophistication than deploying an effective defense.

None of these economic factors are unique to denial of service, but they are more pronounced here than in other attack categories because the attack itself has no complexity requirement. Breaking an application requires finding and exploiting a specific vulnerability. Exhausting resources requires only sending enough traffic.


Historical Trajectory

The history of denial of service attacks is a history of attackers finding new sources of asymmetry as old ones were addressed.

Early attacks, Smurf, fraggle, ping of death, exploited misconfigurations, protocol implementation bugs, and the relative scarcity of defensive tools. Smurf attacks directed amplified ICMP traffic at victims by spoofing source addresses to broadcast addresses of networks that would generate replies from all hosts. The amplification factor was bounded by the number of hosts responding to broadcast ICMP on the intermediary network. BCP 38 (ingress filtering) and the gradual disabling of directed broadcast forwarding largely eliminated this attack class, though the deployment of BCP 38 remains incomplete decades after its publication.

The SYN flood as a widely recognized attack class dates from roughly 1996, associated with the paper by Phil Kocher and earlier operational reports. SYN cookies were proposed as a defense and were eventually integrated into major operating systems, though not without resistance from implementers who were concerned about the loss of TCP options.

Distributed attacks using botnets became feasible as internet-connected host populations grew and security practices lagged. The MafiaBoy attacks in 2000 demonstrated that a single individual with access to a moderate-sized botnet could take down large web properties. The Mirai botnet in 2016 demonstrated that the IoT device population represented an enormous pool of compromisable hosts with high-bandwidth connections and minimal security, capable of generating attacks measured in terabits per second.

Amplification attacks matured through the 2000s and 2010s. DNS amplification became practical as open resolvers remained deployed in large numbers. NTP amplification using the monlist command achieved amplification factors exceeding 500x. Memcached reflection in 2018 demonstrated amplification factors of approximately 50,000x under some conditions, enabling attacks in the terabit range from a small number of attack sources.

Application-layer attacks emerged as volumetric defenses, scrubbing infrastructure, traffic shaping, bandwidth scaling, became standard for large targets. The HTTP layer, accessible through CDN infrastructure that attenuates volumetric traffic, became the primary attack surface for sophisticated campaigns against well-defended targets. R.U.D.Y. (R-U-Dead-Yet), Slowloris, and similar slow-rate attack tools demonstrated that a server could be denied to legitimate users with modest traffic volumes by exploiting the connection handling behavior of web servers.

Today's campaigns combine volumetric, protocol, and application-layer techniques simultaneously, use legitimate cloud infrastructure as attack sources, and rely on commercial stresser services that have made sophisticated attacks available without any particular technical skill.


What Comes Next

The posts that follow cover each attack class in detail: the specific resource asymmetry, what the traffic looks like at packet level, how detection works, where it fails, and what the defense architecture looks like. The topics include amplification and reflection, protocol state machine exploitation, application-layer attacks, algorithmic complexity attacks, botnet coordination, multi-vector campaigns, slow-rate attacks, scrubbing and anycast infrastructure, and the weaponization of legitimate cloud and CDN infrastructure.