Table des matières

Captain Crunch (250)

Help the captain to find the flag!
http://forbiddenbits.net/tasks/spawn.png

Overview

On se retrouve avec une image PNG toute noir.

Solution

En regardant de plus près, il existe des pixels de (0, 0, 0) et de (1, 1, 1) (RGB). En convertissant les (0, 0, 0) en Blanc et les (1, 1, 1) en Noir, on se retrouve avec un QRCode.

from PIL import Image
 
image  = Image.open('spawn.png')
pixels = image.load()
 
for x in range(0, 300):
	for y in range(0, 300):
		if pixels[x, y] != (1, 1, 1):
			pixels[x, y] = (0, 0, 0) # black
		elif pixels[x, y] != (0, 0, 0):
			pixels[x, y] = (255, 255, 255) # white
 
image.save('qrcode.png')

La lecture du QRCode nous donne un lien vers un fichier hébergé sur leur serveur, une suite ?

http://forbiddenbits.net/060645cc5ebdf80e84ebc91547641b49

Il s'agit d'une suite de symbole hexadécimal, vaut mieux les passer en donnée brute afin de mieux voir le problème.

f = open('060645cc5ebdf80e84ebc91547641b49 ', 'r')
contents = f.read()
f.close()
 
raw = ''.join([chr(int(contents[i:i+2],16)) for i in range(0, len(contents), 2)])
 
f = open('raw.bin', 'wb')
f.write(raw)
f.close()

Le fichier est bien entendu illisible, au possible. Quelques chaîne de caractères sont quand même lisible:

fbbits

J'ai immédiatement pensé à un simple XOR, et j'avais raison même si pour un raison inconnu, ma première tentative de déchiffrement s'est soldé par un échec.

f = open('raw.bin', 'rb')
contents = f.read()
f.close()
 
decoded = ''
 
for i in range(len(contents)):
	decoded += chr(ord(contents[i]) ^ ord('fbbits'[i % len('fbbits')]))
 
f = open('unxor.bin', 'wb')
f.write(decoded)
f.close()

Le fichier decoded.bin est une image JPEG avec le flag marqué en clair.

Flag

f4a48257817d4a77da31c0c708c836a7