Rating: 5.0

### Challenge
Title: brainfun
Competition: CSAW quals 2016
Category: Forensics
Points: 150
Description: Scrambled Fun for Everyone! Author: fang0654 \<brainfun.png\>

### Background
- 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.

### Progress
- 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.

### Solution
- 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 + blue` to 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 `0x1230` this way.
- I probably should have used `struct.pack("hhh", red, green, blue)`
- It turns out that they spell "owmybrain", but whatever.
- Running that as brainfuck spits out the flag: `flag{w3_r_th3_h0llow_m3n}`
- Here's a one-liner (it's not very efficient):
```python
python3 -c '__import__("pybrainfuck").BrainFck().run("".join([chr(p[3]) 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[0]<<8) + (p[1]<<4) + p[2])]))'
```

Original writeup (https://gist.github.com/Lense/a8e94e96f886cb773f646b8aaea806fc).