# Plaid CTF 2018 - Task "Messy Desk"
## Extracting the QR code
In this task we are given a fragment of video from a surveillance camera,pointing to a messy desk. The only interesting thing in the video is areflection of a QR code on the glass/plastic surface of a sphere. It's acurved and quite small reflection, less than 100 pixels wide, as you cansee here in a crop of a video frame in its original resolution:
![](qr-original.png)
After flipping, scaling and transforming it into a (more or less) square,this is what we got:
![](qr-work.png)
Not very promising... Obviously, this wouldn't be detected by any QR codereader, so we decided to manually build a new QR code from the scratchbased on it, but with enough quality to be parsed by readers.
## Manually building the QR code
Of course the main problem is determining which pixels are black and whiteon the original image, as the resolution is very low, especially on thebottom right corner. But looking carefully we can tell many pixels apart,mostly those that are alone or forming a line (while those forming a clusterare more difficult to separate). Thanks to this, we can infer it's a version2 QR (25x25).
We also have information about how all QR codes are formatted. Thanks tothe excellent [QR code tutorial at Thonky.com](https://www.thonky.com/qr-code-tutorial/),(from where the next two images have been taken), we can fix the positionof some pixels, helping also to fix other pixels in the vicinity:
![Taken from QR tutorial at Thonky.com](function-patterns2.png)
But especially important is the format string, a 15-bit length sequence(5 bit of data + 10 bit for error correction) that determines the errorcorrection level for the QR code and the applied mask pattern:
![Taken from QR tutorial at Thonky.com](format-layout.png)
Looking at the [table of possible values](https://www.thonky.com/qr-code-tutorial/format-version-tables),for the format string we can quickly see that the best matchingsequence is 011000001101000, corresponding to ECC level Q (thatallows to recover 25% of data, very useful for this problem), andthe pattern mask 1 (there are several masks that help QR codes tobe easier to read)
All of this lead to our first version of the reconstructedQR code:
![](qr-reconstructed-v1.png)
But it didn't work :D  In spite of several attempts with small changesto some doubtful bits, no QR code reader would consider it valid.
## Fixing the QR code to make it work
What else could we do? From the analysis of the format stringwe learnt that the QR code uses pattern mask 1, meaning thateven rows are inverted.
Thanks again to the QR tutorial we could learn [how bits are placed](https://www.thonky.com/qr-code-tutorial/module-placement-matrix)in a QR code, and applying the pattern mask we could decodethe first two columns, obtaining this:
```0100 meaning data is in byte format00010010 the code has 18 characters (it's actually 19)01010100 T01000010 B11000100 D (assuming first bit is incorrect)01000110 F00111011 ;01111010 z00110000 0```
`TBDF;z0`? What a crappy way to start a flag... But we have to take intoaccount that the code starts from the bottom right corner, where resolutionis lower and it's easier to make a mistake.
But thankfully we knew that all flags begin with "PCTF{", so wecould just fix the pixels to match this sequence. It was nota big deal, as only 5 pixels were affected. This is the result:
![](qr-reconstructed-v2.png)
The plan was to go on and verify if the remaining characters of the flagkept making sense, but... it worked!!!  QR code readers would read thefull flag from that QR code:
`PCTF{z0oo0m_nh4nc3}`
Probably there were some more bits that were wrong in theremaining QR code, but the error correction bits were now enoughfor the QR readers to completely rebuild the original message, sothere was no need to recover perfectly the original QR code.