Introduction
Network forensics challenges give you a packet capture file (usually a .pcap or .pcapng file) recorded from a real or simulated network. Your job is to find the flag hidden somewhere inside the traffic: in a plaintext HTTP response, embedded in a file transferred over FTP, encoded in DNS queries, or smuggled inside a protocol you wouldn't normally suspect.
Wireshark is the standard tool for this work. It parses and dissects hundreds of protocols, lets you reconstruct TCP streams as readable text, and can export files from network transfers. This guide covers the skills needed for challenges like Packets Primer, Eavesdrop, Wireshark doo dooo do doo, Wireshark twoo twooo two twoo, pcap poisoning, and shark on wire 1.
Opening a pcap file
Install Wireshark on Ubuntu or Debian:
sudo apt install wireshark
Open a capture file from the command line or via File → Open:
wireshark challenge.pcap
Wireshark also accepts compressed files (.pcap.gz) and the newer .pcapng format that supports multiple interfaces and packet comments.
strings challenge.pcap | grep -i 'picoctf\|flag' from the terminal. A surprising number of beginner challenges have the flag sitting in plaintext and this finds it in under a second.The Wireshark interface
The Wireshark window has three main panes:
- Packet list (top): one row per packet, showing number, timestamp, source, destination, protocol, and a summary.
- Packet details (middle): the dissected protocol tree for the selected packet. Click any row to expand it.
- Packet bytes (bottom): the raw hex and ASCII representation. Selecting a field in the details pane highlights the corresponding bytes here.
The display filter bar at the top is where you type filters to hide irrelevant packets. Press Enter or the arrow button to apply. The bar turns red for an invalid filter and green for a valid one.
Following TCP/UDP streams
Reconstructing a complete conversation from individual packets is the most useful forensics operation. Right-click any packet in a TCP flow and choose Follow → TCP Stream. Wireshark reassembles all the packets in that flow into a single readable window, with client data in red and server data in blue.
This instantly shows you the full HTTP request and response, an FTP data transfer, or a shell session. Many CTF flags are directly visible as plaintext in a stream view.
At the bottom of the stream window you can switch the display to:
- ASCII: printable characters (default)
- Hex Dump: raw bytes alongside ASCII
- Raw: the raw byte stream, useful for saving binary data
For UDP flows, use Follow → UDP Stream. For DNS challenges use Statistics → DNS or filter on dns and examine individual query names in the packet detail tree.
Display filters
Display filters narrow the packet list to only the packets you care about. Wireshark uses its own filter language (not Berkeley Packet Filter). Some essential filters:
| Filter | What it matches |
|---|---|
| http | All HTTP traffic |
| tcp.port == 4444 | Traffic on a specific port |
| ip.addr == 10.0.0.5 | Traffic to or from a specific IP |
| http.request.method == "POST" | HTTP POST requests only |
| ftp-data | FTP data transfers (the actual file contents) |
| dns | All DNS queries and responses |
| tcp contains "picoCTF" | TCP packets whose payload includes that string |
| frame contains "flag" | Any packet containing the word flag |
| http.response.code == 200 | Successful HTTP responses |
| !(arp || dns) | Hide ARP and DNS noise |
| icmp | ICMP packets (ping, potential covert channel) |
tcp contains "picoCTF{" as a quick flag search. The braces are safe because they appear in the middle of the string, not as filter syntax.Finding credentials
Plaintext protocols like HTTP (not HTTPS), FTP, Telnet, and POP3 transmit usernames and passwords in the clear. Wireshark can extract them automatically:
Go to Tools → Credentials. Wireshark scans the capture for known credential patterns across dozens of protocols and lists them in a separate window with the packet number, protocol, username, and password.
For HTTP Basic Auth, filter to http.authbasic and read the Authorization header. The value is Base64-encoded; decode it to recover username:password.
# Decode HTTP Basic Auth from the terminalecho 'dXNlcjpwYXNz' | base64 -d# user:pass
Extracting files from captures
Files transferred over HTTP, FTP, SMB, or TFTP are reconstructed by Wireshark automatically. Go to File → Export Objects and choose the protocol. Wireshark lists every transferred file with its filename and size. Save the ones you want to disk.
For protocols not in the Export Objects menu, follow the TCP stream, switch the view to Raw, then click Save As to write the raw bytes to a file.
file on any extracted binary to check its true type. The transferred data might be a ZIP, PNG, or PDF that was stored with a misleading extension.tshark on the command line
tshark is the command-line version of Wireshark. It is invaluable when you want to grep, pipe, or script analysis of a large capture without a GUI.
# List all HTTP requeststshark -r capture.pcap -Y 'http.request' -T fields \-e ip.src -e http.request.method -e http.request.uri# Print every DNS query nametshark -r capture.pcap -Y 'dns.qry.name' -T fields -e dns.qry.name# Follow TCP stream 0 and print as ASCIItshark -r capture.pcap -q -z follow,tcp,ascii,0# Extract all HTTP objects to a foldertshark -r capture.pcap --export-objects http,/tmp/exported_files# Search for the flag in any packet payloadstrings capture.pcap | grep 'picoCTF'
strings trick works surprisingly often. Before doing any analysis, run it first to see if the flag is sitting in plaintext.TLS and encrypted traffic
HTTPS traffic is encrypted, so you cannot read the payload directly. However, TLS connections still expose useful metadata in the handshake, and some CTF setups give you a key log file to decrypt everything.
Extracting metadata without decryption
The TLS ClientHello packet is sent in the clear and contains the Server Name Indication (SNI), which reveals which hostname the client was connecting to. This is often enough to identify the suspicious connection in a capture.
# Extract all SNI values (server names) from TLS handshakes:tshark -r cap.pcap -Y 'tls.handshake.type == 1' \-T fields -e tls.handshake.extensions_server_name# Extract certificate Common Names from the capture:tshark -r cap.pcap -Y 'x509sat.printableString' \-T fields -e x509sat.printableString | sort -u# Wireshark filter to isolate TLS traffic to a specific domain:tls.handshake.extensions_server_name == "suspicious.attacker.com"
Decrypting TLS with a key log file
Some challenges provide a SSLKEYLOGFILE (a file containing TLS session keys logged by the browser or client). If you have one, Wireshark can decrypt the entire TLS session:
# In Wireshark:Edit -> Preferences -> Protocols -> TLS-> (Pre)-Master-Secret log filename: browse to the .log file# Wireshark will now show decrypted HTTP/2 or HTTP traffic inside the TLS streams.# With tshark:tshark -r cap.pcap -o 'tls.keylog_file:/path/to/sslkeys.log' \-Y 'http' -T fields -e http.request.uri -e http.file_data
CLIENT_RANDOM line records the session master secret keyed by the client random, so Wireshark can decrypt any TLS 1.2 session it covers, including static RSA and forward-secret (ECDHE/DHE) key exchanges alike. The server private key (Edit → Preferences → Protocols → TLS → RSA keys list) is the fallback for when you have no key log: it only works against non-PFS static RSA key exchange and cannot decrypt ECDHE/DHE traffic, because with forward secrecy the private key never derives the session keys.ICMP covert channels
ICMP (ping) packets should have a small, fixed payload. When you see ICMP packets with unusually large or non-standard payloads, the data may be a covert channel carrying the flag.
# Filter to ICMP packets with data payloads:icmp# With tshark, extract each ICMP payload as hex:tshark -r cap.pcap -Y icmp -T fields -e data.data# Concatenate and decode:tshark -r cap.pcap -Y icmp -T fields -e data.data | tr -d '\n' | xxd -r -p
Common CTF patterns
Flag in HTTP response body
The most common beginner pattern. Filter to http, follow the stream of a suspicious request, and read the response. The flag may be in the HTML body, a JSON field, or a custom header. Used in Packets Primer and Wireshark doo dooo do doo.
Flag in DNS exfiltration
Flags are sometimes encoded as subdomain labels in DNS queries, e.g. cGljb0NURg.attacker.com. The data is split across multiple queries, each carrying one chunk as a subdomain label. To reconstruct:
# 1. Extract all unique query names:tshark -r cap.pcap -Y dns.qry.name -T fields -e dns.qry.name | sort -u# 2. Strip the common parent domain and sort by order (often a sequence number prefix):# Example queries: 01-cGljb0N.exfil.com 02-RGSB5Y3Q.exfil.com 03-dGZ7ZG5z.exfil.com# 3. In Python: extract, join, and decode:import base64chunks = ['cGljb0N', 'RGSB5Y3Q', 'dGZ7ZG5z'] # extracted labels in ordercombined = ''.join(chunks)# Fix base64 padding:combined += '=' * (4 - len(combined) % 4)print(base64.b64decode(combined))
Exfiltration channels frequently stack base32 or hex inside a base64 outer layer. Paste the concatenated result into Recipe Chain and run Magic to peel apart nested encodings automatically. Used in Wireshark twoo twooo two twoo.
Credentials used as the flag
Some challenges are solved by finding a username or password that is itself the flag, or leads to a service where the flag lives. Use Tools → Credentials or filter to the relevant plaintext protocol. Used in Eavesdrop.
Modified or injected packets
In pcap poisoning, extra packets have been injected into a legitimate capture. Look for packets that break the normal conversation flow (out-of-sequence TCP, responses with no matching request, packets from unexpected source IPs) and inspect their payloads directly.
Unusual protocol
Check Statistics → Protocol Hierarchy. If you see an unexpected protocol like ICMP with large payloads, raw TCP on a non-standard port, or an unrecognized stream, that is usually the carrier for the hidden data. Used in shark on wire 1 and shark on wire 2.
Quick reference
| Filter | What it matches |
|---|---|
| Follow TCP Stream | Right-click packet -> Follow -> TCP Stream |
| Export HTTP files | File -> Export Objects -> HTTP |
| Find credentials | Tools -> Credentials |
| Protocol breakdown | Statistics -> Protocol Hierarchy |
| Conversation stats | Statistics -> Conversations |
| strings + grep | strings capture.pcap | grep picoCTF |
| tshark fields | tshark -r cap.pcap -Y 'filter' -T fields -e field.name |
| Decrypt TLS | Edit -> Preferences -> TLS -> key log file |
| Export all HTTP objects | tshark -r cap.pcap --export-objects http,/tmp/out |
Practice with: Packets Primer, Eavesdrop, Wireshark doo dooo do doo, Wireshark twoo twooo two twoo, pcap poisoning, shark on wire 1.