Learn · Network forensics

Packets & pcap

A packet capture is the closest thing the network has to a disk image: the bytes as they crossed one wire, with a time stamp each. Here is how a capture file is built, and how to read a packet layer by layer.

1 Where captures come from

A capture only contains what passed the capture point. Three common ones:

Intrusion detection systems often keep a ring buffer of recent traffic and write it out when a rule fires. Such captures are short, and they may keep only the first part of each flow. Write down the capture point, the time range and any limits (snap length, per-flow caps, drops) together with the file's hash.

Capture filter vs display filter: a capture filter (BPF, e.g. host 192.0.2.80 and tcp port 80) decides what is written; what it drops is gone. A display filter (Wireshark, e.g. ip.addr==192.0.2.80 && http) only hides packets on screen. In a case, capture wide and filter on display.

2 The pcap file

The classic pcap format is simple: a 24-byte global header, then for every packet a 16-byte record header followed by the packet bytes. The header fields are written in the byte order of the machine that captured, so the magic number tells you how to read the rest. The packet bytes themselves are in network byte order (big-endian).

Each record header holds the time (seconds since 1970 in UTC plus micro- or nanoseconds), the captured length and the original length. If the capture kept only the start of a packet, the captured length is smaller. The packet below was cut to 128 bytes; the decoder still reads the headers, but the payload is mostly missing and the TCP checksum cannot be checked.

What tcpdump says about this capture

3 One packet, four layers

Each layer's header says what comes next: the Ethernet EtherType 08 00 means IPv4, the IP protocol byte 6 means TCP, and the TCP ports hint at the application. This is the first packet of a TCP connection (SYN) from a client to a web server:

pcap record16 bytes
Ethernet14 bytes: MACs, type
IPv420+ bytes: addresses, TTL, protocol
TCP20–60 bytes: ports, seq/ack, flags
PayloadHTTP, TLS, …

Details that matter in investigations:

Not everything is IP. ARP asks "who has 192.168.56.1?" so the client can learn its gateway's MAC. ARP replies are useful evidence that a device with a given MAC and IP was on the local network at that moment.

4 pcapng

Wireshark saves pcapng by default. It is a sequence of blocks, each with a type, a length at the start and the same length again at the end. A Section Header Block starts the file and fixes the byte order; Interface Description Blocks describe each capture interface; Enhanced Packet Blocks hold the packets. Blocks can carry options such as comments, the interface name or the capturing OS, which are worth noting in a report.

The time stamp in the EPB is one 64-bit number split into a high and a low 32-bit half. This packet is the same DNS query as the one at 09:30:00.200000 in the pcap file above. editcap -F pcap in.pcapng out.pcap converts between the formats (the options are lost).

5 Pitfalls

6 Try it yourself

Answer from the hex views above. Numbers can be typed in decimal or hex (0x…).

What is the snap length of the capture, in bytes?

Global header offset 16, four bytes, in the byte order the magic number tells you.

Bytes 16–19: 00 00 04 00, little-endian = 0x00040000 = 262,144. That is tcpdump's default: in practice, no packet is cut by the snap length here. The truncated packet was cut by the sensor's own rule, not by the snap length.

How many bytes of the truncated packet were not captured?

Record header: captured length at +8, original length at +12.

Captured 80 00 00 00 = 128, original C0 05 00 00 = 1,472. 1,472 − 128 = 1,344 bytes are missing.

Which two bytes hold the client's source port in the SYN packet? Type them in file order.

The TCP header starts right after the 20-byte IPv4 header; the source port is its first field.

TCP header at record offset +32: C9 3A = 51,514 (big-endian), an ephemeral port chosen by the client. The next two bytes, 00 50, are the destination port 80.

The web server's reply arrives with TTL 52. Which start value, and so which kind of system, is most likely?

Internet paths rarely have more than about 30 hops.

64 − 12 = 52. 76 or 203 hops are unrealistic. The TTL is a hint, not proof: the start value can be configured, and middleboxes may rewrite it.

These are the 24 bytes of the global header. Edit them and watch the decoded header:

  • Change the magic number to A1 B2 C3 D4. The decoder now reads the file as big-endian. What happens to the version and the snap length?
  • Reset, then change the link type (offset 20) from 01 to 71 (113). What would a tool now expect at the start of every packet?