Skip to main content

Ph4nt0m 1ntrud3r picoCTF 2025 Solution

Analyze a network capture to locate and reassemble data that was quietly exfiltrated across multiple packets.

Published: April 2, 2025Updated: August 25, 2026

Description

A "digital ghost" exfiltrated data through a small capture file. Sort the packets chronologically, reassemble the attacker's Base64 blobs, and decode them to reveal the stolen message.

Grab the PCAP and run capinfos to see capture duration and packet count.

Open it in Wireshark (or pull TCP payloads with tshark). Sort by time so you can read the exfiltration stream in order.

bash
wget https://challenge-files.picoctf.net/c_verbal_sleep/4d25aca04e2409ba0d917d8ed27d49c6fb616ff9603fa3926712cce623a3d7f5/myNetworkTraffic.pcap
bash
capinfos myNetworkTraffic.pcap
bash
tshark -r myNetworkTraffic.pcap -Y tcp -T fields -e frame.number -e frame.time_epoch -e tcp.payload

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
PCAP triage techniques (Follow TCP Stream, payload extraction with tshark) live in the Wireshark and PCAP guide, and the Base64 reassembly is one of the canonical recipes in the CTF Encodings cheatsheet.
  1. Step 1Identify the suspicious payloads
    Observation
    The TCP payloads hold small ASCII strings ending in == padding, which is Base64. The attacker fragmented the stolen data and encoded each piece before sending it.
    The capture contains TCP segments whose data fields are tiny Base64 strings ending with == padding. Print frame numbers + payloads with tshark; the packets are captured out of chronological order, so you must sort by the epoch timestamp column to reconstruct the correct sequence. The sorted order (by frame.time_epoch ascending) is: packets 9, 21, 17, 15, 20, 13, 8. Note: zsteg is for image steganography, not pcaps - do not reach for it here.
    bash
    # Print frame number, timestamp, payload for the chunked TCP flow:
    tshark -r myNetworkTraffic.pcap -Y 'tcp.port == <PORT>' \
      -T fields -e frame.number -e frame.time_epoch -e tcp.payload
    # Packets are out of chronological order; sort the output by the timestamp column to get the correct sequence.

    Expected output

    picoCTF{1t_w4snt_th4t_34sy_tbh_4r_...}
    What didn't work first

    Tried: Sort the tshark output by frame.number instead of frame.time_epoch to get the exfiltration sequence.

    Frame numbers record capture order on disk, not the order the packets were sent. These arrived out of order, so sorting by frame number jumbles the sequence and the concatenated Base64 decodes to garbage. Sort by timestamp instead, which recovers the real order: 9, 21, 17, 15, 20, 13, 8.

    Tried: Use tshark without a display filter, printing all TCP payloads, to locate the Base64 chunks.

    Without a filter, the output includes handshake and ACK packets with empty payloads, whose blank lines break the concatenation and hide which frames carry data. Filter on tcp.payload, or on the destination port, to keep only the frames with bytes in them.

    Learn more

    PCAP (Packet Capture) files store raw network traffic recorded by tools like tcpdump, Wireshark, or network taps. The PCAP format stores each packet with a precise timestamp, enabling chronological reconstruction of conversations. PCAP analysis is a core skill in network forensics, incident response, and network-based CTF challenges.

    Data exfiltration via TCP payload is one of the simplest covert channel techniques. An attacker who has compromised a host can embed stolen data in the payloads of outbound TCP connections, sometimes disguised as legitimate traffic. Fragmenting the data into small chunks (as here, with individual Base64 segments) mimics the behavior of keep-alive packets or protocol handshakes and can evade simple size-based anomaly detection.

    Real-world exfiltration is often more sophisticated: data can be hidden in DNS query names (DNS tunneling), ICMP echo request payloads, HTTP User-Agent headers, or timing intervals between packets (covert timing channels). Tools like dnscat2 and iodine automate DNS-based exfiltration. Network detection tools like Zeek and Suricata include signatures for many of these patterns.

  2. Step 2Concatenate in order and decode
    Observation
    Decoded on its own, each chunk gives only a fragment: one yields 'picoCTF' and nothing more. Concatenate all the Base64 first, then decode once.
    Canonical workflow here is manual extraction with tshark, because it makes the ordering explicit. Copy the cGljb0NURg==, ezF0X3c0cw==, ... fQ== strings in chronological order, concatenate, and pipe through base64 -d. The output starts with picoCTF{; if it doesn't, the packet order is wrong, so re-sort and try again. Wireshark's Follow TCP Stream is the GUI alternate - same data, just reassembled for you.
    bash
    # Concatenate the chunks (no newlines) and decode:
    bash
    printf '%s' 'cGljb0NURg==ezF0X3c0cw==bnRfdGg0dA==XzM0c3lfdA==YmhfNHJfOA==ZTEwZTgzOQ==fQ==' | base64 -d
    bash
    # One segment per line works too if you prefer:
    bash
    printf 'cGljb0NURg==\nezF0X3c0cw==\nbnRfdGg0dA==\nXzM0c3lfdA==\nYmhfNHJfOA==\nZTEwZTgzOQ==\nfQ==\n' | base64 -d
    bash
    # Expected: a string starting with picoCTF{
    What didn't work first

    Tried: Pipe the raw hex payload bytes directly from tshark into base64 -d without converting them to ASCII first.

    tshark prints the payload as hex, not as the Base64 text the attacker sent. Pipe that hex into a Base64 decoder and it treats the hex digits as Base64 characters, giving binary garbage. Convert the hex to ASCII first, with xxd -r -p or bytes.fromhex, and decode what comes out.

    Tried: Paste the concatenated Base64 into a strict decoder such as Python's base64.b64decode or a CyberChef 'From Base64' recipe.

    Each chunk carries its own == padding, so the joined string is seven separate Base64 messages rather than one. A strict decoder ignores the interior padding and keeps packing 6-bit groups across the boundary, which produces picoCTF followed by binary garbage. GNU base64 -d restarts at each pad and prints the whole flag; if your decoder does not, decode the chunks one at a time and join the plaintext instead.

    Learn more

    Packet ordering matters critically in network forensics. PCAP files record packets in the order they were captured, which usually reflects network arrival order, but TCP guarantees in-order delivery from the application's perspective. When packets are out of capture order (due to network reordering or parallel paths), a real TCP stream is reassembled by sequence number rather than by file order. In this crafted capture the intended order is the one the timestamps describe, which is why sorting on frame.time_epoch is what recovers it here.

    Wireshark's Follow TCP Stream feature (right-click a packet, Follow, TCP Stream) automatically reassembles a complete TCP conversation in sequence-number order, handles retransmissions, and presents the payload as continuous text or hex. This is usually the fastest way to extract application-layer data from a PCAP, and it is the recommended alternate workflow if the manual tshark approach above feels fiddly. For UDP-based challenges, Follow UDP Stream works similarly but without reassembly guarantees.

    Base64 is an encoding scheme, not encryption. It maps arbitrary binary data to a 64-character alphabet (A-Z, a-z, 0-9, +, /) plus = padding, and increases size by about 33%. The fact that the attacker used Base64 rather than encryption reveals a fundamental mistake: encoding is reversible by anyone without a key. Sophisticated exfiltration would encrypt the data with a key the attacker controls before encoding, which is exactly what command-and-control frameworks like Cobalt Strike and Metasploit do by default. CyberChef (the GCHQ-developed web tool) is exceptionally useful for chaining decoders if you need more than one transformation in sequence.

Interactive tools
  • File Magic IdentifierIdentify file types from magic numbers. Paste hex bytes or drop a file to detect PNG, JPEG, ZIP, PDF, ELF, PCAP, SQLite, and dozens of other formats.
  • Image Metadata ViewerRead EXIF, XMP, JPEG comments, and PNG tEXt / iTXt / zTXt chunks from images entirely in the browser. Highlights flag-like values.

Flag

Reveal flag

picoCTF{1t_w4snt_th4t_34sy_tbh_4r_8e...}

If you use Wireshark, the Follow TCP Stream view also displays the Base64 segments in order once you pick the first packet.

Key takeaway

A packet capture preserves the raw bytes of every connection, so a cleartext protocol leaves a complete record of whatever an attacker took. Chunking the data into small Base64 segments spreads it across packets without hiding anything, since the encoding reverses without a key. DNS tunneling, ICMP covert channels, and HTTP exfiltration all yield to the same workflow: reassemble the stream in order, identify the encoding, decode.

Related reading

Tools used in this challenge

Where to go next