Competition: CSAW quals 2016
Description: Scrambled Fun for Everyone! Author: fang0654 <brainfun.png>
- There's nothing hidden in the file other than the pixel data.
- The image is 512x512, but can be scaled down 32x32 to match the blocks to pixels.
- The RGB values are all multiples of 0x10. An example pixel could be
(0x40, 0xf0, 0x20).
- There is also transparency.
- There aren't that many different alpha values. Many occur around the same number of times (28-30).
- The alpha values are in the printable ASCII range.
- The values that occur around the same number of times are lowercase letters,
and the others are
., and a single newline.
- The name of the challenge is brainfun, which sounds kind of like brainfuck, which is an esoteric programming language which uses those symbols.
- The challenge description says that it's scrambled.
- Pige0n noticed that the letters can be rearranged to spell "my rainbow", which suggests that there is a definite order to the pixels.
- There are probably sections of lowercase letters and sections of brainfuck symbols.
- Brainfuck symbols had red values around the middle, and lowercase letters had low and high values.
- Sort the pixel values by RGB value, using the key
red<<8 + green<<4 + blue. Edit (thanks BookGin):
- It should be
red<<16 + green<<8 + blueto sort by full values, but I abused the fact that all the RGB values take the format of
0xN0, so a pixel
(0x10, 0x20, 0x30)will get converted to
- I probably should have used
struct.pack("hhh", red, green, blue)
- It should be
- It turns out that they spell "owmybrain", but whatever.
- Running that as brainfuck spits out the flag:
- Here's a one-liner (it's not very efficient):
python3 -c '__import__("pybrainfuck").BrainFck().run("".join([chr(p) for p in sorted([list(__import__("PIL", globals(), locals(), ["Image"]).Image.open("brainfun.png").getdata())[r*512 + c] for r in range(0, 512, 16) for c in range(0, 512, 16)], key=lambda p: (p<<8) + (p<<4) + p)]))'