
How to Capture and Analyse a DDoS Attack with Wireshark (and tcpdump)
When your server is under attack, "we're being DDoSed" is not actionable — "SYN flood, four million packets per second, spoofed sources, targeting port 443" is. The difference between the two is a thirty-second packet capture and a structured look at it. This guide covers capturing safely on a machine that's already saturated (tcpdump, not the Wireshark GUI), the triage workflow in Wireshark — Protocol Hierarchy, Conversations, I/O Graphs — and the display-filter signatures of the common attack vectors, ending with how to turn findings into mitigation.
08. Juli 2026
von Jesse Schokker
Wireshark
DDoS
Security
Networking
Loading...
Answer first: the workflow
Analysing an attack against your own infrastructure is a five-step job, and every step exists to answer one question: which attack vector is this, so the right mitigation can be applied. (For what the vectors are and how each is stopped, see our companion piece, DDoS attacks explained.)
- Capture a sample with
tcpdump— small snapshot length, bounded size, never the Wireshark GUI on the victim machine. - Move the capture off the server and open it in Wireshark on your workstation.
- Triage with the Statistics menus — Protocol Hierarchy tells you what the traffic is, Conversations tells you who it involves, I/O Graphs tell you when and how hard.
- Confirm the vector with display filters — each attack family has a recognisable signature.
- Turn findings into action — a firewall rule where on-host filtering helps, and a specific, actionable report to your provider where it doesn't.
One scoping note before the tooling: this is a defensive forensics guide — analysing attacks hitting infrastructure you operate, using captures you're entitled to take. If you want to practise before you need it (a good idea — mid-attack is a bad time to learn Wireshark), there are public attack captures to train on, listed at the end.
Step 1: capture under load without making things worse
The instinct to open Wireshark on the attacked server is wrong twice: the GUI dissecting millions of packets per second will finish the resource-exhaustion job the attacker started, and a naive capture writes full packets to disk at attack line-rate — gigabytes per minute. The right tool on the victim is tcpdump (or dumpcap, Wireshark's capture engine, if it's installed), configured to be cheap:
# 30-second sample, headers only, no DNS lookups, bounded packet count
tcpdump -i eth0 -n -s 128 -c 500000 -w /tmp/attack-sample.pcap
Why each flag earns its place:
-s 128caps the bytes captured per packet. For vector identification you need headers, not payloads — Ethernet + IP + TCP/UDP headers plus a little slack fit comfortably in 128 bytes. This matters more than it used to look: modern tcpdump's default snapshot length is 262,144 bytes, so an explicit small snaplen is what keeps the file small and the per-packet cost low.-ndisables name resolution. Resolving thousands of attacking IPs via DNS — possibly while your link is saturated — is self-sabotage.-c 500000stops after half a million packets, whatever happens. A bounded capture can't fill your disk.-w filewrites raw packets for later analysis instead of decoding to the terminal (decoding costs CPU; the terminal costs your SSH session's bandwidth).
If the attack is sustained and you want continuous visibility rather than one sample, use a ring buffer so disk usage stays constant no matter how long it runs:
# rotate at 100 MB, keep at most 10 files (~1 GB ceiling), overwrite oldest
tcpdump -i eth0 -n -s 128 -w /tmp/attack-ring.pcap -C 100 -W 10
Two practical notes. First, add a capture filter to cut noise when you already know the target — e.g. tcpdump ... dst host 203.0.113.10 (substitute your address; examples in this guide use documentation ranges). Second, at extreme packet rates even tcpdump will drop packets — it reports how many when it exits. For vector identification that's fine: a sample is all you need, and statistical truth survives drops. (If you need complete capture at high rates, that's specialised territory — dumpcap with a large buffer, or sampling technologies like sFlow at the switch layer — but it's not required for triage.)
Step 2: get the capture off the box
Analysis happens on your workstation, not the wounded server:
scp server:/tmp/attack-sample.pcap .
Open it in Wireshark — current stable is the 4.6 series. If the file is huge despite your bounds, Wireshark's own performance guidance applies: files beyond a few hundred megabytes get sluggish, so slice a piece first (editcap -c 1000000 big.pcap slice.pcap splits by packet count; editcap ships with Wireshark).
Step 3: triage — three Statistics windows
Don't start by scrolling packets; start with the aggregate views. Three windows, in order:
Protocol Hierarchy (Statistics → Protocol Hierarchy)
One glance answers "what is this traffic?": the protocol tree with packet and byte percentages. A healthy web server's capture is dominated by TCP/TLS. An attack capture is usually grotesquely skewed — 95% UDP where you serve none, or a wall of bare TCP packets with no application-layer protocol on top (the signature of a flood of handshake packets that never become connections).
Conversations (Statistics → Conversations)
The who-talks-to-whom table, sortable by packets, bytes, and duration. What to read from it:
- Source spread. Ten thousand source addresses each sending a few hundred packets to one destination is a distributed flood (or spoofing — step 4 distinguishes them). A handful of sources sending millions of packets is something you can null-route today.
- Sort by packets, not bytes, for packet-rate attacks — a SYN flood is enormous in packet count and modest in bytes.
- The UDP tab vs TCP tab split often decides the family on its own.
I/O Graphs (Statistics → I/O Graphs)
Traffic over time. Set the Y axis to packets/sec (attacks that matter are usually packet-rate anomalies, and bytes-graphs understate small-packet floods), and add graph lines with filters to compare classes of traffic — e.g. one line for tcp.flags.syn == 1 && tcp.flags.ack == 0 against one for all traffic shows exactly when a SYN flood began and whether it's constant or pulsing. Attack bursts of seconds to a few minutes are the norm, not the exception — most real attacks are short.
Step 4: confirm the vector with display filters
Now the specific signatures. Type these into Wireshark's display filter bar on your capture.
SYN flood
tcp.flags.syn == 1 && tcp.flags.ack == 0
That's every initial SYN. In legitimate traffic, SYNs are a sliver of the total and each is followed by a completing handshake. In a SYN flood, this filter matches a huge share of the capture, and the follow-ups never come. Cross-checks:
- Compare counts with
tcp.flags.syn == 1 && tcp.flags.ack == 1(the server's SYN-ACKs) and with established-connection traffic. Thousands of SYNs, no completed conversations → flood confirmed. - Spoofed or real sources? Look at
ip.ttlacross the flood: real botnet clients arrive with the natural spread of TTLs you'd expect from diverse network paths; naive spoofing tools often emit uniform or neatly-patterned TTLs, identical window sizes, and sequence numbers with no organic variety. Sources that never respond to your SYN-ACK are consistent with spoofing; sources that complete handshakes and then attack are real machines.
UDP amplification / reflection
udp.srcport in {53, 123, 389, 11211, 1900, 19}
Reflected attack traffic arrives from the well-known port of the abused service — DNS (53), NTP (123), CLDAP (389), memcached (11211), SSDP (1900), CharGEN (19) — because it genuinely is that service, answering queries the attacker sent in your name. Corroborating signs:
- Large, often fragmented packets — amplification means the responses are big; check Statistics → Packet Lengths for a distribution pinned at the high end, and
ip.flags.mf == 1 || ip.frag_offset > 0for fragments. - For DNS specifically:
dns.flags.response == 1traffic you have no matching queries for, and amplification-friendly query types visible in the responses (dns.qry.type == 255, the classic ANY query). - The "sources" here are reflectors — victims themselves, not attackers. Blocking them individually is whack-a-mole; the actionable output is "drop UDP source port N toward my address upstream", which is precisely the kind of rule your provider's mitigation (or a network-edge firewall) applies well.
ICMP flood
Protocol Hierarchy makes this one obvious on its own; confirm with icmp.type == 8 (echo requests) at absurd rates from many sources.
HTTP(S) floods — and the encryption caveat
For plaintext HTTP you can go deep in Wireshark: http.request rates per source in Conversations, repeated identical URIs (http.request.uri contains "/search"), archaic or absent User-Agents. But most floods today target HTTPS, and a packet capture cannot see inside TLS without the server's session keys. Be honest about the boundary: from the capture you can still establish that it's an application-layer attack — a storm of short-lived TLS connections is visible as tls.handshake.type == 1 (ClientHellos) at anomalous rates per source — but what they're requesting comes from your web server's access logs, not the pcap. Analyse L7 floods with both: the capture proves the connection pattern; the logs show the URIs and headers.
Step 5: from findings to mitigation
The point of the analysis is the sentence it lets you write. Compare:
"We're under DDoS, please help."
"Since 14:02 UTC we're receiving ~3.5M pps of NTP reflection — UDP source port 123, ~1,200-byte packets, many fragments — at 203.0.113.10. Can you drop UDP src 123 toward that address at the edge?"
The second gets a precise upstream filter applied in minutes. Route your findings by what you learned:
- Volumetric (amplification, UDP floods): upstream, always — the packets already crossed your uplink, so on-host rules can't help. Hand the vector signature to your provider or apply it in a self-service edge firewall if you have one.
- SYN floods: confirm SYN cookies are on (
sysctl net.ipv4.tcp_syncookies), rate-limit new connections, and pass the signature upstream if volume exceeds what the host absorbs comfortably. - L7 floods: your reverse proxy and WAF — per-source request limits, caching, challenges for the offending pattern from the access logs.
On-host, nftables expresses the emergency rules compactly (see our firewall baseline and iptables vs nftables for the fundamentals):
# emergency: drop NTP-reflection traffic on the host (better: at the edge)
nft add rule inet filter input udp sport 123 drop
# throttle new connections per source during a connection flood
nft add rule inet filter input tcp dport 443 ct state new limit rate over 50/second drop
And afterwards — save the capture, the filters that identified the vector, and the rule that stopped it. Attacks recur; the second incident should take five minutes.
Practising before you need it
Mid-incident is the wrong moment to learn this workflow. Public datasets let you rehearse legally:
- StopDDoS packet captures — anonymised real-world and lab DDoS pcaps covering exactly the vectors above: DNS/NTP/CLDAP/memcached reflection, SYN and UDP floods. The best practice set for this article; open one and run the triage sequence.
- CIC-DDoS2019 — an academic dataset (University of New Brunswick) with raw pcaps of ~13 labelled attack types mixed with benign traffic; heavier, suited to deeper study.
- The Wireshark wiki's sample captures include some historic attack traffic (fragmentation attacks, worm traffic) — older, but fine for practising the Statistics workflow.
Frequently asked questions
Can Wireshark stop a DDoS attack?
No — Wireshark is a microscope, not a shield. Its job in an incident is diagnosis: telling you which vector you're facing so the actual mitigation (upstream scrubbing, edge filters, rate limits, WAF rules) can be aimed correctly. The stopping happens in your provider's mitigation layer and your firewall, as covered in our DDoS protection guide.
Should I use tcpdump or Wireshark?
Both, in sequence: tcpdump (or dumpcap) captures on the server — it's lightweight, headless, and safe to run on a machine under stress — and Wireshark analyses the resulting file on your workstation, where its dissectors and statistics tools shine. Running the Wireshark GUI on a production server under attack is the one clearly wrong answer: it burns exactly the CPU and memory the attack is trying to exhaust.
How long should the capture be?
Shorter than intuition suggests: thirty seconds of attack traffic is normally ample to identify a vector, because floods are statistically monotonous — millions of near-identical packets. Bound every capture (-c for count, or -C/-W ring buffers) so it can't fill the disk, and prefer several short samples over one giant file; a multi-gigabyte pcap mostly buys you a sluggish Wireshark session, not more insight.
The attack is over HTTPS — is capturing pointless?
Not pointless, just bounded. The capture still reveals the connection-level story: source distribution, connection rates, TLS handshake floods, packet timing — enough to confirm "application-layer flood" and profile the clients. What it can't show is the plaintext requests inside TLS, so pair the pcap with your web server's access logs, which record the decrypted request line, headers, and timing for every request the server actually processed.
Deploying on Serverside
The best time to do this analysis is while your server stays reachable — which is what always-on mitigation is for. Every dedicated server on our network sits behind always-on DDoS mitigation on ASN 55285: attacks are scrubbed at the edge automatically, and the self-service edge firewall lets you apply exactly the kind of vector-specific drop rules this guide teaches you to derive — upstream of your port, where volumetric traffic must be stopped. Sub-minute provisioning, and KVM console access for when you want to work on a box out-of-band.
Round out the series with DDoS attacks explained: forms and protection, sensible default firewall rules, and iptables vs nftables.

Über den Autor
Jesse SchokkerCo-founder & CTO, Serverside.com
Jesse is the co-founder and CTO of Serverside.com, where he leads the engineering behind the company's bare-metal cloud — from the ASN 55285 backbone to sub-minute server provisioning. He writes about dedicated servers, operating systems, and running production workloads on bare metal.
