Information picoCTF 2021 Solution

Published: April 2, 2026

Description

Files can always be changed in a secret way. Can you find the flag in the cat.jpg file?

Download cat.jpg.

bash
wget <url>/cat.jpg

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1
    Inspect the EXIF metadata
    Observation
    I noticed the challenge description said the file 'can always be changed in a secret way' and provided a JPEG image, which suggested hidden data in the file's metadata rather than in the visible pixels, pointing directly to EXIF inspection with exiftool.
    Run exiftool on cat.jpg to dump all metadata fields. Look through the output for any field containing a base64-encoded string. The License field contains the encoded flag.
    bash
    exiftool cat.jpg
    What didn't work first

    Tried: Run strings cat.jpg and grep the output for picoCTF

    strings only extracts printable ASCII sequences from raw bytes. EXIF metadata is stored in a structured binary IFD (Image File Directory) format, so the License field value may appear as raw bytes rather than a clean ASCII run that strings would capture cleanly. More importantly, the flag is base64-encoded inside the field, so even if strings catches it you still see an encoded string with no picoCTF prefix to grep for. exiftool parses the IFD structure and labels each field by name, making the License field immediately visible.

    Tried: Open cat.jpg in a hex editor and search manually for base64-looking text

    While the EXIF data is technically present in the file's bytes, EXIF IFDs have variable offsets, nested pointer chains, and may use UTF-16 encoding for some fields, making manual hex navigation error-prone and slow. exiftool resolves all offsets and decodes field encodings automatically. Manual hex inspection risks misidentifying the field or missing it entirely if the value is stored as a UTF-16 Unicode string rather than plain ASCII.

    Learn more

    EXIF (Exchangeable Image File Format) is a standard for storing metadata in JPEG, PNG, TIFF, and other image files. It was originally designed for camera settings - shutter speed, aperture, GPS coordinates - but any field can hold arbitrary text. Common fields include Make, Model, DateTime, Artist, Copyright, and Comment. Less-read fields like License, UserComment, or custom XMP properties are easy hiding spots.

    exiftool by Phil Harvey is the de-facto standard for reading and writing EXIF data. It supports over 200 file formats. For CTF forensics, always run exiftool as a first step on any downloaded image.

    Privacy risks of EXIF data: By default, smartphones embed GPS coordinates, device model, and serial numbers into every photo. Sharing an unstripped photo online can reveal your precise home location. Journalists, activists, and security researchers routinely strip EXIF data before publishing images. Tools like exiftool -all= image.jpg remove all metadata in place. Social media platforms like Facebook and Twitter strip EXIF on upload, but many file-sharing sites and email attachments do not.

    EXIF fields commonly used in CTF steganography: Beyond the standard camera fields, useful hiding spots include Comment, UserComment, Artist, Copyright, Software, License, and XMP (Extensible Metadata Platform) fields embedded as an XML block inside the file. The challenge uses the License field, which most users would never inspect. When no obviously suspicious field stands out, run exiftool -a -u image.jpg - the -u flag shows unknown or non-standard tags that exiftool recognizes but does not normally display.

    Other metadata formats: PNG files use iTXt/tEXt/zTXt chunks instead of EXIF. PDF files embed metadata in an XMP stream. ZIP and Office documents store metadata in [Content_Types].xml and docProps/. Always match the metadata inspection tool to the file format - exiftool handles all of these, but dedicated tools like pngcheck (for PNG chunks) can reveal additional detail.

  2. Step 2
    Decode the base64 string from the License field
    Observation
    I noticed the License field value from exiftool output was a long alphanumeric string ending with '==' padding and whose length was a multiple of four, which are the unmistakable hallmarks of base64 encoding and suggested running base64 -d to recover the original flag.
    Copy the base64 string from the License field and pipe it through base64 -d to recover the flag.
    bash
    echo "cGljb0NURnt0aGVfbTN0YWRhdGFfMXNfbW9kaWZpZWR9" | base64 -d

    Expected output

    picoCTF{the_m3tadata_1s_modified}
    What didn't work first

    Tried: Pipe the string through base64 -e instead of base64 -d

    base64 -e (or just base64 with no flag) encodes input rather than decoding it, producing a doubly-encoded string that looks like more base64 gibberish instead of the flag. The flag is already encoded in the License field - the correct direction is decoding with -d (or --decode on macOS). If you see a long base64-looking output instead of a readable picoCTF{...} string, you are encoding instead of decoding.

    Tried: Try to decode the string with a URL-safe base64 decoder or ROT13 first

    URL-safe base64 replaces + with - and / with _, so a standard base64 string decoded with a URL-safe decoder will error or produce garbage on any characters those differ. The License field value uses standard base64 (with + and / characters and = padding) and requires a standard decoder. ROT13 only shifts alphabetic characters and produces unreadable text on a base64-encoded flag. The presence of = padding and a length that is a multiple of 4 are reliable indicators of standard base64.

    Learn more

    Base64 encodes binary data (or any bytes) using a 64-character alphabet (A-Z, a-z, 0-9, +, /). It is commonly used to embed binary data in text fields or URLs. The = padding at the end is a sign that the string is base64-encoded. base64 -d on Linux (or base64 --decode on macOS) decodes it back to the original bytes.

    Recognizing base64 on sight: Base64 strings consist only of alphanumeric characters, +, /, and trailing = padding. The string length is always a multiple of 4 (with padding). A rough rule of thumb: base64-encoded text is about 33% longer than the original binary. If you see a long string of alphanumerics with no spaces and ending in = or ==, it is almost certainly base64. Use echo "string" | base64 -d to test immediately.

Interactive tools
  • Image Metadata ViewerRead EXIF, XMP, JPEG comments, and PNG tEXt / iTXt / zTXt chunks from images entirely in the browser. Highlights flag-like values.
Alternate Solution

Once you copy the Base64 string from the License EXIF field, decode it with the Base64 Decoder on this site - paste and click decode to reveal the flag instantly without needing a terminal.

Flag

Reveal flag

picoCTF{the_m3tadata_1s_modified}

EXIF metadata fields can hold arbitrary data - always check all fields, not just the obvious ones like title and author.

Key takeaway

Image files carry structured metadata fields that are entirely separate from the visible pixel data and can hold arbitrary text strings. EXIF was designed for camera settings, but any field including obscure ones like License or UserComment can be written with any value, making metadata a convenient covert channel. The same principle applies across file formats: PDFs embed XMP streams, Office documents carry docProps XML, and PNG files use tEXt chunks. In real-world security, EXIF GPS data has deanonymized journalists and activists, and metadata scrubbing is a standard step before publishing sensitive files.

Related reading

Want more picoCTF 2021 writeups?

Tools used in this challenge

What to try next