3DS CTF 2017 - Microscope

by dp1
December 20, 2017

The input gif had 108900 frames, all either yellow or green. By mapping each one to a single white or black pixel of an image, we can get to a qr code. The tricky part here was that the frame data was identical for each one of them, while the thing to change was the first entry in the color palette, effectively modifying the color without touching the actual pixel data.

#!/usr/bin/python2

import os
from PIL import Image

def extractFrames(inGif, outFolder):
	outdata = []
	frame = Image.open(inGif)
	nframes = 0
	while frame:
		if frame.getpalette()[0] < 128:
			outdata += [(0,0,0)]
		else:
			outdata += [(255,255,255)]
		
		nframes += 1
		try:
			frame.seek(nframes)
		except EOFError:
			break
	return outdata
    

if __name__ == "__main__":
	c = extractFrames('gif.gif', 'output')
	img = Image.new('RGB', (330, 330))
	img.putdata(c)
	img.save('qr.png', 'PNG')

The output of this script is the following image, which when read reveals the flag:

3DS{s0_y0u_kn0w_yur_g1fs}