
Flash CTF - GIFted
GIFted Writeup
Overview
GIFted is a forensics challenge with a single animated GIF as the handout. The animation never shows anything readable, so we take it apart frame by frame, notice that the frames are tiles of one larger image, and put them back together into a QR code that holds the flag.
Reconnaissance
The download contains one file, gift.gif. Opening it in an image viewer plays a short loop of blocky black and white squares that never settle into anything we can read.
$ file gift.gif
gift.gif: GIF image data, version 89a, 82 x 82An animated GIF is a stack of separate images played one after another. ImageMagick's identify prints one line per frame, so it tells us how many frames there are and how big each one is.
$ identify gift.gif
gift.gif[0] GIF 82x82 82x82+0+0 8-bit sRGB 2c 0.000u 0:00.000
gift.gif[1] GIF 82x82 82x82+0+0 8-bit sRGB 2c 0.000u 0:00.000
...
gift.gif[24] GIF 82x82 82x82+0+0 8-bit sRGB 2c 8520B 0.000u 0:00.000There are 25 frames, every one of them 82x82 and drawn at offset +0+0. Each frame uses only two colours. Twenty-five is 5 x 5, which makes us suspect the frames are pieces of one square picture rather than steps of an animation.
Exploitation
Let's dump the frames to separate files so we can look at them one at a time.
$ convert gift.gif frame_%02d.png
$ ls frame_*.png | wc -l
25Most frames look like random noise. A few stand out. frame_00.png is mostly white, with the corner of a thick black square ring in its lower right. frame_04.png has the same kind of corner in its lower left. A wide white margin with a nested black square in the corner is exactly how the top-left and top-right corners of a QR code look. If frame 0 is the top-left tile and frame 4 is the top-right one, the frames are stored in reading order: five per row, five rows.
ImageMagick's montage lays images out in a grid in the order it receives them. -tile 5x5 asks for five columns and five rows, and -geometry +0+0 keeps each frame at its own size with no gap between tiles.
$ montage gift.gif -tile 5x5 -geometry +0+0 qr.png
$ identify qr.png
qr.png PNG 410x410 410x410+0+0 8-bit Gray 2c 654B 0.000u 0:00.000The result is a 410x410 image, and opening it shows a complete QR code with all three finder squares in place.
Getting the Flag
Scanning the rebuilt image with zbarimg reads the QR code.
$ montage gift.gif -tile 5x5 -geometry +0+0 qr.png
$ zbarimg -q qr.png
QR-Code:Skillbit{the_wrapping_was_more_interesting_than_the_gift}Scanning gift.gif itself, or any single frame, finds nothing. The code only becomes readable once all 25 tiles are back in position.
Key Takeaways
- An animated GIF is a set of independent frames. Tools like
identifyandconvertlet us inspect and extract each one instead of watching the animation. - A perfect-square frame count with every frame the same size is a strong sign that the frames tile into one larger image.