Description
Something is tucked away inside a JPEG image. The title is a hint: the clue to extracting it is hiding in plain sight, right in the file's own metadata.
Setup
Download the JPG file from the challenge page.
Install exiftool and steghide: sudo apt install libimage-exiftool-perl steghide
sudo apt install libimage-exiftool-perl steghideSolution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1Run exiftool to inspect the image metadata
ObservationThe title says the clue hides in plain sight inside the file. That points at the image's metadata fields rather than its pixel data, so exiftool is the natural first tool.Run exiftool on the downloaded image and look at the Comment field. Instead of a flag, you will find a base64-encoded string: c3RlZ2hpZGU6Y0VGNmVuZHZjbVE9. That string is the first clue.bashexiftool img.jpgWhat didn't work first
Tried: Opening the image in a hex editor or viewer to search for hidden text manually
Hex editors show raw bytes and viewers render pixels, but the EXIF Comment sits in a structured binary segment near the start of the JPEG that is easy to miss without a parser. exiftool walks the Image File Directory and labels every field, so the Comment appears named rather than buried in a wall of bytes.
Tried: Running strings on the image file to find the base64 comment
strings does show the base64 comment, but alongside dozens of other sequences from the JPEG header, ICC profile, and thumbnail data, so picking out the meaningful one is guesswork. exiftool labels the field as Comment, which leaves no ambiguity about what to decode.
Learn more
EXIF (Exchangeable Image File Format) is a standard for embedding structured metadata inside image files. Tags cover camera model, lens settings, GPS coordinates, timestamps, and a free-form
Commentfield that can hold arbitrary text.exiftoolby Phil Harvey reads every known metadata standard (EXIF, XMP, IPTC) across over 200 file formats and prints them as key-value pairs.The
Commentfield is completely free-form, making it a natural hiding spot in forensics challenges. In this case it holds a base64 string rather than the flag itself, which sets up the next layer of the puzzle.exiftool -Comment img.jpg- show only the Comment fieldexiftool -all= img.jpg- strip all metadata in place
Step 2Double-decode the base64 comment to get the steghide passphrase
ObservationThe exiftool Comment field holds c3RlZ2hpZGU6Y0VGNmVuZHZjbVE9, which is padded base64. Decoding once gives steghide:cEF6endvcmQ=, whose suffix is base64 again, so a second decode recovers the real passphrase.Decode the comment string once: you getsteghide:cEF6endvcmQ=. The prefixsteghide:names the tool to use; the suffixcEF6endvcmQ=is another base64 string. Decode that second string to reveal the passphrase:pAzzword.bashecho "c3RlZ2hpZGU6Y0VGNmVuZHZjbVE9" | base64 -dbashecho "cEF6endvcmQ=" | base64 -dWhat didn't work first
Tried: Using the raw first-decode output steghide:cEF6endvcmQ= as the steghide passphrase directly
Passing the whole string, colon and second base64 blob included, makes steghide fail, because the passphrase is only the decoded value of that second segment. The colon is a delimiter between tool name and encoded passphrase, not part of the secret.
Tried: Trying base64 -d on the original comment string and stopping after a single decode
One decode gives steghide:cEF6endvcmQ=, which looks like an answer but is still partly encoded. Treat cEF6endvcmQ= as the passphrase and steghide rejects it. Decode that suffix a second time to get the real passphrase, pAzzword.
Learn more
Base64 encodes arbitrary binary data as printable ASCII characters, making it safe to embed in text fields like EXIF comments. Double encoding (base64 of base64) is a common trick in CTF challenges to add an extra layer of obfuscation. The first decode reveals the tool name and a second encoded blob; the second decode yields the actual passphrase.
The naming convention
tool:encodedPassphrasein the first decoded string is the challenge author giving you everything you need in one place: the tool to use and the secret to unlock it, separated by a colon.Step 3Extract the hidden file with steghide
ObservationThe first decode names the tool outright, in the form steghide:encodedPassphrase, and the second gives the passphrase pAzzword. That points straight at running steghide extract on the JPEG.Runsteghide extractwith the passphrasepAzzword. Steghide will write a file calledflag.txtto the current directory. Read that file to get the flag.bashsteghide extract -sf img.jpg -p pAzzwordbashcat flag.txtExpected output
picoCTF{h1dd3n_1n_1m4g3_...}What didn't work first
Tried: Running steghide extract without the -p flag and entering pAzzword at the interactive prompt but mis-capitalizing it
Steghide passphrases are case-sensitive. Typing pazzword or Pazzword instead of pAzzword causes a passphrase error and no output file is written. The exact mixed-case string pAzzword must be used, which is why decoding the base64 precisely rather than guessing is essential.
Tried: Using stegsolve or zsteg instead of steghide to extract the hidden data
Stegsolve and zsteg target LSB steganography in PNG bit planes and know nothing about steghide's DCT-coefficient embedding in JPEGs, so they report no data or emit garbage. The decoded EXIF comment names steghide explicitly, so extract with steghide, the -sf flag, and the recovered passphrase.
Learn more
Steghide is a steganography tool that conceals data by modifying the least-significant bits of a JPEG's DCT coefficients, the frequency-domain numbers that encode the image. The change is mathematically small and visually undetectable to the human eye, but the hidden bytes are perfectly recoverable with the correct passphrase. This is true steganography: the data is hidden inside the image content, not just in metadata.
The challenge title "hidden in plainsight" points to both layers: the passphrase is hiding in plain sight in the EXIF comment (if you know to look and decode it), while the flag itself is hidden inside the image using steghide.
steghide --info img.jpg- check whether steghide data is present without extractingsteghide extract -sf img.jpg- extract interactively (prompts for passphrase)steghide extract -sf img.jpg -p pAzzword- extract non-interactively with the passphrase
Interactive tools
- StegallDrop any file and Stegall runs every applicable steg technique in parallel: LSB sweeps, bit planes, spectrograms, polyglot carving, metadata, whitespace decode, and a 6-layer base/ROT/XOR/zlib cascade. Recursively unpacks results and surfaces flag matches.
- Hex ViewerView text or raw hex bytes as a xxd-style hex dump with byte offset, hex columns, and ASCII sidebar. Highlights printable characters and null bytes.
- Strings ExtractorPull printable text from any binary, library, or image. ASCII and UTF-16 detection, configurable minimum length, flag-like highlight, no command line needed.
Flag
Reveal flag
picoCTF{h1dd3n_1n_1m4g3_...}
The hash suffix in the flag is unique per challenge instance, so your flag will differ from others. The format is picoCTF{h1dd3n_1n_1m4g3_<hash>}.