Skip to main content

CanYouSee picoCTF 2024 Solution

Run exiftool on ukn_reality.jpg: the Attribution URL field holds a Base64 string that decodes to the flag.

Published: April 3, 2024Updated: August 25, 2026

Description

How about some hide and seek?

Download the file and unzip it to expose ukn_reality.jpg.

All work happens locally with command-line tools.

bash
wget https://artifacts.picoctf.net/c_titan/6/unknown.zip && \
unzip unknown.zip

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1Inspect EXIF metadata
    Observation
    A JPEG with something described as hidden usually means the metadata layer rather than the pixels, since viewers never render it. exiftool is the first thing to run.
    Run exiftool to dump every field. The Attribution URL entry stands out because it holds a Base64-looking string instead of a normal URL.
    bash
    exiftool ukn_reality.jpg
    ...
    Attribution URL                : cGljb0NURntNRTc0RDQ3QV9I...
    ...
    What didn't work first

    Tried: Run strings on ukn_reality.jpg instead of exiftool, hoping to spot the encoded value in raw output.

    strings does surface Base64-looking text, but it also floods the terminal with JPEG markers and Huffman fragments that look much the same. It knows nothing of EXIF field names either, so you cannot tell an Attribution URL from a camera model or a copyright notice. exiftool parses the structure and labels every field, which makes the odd one out.

    Tried: Use steghide on ukn_reality.jpg to look for hidden data embedded in the pixel values.

    steghide hides data in the low bits of the pixels and needs a passphrase to get it back. Here the payload is in EXIF fields, not pixels, so steghide finds nothing and asks for a passphrase that was never set. exiftool reads the metadata layer instead.

    Learn more

    exiftool reads, writes, and edits metadata across a wide variety of file formats. Run it without arguments and it dumps every field it can find: EXIF, IPTC, XMP, ICC Profile, JFIF, and more. For forensics this broad dump is always the right first step.

    The Attribution URL is an XMP field typically used to credit the source of an image, so legitimate values look like https://example.com/photo. A long alphanumeric string with no slashes or dots is an obvious signal that something has been encoded into the field.

    Base64 uses only A-Z, a-z, 0-9, +, /, and = (padding). If a metadata field contains only these characters and its length is a multiple of 4, it's almost certainly Base64. Recognising that pattern in otherwise structured metadata is a core forensics reflex.

  2. Step 2Extract just the encoded value
    Observation
    The Attribution URL field holds letters, digits, and trailing equals signs rather than an actual URL. That is base64, so pipe the value through base64 -d.
    A quick pipeline can isolate the Attribution URL value, strip whitespace, and hand the text to base64 -d. The decoded output is the entire flag.
    bash
    exiftool ukn_reality.jpg | grep "Attribution URL" | cut -d":" -f2- | tr -d " " | base64 -d

    Expected output

    picoCTF{ME74D47A_HIDD3N_a6d...}
    What didn't work first

    Tried: Omit the -d flag, or reach for a -e flag, expecting base64 to auto-detect the direction.

    With no flag at all, base64 encodes: it takes your already-encoded text and hands back a doubly-encoded string that looks like noise, with no error to explain it. There is no -e option either, so that spelling just prints a usage error. Decoding is -d (or --decode).

    Tried: Use cut -d":" -f2 (without the trailing dash) to extract the Attribution URL value.

    cut -f2 takes only the second colon-delimited field. That happens to work on a value with no colons in it, but the same pipeline on a URL like https://example.com quietly clips to //example.com. Writing -f2- means field 2 through end of line, so embedded colons survive.

    Learn more

    The pipeline chains small Unix tools, each with a single responsibility: grep finds the line, cut -d":" -f2- takes everything after the first colon, tr -d " " strips whitespace, and base64 -d decodes the result.

    The trailing dash in -f2- is the important detail. -f2 alone takes only the second colon-delimited field, which would clip the value if the URL itself contained colons (e.g. https://...). -f2- means "field 2 to the end," which keeps embedded colons intact.

    Base64 reverses the lossless encoding that maps arbitrary binary into printable ASCII. Every 3 input bytes become 4 output characters, which is why the encoded string is roughly 33% longer than the data it carries.

    This grep then extract then decode pattern shows up constantly in CTFs and real forensics. The shell one-liner is faster than a GUI tool and the muscle memory transfers directly to log analysis and incident response.

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{ME74D47A_HIDD3N_a6d...}

Decoding the Attribution URL entry reveals the complete flag shown above.

Key takeaway

Metadata sits outside the rendered content and never reaches the viewer, which makes it a natural hiding place. Any format with named fields can carry a payload nobody sees: EXIF, IPTC, and XMP in images, ID3 in audio, PDF document properties, Office custom properties. The reflex worth building is recognizing an encoding by its alphabet and padding, because once you name it the command line undoes it in seconds.

Related reading

Tools used in this challenge

Where to go next