We're given an image file named `A_Real_Space_Hero.jpg`. Because this is forensics, we're dealing with something hidden inside the image.


We can start with checking the file with `exiftool`.

--- redacted due to brevity ---
Warning : Invalid JUMBF sequence number

It looks like there is something strange with this image. Let's look further, and run `binwalk` against the image.

258102 0x3F036 Zip archive data, at least v2.0 to extract, compressed size: 114, uncompressed size: 124, name: secrets/piece_104.png
258267 0x3F0DB Zip archive data, at least v2.0 to extract, compressed size: 150, uncompressed size: 198, name: secrets/piece_105.png
258468 0x3F1A4 Zip archive data, at least v2.0 to extract, compressed size: 146, uncompressed size: 183, name: secrets/piece_106.png

# redacted due to brevity

Okay we've definetly found something. Let's extract the zip archive again using `binwalk`.

binwalk -e A_Real_Space_Hero.jpg

We're now given a directory, conveniently named "secrets", with hundreds of image files hidden within that directory. These files are named `piece_[number].png`, and as the name suggests, they are pieces of a larger image. There's a total of 400 pieces in the directory, and we can assume the image is 200px by 200px (as each piece is 20px by 20px).

from PIL import Image
import os

pieces = [filename for filename in os.listdir("./secrets")]
pieces.sort(key=lambda x: int(x.split("_")[1][:-4]))

first_piece = Image.open(os.path.join("./secrets", pieces[0]))
width, height = first_piece.size

rows = len(pieces) // width
columns = width

assembled_image = Image.new("RGB", (width * columns, height * rows))

for i, filename in enumerate(pieces):
piece = Image.open(os.path.join("./secrets", filename))
x = (i % columns) * width
y = (i // columns) * height
assembled_image.paste(piece, (x, y))


We're now given a QR code, which we can scan to get the flag. I just dragged the image onto CyberChef and got the flag.



(hey look, it's a reference!)