Description
Figure out how they are communicating, then find the flag. Download tftp.pcapng.
Setup
wget <url>/tftp.pcapngSolution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1Export all TFTP objects from the capture
ObservationThe capture is named tftp.pcapng, and TFTP moves files in plaintext over UDP. So every transferred file is recoverable straight out of the capture with Wireshark's Export Objects.Open tftp.pcapng in Wireshark, then File > Export Objects > TFTP. You'll recover instructions.txt, plan, picture1.bmp, picture2.bmp, picture3.bmp, and program.deb.bashwireshark tftp.pcapngWhat didn't work first
Tried: Trying to extract files with tcpdump or tshark -r tftp.pcapng -x instead of Wireshark's Export Objects menu
tshark -x prints raw per-packet hex, not reassembled payloads, and TFTP splits its DATA blocks across many UDP frames, so you get fragments rather than files. Wireshark's Export Objects for TFTP follows the DATA block sequence numbers and reassembles each transfer for you.
Tried: Filtering for HTTP or TCP streams in Wireshark expecting to find transferred files there
TFTP runs over UDP port 69, so TCP stream reassembly finds nothing at all. Export Objects works only with TFTP selected from the protocol list; the HTTP entry comes back empty. Check the Protocol column: frames labeled TFTP under UDP confirm you are in the right place.
Learn more
TFTP packet primer. TFTP runs over UDP/69 with a tiny opcode-driven format:
- 1 = RRQ (read request):
opcode | filename\0 | mode\0 - 2 = WRQ (write request): same shape as RRQ
- 3 = DATA:
opcode | block# | up to 512 bytes - 4 = ACK:
opcode | block# - 5 = ERROR:
opcode | errcode | message\0
Filename and mode in RRQ/WRQ are NUL-terminated ASCII strings. Because everything is plaintext, Wireshark's Export Objects walks the DATA blocks and reassembles complete files. See Wireshark for CTF for the broader protocol-analysis playbook.
- 1 = RRQ (read request):
Step 2Decode the text files with ROT13
Observationinstructions.txt and plan hold text with recognizable English word shapes but uniformly shifted letters, which is the mark of a letter substitution. ROT13 is the obvious first try, being the common self-inverse shift on a 26-letter alphabet.instructions.txt and plan are ROT13. Decode them to learn the steg tool (steghide) and the passphrase. Look for the passphrase on a clearly-marked line: often the last line of the file or a label like 'password:' or 'passphrase:'.bashtr 'A-Za-z' 'N-ZA-Mn-za-m' < instructions.txtbashtr 'A-Za-z' 'N-ZA-Mn-za-m' < planWhat didn't work first
Tried: Trying caesar cipher with a different shift (ROT7, ROT18) because the first few words still look garbled
ROT13 is a shift of 13 and its own inverse, so one application decodes the message completely. If the output still looks garbled, the usual cause is running tr against the wrong file, or misreading a filename from the Wireshark export. Check the exact names Export Objects produced; they are case-sensitive.
Tried: Using base64 -d or xxd to decode the text files instead of ROT13
Base64 output uses only alphanumerics along with the plus, slash, and equals characters, and shows no English word shapes however you shift it. These files carry recognizable but shifted words, HFRQ decoding to USED, which is the signature of a letter substitution rather than base64.
Step 3Extract the hidden data from picture3.bmp
ObservationThe decoded plan names steghide as the tool, picture3.bmp as the carrier, and DUEDILIGENCE as the passphrase. That is everything needed to run steghide extract against that one image.Use steghide on picture3.bmp with the recovered passphrase (DUEDILIGENCE in the canonical solve). The output file contains the flag.bashsteghide extract -sf picture3.bmp -p DUEDILIGENCEbashcat flag.txtExpected output
picoCTF{h1dd3n_1n_pLa1n_51GHT_...}What didn't work first
Tried: Running steghide extract on picture1.bmp or picture2.bmp with the recovered passphrase instead of picture3.bmp
steghide reports no extractable data, or a capacity or checksum error, on any carrier with no payload in it. Only picture3.bmp holds hidden data, and the decoded plan names the third image explicitly. Re-read the decoded output to confirm which file it points at.
Tried: Trying zsteg or binwalk on the .bmp files instead of steghide, because those are common stego tools
zsteg reads PNG and BMP LSB planes and knows nothing about steghide's format, which alters pixel colour values in the spatial domain and encrypts the payload with AES keyed by the passphrase. zsteg shows random-looking LSB data rather than the flag. The decoded instructions name steghide, so passphrase-based extraction with steghide -sf is the path.
Learn more
Steghide hides data inside image and audio carriers by tweaking pixel/sample values; the payload is encrypted with a passphrase.
-sfselects the stego file and-ppasses the passphrase. See steganography tools for the broader toolkit (zsteg for PNG LSB, binwalk for embedded archives, stegsolve for visual bit planes).This challenge chains TFTP recovery, ROT13 decoding, and steghide extraction. Each clue is hidden in the previous step's output, a common multi-stage pattern in forensics CTFs.
Interactive tools
- Password Steg (Encrypt & Decrypt)Password-protect a message with AES-GCM and PBKDF2-derived keys. Encode produces a base64 ciphertext you can hide in any carrier; decode recovers the original with the same password. Runs entirely in the browser.
Flag
Reveal flag
picoCTF{h1dd3n_1n_pLa1n_51GHT_...}
TFTP transfers files without encryption: export all objects from the capture, decode the ROT13 instructions to recover the steghide passphrase, and pull the flag out of picture3.bmp.