A denial-of-service attack does not need to break into anything. It only needs to ask for more than the target can answer.
Analogy: The prank call flood
Imagine every prankster in a city deciding to phone one small pizza shop at the same moment. The line is never free, the staff can take no real orders, and the business effectively stops, not because anything is broken but because the capacity to answer is exhausted. A denial-of-service attack does this to a server: it sends far more requests than the target can answer, so legitimate users cannot get through. When the flood comes from many machines at once it is called distributed, a DDoS.
Four families, one shared goal
Not every denial-of-service attack looks the same on the wire.
| Type | How it exhausts the target | Example |
|---|---|---|
| Volumetric | Floods the network link with sheer traffic volume | LOIC, UDP flood |
| Protocol | Exhausts connection tables with half-open sessions | SYN flood |
| Application | Ties up the server with costly requests | HTTP GET flood |
| Amplification | Small forged requests trigger huge replies at the victim | memcached, DNS |
This article builds a detector for the simplest and most visible of the four: a volumetric or application-layer flood, where the same request is repeated far more often than any real use would produce.
LOIC and the fingerprint of simplicity
The Low Orbit Ion Cannon, or LOIC, became widely known in 2010 when the online collective Anonymous distributed it for coordinated campaigns. Its traffic is simple by design: the same HTTP GET request, or raw TCP and UDP packets, sent as fast as the connection allows, with none of the logic a real browser would use, no cookies kept, no respect for how often a page would really be reloaded. That very simplicity is its fingerprint.
find_flood_pattern.py
# find_flood_pattern.py: spot a burst of identical requests to one target
from collections import defaultdict
import dpkt, socket
from open_capture import read_packets
request_counts = defaultdict(int)
for ts, raw in read_packets("capture.pcap"):
try:
ip = dpkt.ethernet.Ethernet(raw).data
tcp = ip.data
if len(tcp.data) == 0:
continue
http = dpkt.http.Request(tcp.data)
key = (socket.inet_ntoa(ip.dst), http.method, http.uri)
request_counts[key] += 1
except (AttributeError, dpkt.dpkt.UnpackError):
continue
for (dst_ip, method, uri), count in sorted(
request_counts.items(), key=lambda x: -x[1])[:5]:
print(f"{count} identical requests: {method} {uri} -> {dst_ip}")
Run against a lab capture built for this unit, roughly 1,845 packets, most of them a flood of GET /index.html from three sources against one victim, mixed in among a little ordinary background traffic:
Sample output
1800 identical requests: GET /index.html -> 10.0.0.5
5 identical requests: GET /style.css -> 10.0.0.5
Eighteen hundred copies of one request, GET /index.html, in a single capture is not traffic a browser could produce. That is the fingerprint of a flood, and the script found it in a few lines of output. A handful of identical requests, the five for style.css, is normal; thousands of the exact same request at one destination in a single capture window is the flood this script is built to surface.
dpkt.http.Request(tcp.data) parses a TCP payload as an HTTP request, giving .method (such as GET) and .uri (the path requested). Wrapped in the same try/except pattern from the last article, it safely skips any TCP payload that is not a valid HTTP request at all, such as the encrypted bytes of an HTTPS connection.
Real incident: Operation Payback, 2010: LOIC and a voluntary botnet
In December 2010, the collective Anonymous organised Operation Payback, directing volunteers to download and run LOIC against the websites of PayPal, Mastercard and Visa, in protest at those firms halting donations to WikiLeaks. Thousands ran the tool at once, and unlike a botnet built from compromised machines, every participant joined knowingly, which did not protect many of them from prosecution. Authorities in the United States and United Kingdom later arrested and charged several, some of whom had assumed that running a freely available tool against a public website carried no legal consequence.
What this teaches: the pattern find_flood_pattern.py looks for, identical requests converging on one target, is exactly what thousands of LOIC instances produced that December. It also carries a legal lesson as sharp as the technical one: knowingly joining a denial-of-service attack, even as one volunteer among thousands and even for a cause one believes in, is a criminal offence in most countries, India's IT Act, 2000 among them.
Check your understanding
Question 1: Walk through what find_flood_pattern.py counts, and describe the result that would indicate a LOIC-style flood.
It counts how many times each exact combination of destination address, HTTP method and requested path appears across the whole capture. A result showing the same destination, method and path repeated thousands of times, far beyond what a real browser's normal use would produce, indicates a LOIC-style volumetric flood.
Question 2: Why does a simple, repetitive tool like LOIC leave such a clear fingerprint, compared to how a real browser behaves?
A real browser varies its requests, respects caching, keeps cookies and spaces out reloads based on user actions. LOIC sends the exact same request as fast as the connection allows, with none of that variation, so the traffic it produces is unnaturally uniform and repetitive, which is precisely what a counting script like this one is built to notice.
Question 3: In the Operation Payback case, why did "I only ran the tool once, along with thousands of others" not protect participants from prosecution?
Participation itself, not the scale of any one person's individual contribution, was what the law treated as the offence. Knowingly joining a coordinated denial-of-service attack is a criminal act regardless of how many other people joined alongside you or how strongly you believed in the cause.
Key takeaway: Key takeaway
A denial-of-service attack exhausts capacity, not security; four families do it in different ways, but a simple volumetric or application-layer flood leaves a blunt, countable fingerprint: one request, repeated far more than any real use ever would be. Counting is often all it takes to find it.

