Skip to main content

Information picoCTF 2021 Solution

Examine an image file's hidden metadata to find an encoded value that leads to the flag.

Published: April 2, 2026Updated: August 13, 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 1Inspect the EXIF metadata
    Observation
    The description says the file can always be changed in a secret way, and hands you a JPEG. That points at the metadata rather than the visible pixels, so start 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 runs from raw bytes, and EXIF lives in a structured binary Image File Directory, so the License value may not appear as a clean ASCII run at all. More to the point, the flag is base64-encoded inside the field, so even a successful catch gives you an encoded string with no picoCTF prefix to grep for. exiftool parses the IFD and labels each field, which makes License visible at once.

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

    The EXIF data is in the file's bytes, but IFDs use variable offsets, nested pointer chains, and sometimes UTF-16 for a field's value, which makes navigating by hand slow and error-prone. exiftool resolves every offset and decodes the field encodings for you. By hand, it is easy to misidentify the field or miss it entirely when the value is UTF-16 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 2Decode the base64 string from the License field
    Observation
    The License field holds a long alphanumeric string ending in '==' padding, with a length divisible by four. Those are the marks of base64, so base64 -d recovers the 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

Tools used in this challenge

Where to go next