How to read a pcap file without Wireshark
A capture arrives, the machine in front of you will not let you install a packet analyser, and the file holds credentials and internal names you must not hand to a website. The questions you have are shallow ones: who talked to whom, what was looked up, what went out in the clear, what is on a timer. This is how a capture file is put together, how to answer those four questions from the headers alone, and where a reader in a browser tab stops being enough.
You can read most of what a capture has to tell you in a browser tab. Drop a .pcap or .pcapng into WIRE and it parses the file locally — conversations ranked by bytes, every name that was looked up, the server names inside TLS handshakes, credentials that crossed in the clear, and flows whose connection attempts are too regular to be a person. Nothing is uploaded, and once the page has loaded it works with the network off. It is not Wireshark and does not pretend to be: it answers the first ten minutes of questions on a machine where you cannot install one and must not hand the file to a website.
Why this comes up at all
Somebody sends you a capture. It is from a customer's network, or a client's laptop, or an incident three time zones away, and you need to know what is in it today. Three things are usually true at once: the machine in front of you is locked down and you cannot install a packet analyser on it; the file may hold credentials, session cookies, internal hostnames and personal data, so putting it through an online converter would be its own incident; and the questions you actually have are shallow ones. Who did this host talk to. What did it look up. Did anything go out in plain text. Is something phoning home.
Those questions do not need stream reassembly or a dissector for a hundred protocols. They need the packet headers read correctly and counted, which a browser can do.
What a capture file actually is
Two formats, and the extension on the file is not a reliable guide to which one you have.
- pcap (the classic libpcap format) is a 24-byte file header followed by a record for each packet: a timestamp, the number of bytes captured, the number of bytes the packet really was, then the bytes. The file header opens with a magic number, and there are four of them:
a1b2c3d4for microsecond timestamps anda1b23c4dfor nanoseconds, each of which can appear byte-reversed (d4c3b2a1,4d3cb2a1) depending on the endianness of the machine that wrote it. Reading the timestamps of a little-endian nanosecond capture as if they were big-endian microseconds does not throw an error. It gives you plausible times that are wrong, which is worse. - pcapng (the newer block format, and what Wireshark writes by default) is a sequence of typed blocks. A Section Header Block declares the byte order for everything after it; an Interface Description Block per interface declares the link type and, optionally, the timestamp resolution, which is a per-interface exponent and not a constant. A file can hold several sections with different byte orders, and several interfaces with different resolutions. Software that assumes microseconds everywhere reports timings that are off by a factor of a thousand on a capture that used nanoseconds.
A capture is also very often incomplete on purpose. Snap length is how many bytes of each packet the capture tool kept: set it to 96 and you have the headers and nothing else. A record whose captured length is smaller than its original length is truncated, and a reader has to expect a header that runs off the end of the bytes it was given rather than treat it as corruption. WIRE reports both numbers and reads a file that was cut off mid-packet up to the cut, and says that is what it did.
The five questions worth asking first
| Question | What answers it | What it tells you |
|---|---|---|
| Who talked to whom? | Conversations by bytes | The one flow that moved the data, and the direction it moved in |
| What was asked for? | DNS questions, HTTP Host, TLS server names | Destinations by name rather than by address |
| What went in the clear? | Cleartext protocols and credentials | What you now have to rotate |
| What is on a timer? | Regularity of connection attempts | Scheduled software, or something that wants to look like it |
| What is missing? | Snap length, truncation, failed lookups | Whether an absence of evidence means anything |
Who talked to whom
Group every packet by the pair of endpoints and add up the bytes. This is the single most useful view of a capture and it is almost always enough to find the thing you were sent the file for: in a capture of any size, a handful of conversations hold nearly all the volume, and the interesting one is usually either the biggest or conspicuously the wrong shape.
Direction matters as much as size. A workstation that received two megabytes from a content network downloaded something. A workstation that sent two megabytes to an address nobody recognises did something else. Look at the ratio, not just the total.
Addresses alone are misleading in both directions. A cloud IP tells you the hosting provider and nothing about the tenant, and the same address can serve a thousand unrelated names. That is what the next question is for.
What was asked for
Three places carry destinations as names, and all three are readable without decrypting anything:
- DNS questions and answers. Every lookup, who asked, and whether it resolved. Reading these properly means following name compression pointers, the scheme that lets a DNS message refer back to a name earlier in itself instead of repeating it — and a message can point at itself, so a reader needs a budget rather than a loop. Answers with
NXDOMAINare worth their own list: a long run of lookups for names that do not exist is what a domain generation algorithm looks like from the outside (DGA scores a list of names for exactly that), and it is also what a typo in a configuration file looks like — telling the two apart is a job of its own, and it is done on the resolver's log rather than on a capture. - The HTTP request line and headers. Method, target and
Host, where the traffic is plain HTTP. TheUser-Agentis worth reading too: software that identifies itself as a library rather than a browser is doing something a person did not click. - The server name in a TLS client hello. This is the useful one. The client hello is the first message of a TLS handshake and it is sent before any encryption is set up, so the Server Name Indication extension — the hostname the client is about to ask for — is in the clear in the capture. You cannot read the traffic and you can still see exactly where it went. Encrypted Client Hello closes this, and it is deployed rather than universal, so most captures still hand you the name.
Reading SNI reliably means walking the handshake field by field: record layer, handshake header, the fixed part of the client hello, then the variable-length session ID, cipher suites and compression methods, then the extension list, then the server name list inside the one extension you want. Searching the packet for something that looks like a hostname finds names in the wrong place and misses the ones that matter.
What went across in the clear
This is the part of a capture that creates work. Anything readable in the file was readable to everything between the two machines, so the finding is not "this was insecure" but "these specific secrets are now compromised and need rotating".
- HTTP basic authentication. An
Authorization: Basicheader is a username and password joined by a colon and base64-encoded. Base64 is not encryption and was never meant to be; it decodes with no key. - Session cookies over plain HTTP. A cookie in a cleartext request is a live credential for as long as the session lasts, which is often longer than the password.
- The protocols that say it in words. FTP and POP3 and IMAP and Telnet send
USERandPASSas text on their own lines. WIRE reads the command at the start of the payload rather than pattern-matching anywhere in the packet, so it reports a password where one was actually sent and not where the letters happen to appear. - Protocols carrying data readably even without a login. SMTP, LDAP, VNC, rsync, MySQL, PostgreSQL, MSSQL, and the
rcommands. Volume on any of these is worth a look even when no credential turns up, because the contents were in the clear too.
What is calling home on a timer
People are irregular. Software is not. A flow whose connection attempts arrive at almost the same interval every time is scheduled: an update checker, a monitoring agent, a mail client, a backup — or an implant, which looks identical from the outside because it is doing the same thing.
The measure that works is not the average gap, which one long pause ruins. It is the median gap, and how far the gaps sit from it as a fraction of it — the median absolute deviation over the median. WIRE calls a flow a timer when there are at least five gaps and that fraction is under a fifth, and BEACON does the same measure on a list of timestamps you already have, and it prints both numbers next to the answer, because a threshold you cannot see is not a finding you can argue with. Five is the floor because four points can line up by accident. A fifth is chosen so that a beacon carrying the jitter implants commonly add, ten or twenty per cent, is still caught, while somebody refreshing a page is not.
The finding is "this is on a timer", and it is the beginning of the work rather than the end of it. Name the destination, decide whether the software that owns it is meant to be there, and only then decide what you have.
What a browser cannot do
Being clear about this is the difference between a useful tool and a misleading one.
- No TCP stream reassembly. A request split across several segments is not read, so a large HTTP POST or a header that straddles a packet boundary is invisible to a per-packet reader. This is the biggest single limitation and it is why a clean report is not proof of a clean capture.
- No decryption. Not of TLS, not of SSH, not of a VPN, whatever keys you have. You get the outside of an encrypted flow: who, where, how much, when, and the name in the handshake — and CERTLENS will take the certificate apart if you have it separately.
- No live capture. A browser tab cannot put an interface into promiscuous mode. The capture has to be taken with something else first.
- No per-protocol dissection in depth. Ethernet with any depth of VLAN tag, Linux cooked capture v1 and v2, raw IP and BSD loopback; IPv4 and IPv6 with the extension header chain walked; TCP, UDP and ICMP; DNS, HTTP and TLS client hellos. That is a fraction of what Wireshark knows, and it is chosen to be the fraction that answers the first questions.
When you do need Wireshark
Install it when the question is about the contents rather than the shape of the traffic: following a stream end to end, decrypting TLS with a key log file, examining a protocol that needs a real dissector, working a retransmission or window problem, or carving a file out of a transfer. Those are the things a per-packet reader in a tab genuinely cannot do, and there is no shame in the first pass being the one that tells you whether the second pass is needed.
Taking the capture in the first place
If the file does not exist yet, these are the commands that make one a reader can trust. The important flag is the snap length: keep the whole packet unless you have a reason not to, because you cannot go back for the bytes you dropped.
# Linux or macOS: the whole of every packet, to a file
sudo tcpdump -i eth0 -s 0 -w capture.pcap
# One host only, which is usually what an investigation wants
sudo tcpdump -i any -s 0 -w capture.pcap host 10.0.0.42
# Long-running, in 100 MB pieces, keeping the last ten
sudo tcpdump -i eth0 -s 0 -w cap.pcap -C 100 -W 10
# Windows, with Wireshark installed but its window closed
dumpcap -i 1 -w capture.pcapng
Two habits worth keeping. Write the capture to a file rather than reading it on screen, so the analysis is repeatable and the file can be hashed. And record what the capture is of — which interface, which host, which clock, what was happening — because a capture with no provenance answers questions about itself before it answers any about the network.
Handling the file afterwards
A capture is one of the most sensitive files an organisation produces: credentials, cookies, internal names, personal data, and a minute-by-minute record of who did what. Treat it accordingly. Hash it when you receive it and keep the hash with it, so what you analysed can be shown to be what you were sent — ATTEST and CUSTODY do that part. Redact before you paste an excerpt into a ticket; INTERCEPT takes secrets out of a network log or a curl command. And do not run it through a website that uploads it, which is the whole reason WIRE reads it in the tab.
Questions people ask about reading a packet capture
Related tools
- WIRERead a packet capture in this tab, without uploading it
- BEACONFind what is calling home on a timer
- DGAFind generated domain names in a DNS log
- INTERCEPTClean secrets out of a network log or curl command
- CERTLENSTake a certificate or a chain apart and check it
- Is it safe to upload this?What a website keeps when you hand it a file