This was the challenge:
The flag is contained in the following attached file. You know how QR codes work right? Flag is in format “word”. (So no flag bit on this one) Challenge by Garry.
Attached was a 1.2MB, 20,000 line file which looked like this:
I’ve been around a while and the =’s at the end of the lines made me think of base64, so I copied it out into CyberChef and got my first indication I was on the right path:
If you squint a bit, it looks like a QR code. Let’s take the squinting out and make it more obvious:
OK. QR Code time. The problem is, this doesn’t really scale. The block was 20 lines, so we’ve got 1000 QR codes, one of which has the flag. (Let’s just skip the bit where I took a screenshot, cropped it and stretched it, then decoded it with my phone).
Python’s my jam, so I’ll use that to split the file up:
#!/usr/bin/env python3
import base64
filename = '1000encoded.txt'
blocks = []
with open(filename, 'r') as fh:
block = ""
for line in fh.read().split("\n"):
block += line
if line.strip().endswith("="): # we have gotten to the end of the base64 block
blocks.append(block)
block = ""
for i, b in enumerate(blocks):
d = base64.b64decode(b)
with open('qrcodes/{}.txt'.format(i), 'w') as fh:
decoded_block = d.decode('utf-8').replace("x", "█")
fh.write(decoded_block)
This gave me 1000 individual text files, each which looked something like the above example. I knew I needed to figure out how to get this into text, and I’d done something similar before with zbar so I used ImageMagick to make the images and zbar to decode:
#!/bin/bash
for txt in $(ls -1 *.txt); do
convert -font DejaVu-Sans-Mono-Bold -pointsize 14 -gravity northwest text:$txt -trim outfile.jpg
convert -resize 600x600\! outfile.jpg $txt.jpg
zbarimg $txt.jpg >> results.txt
done
grep -v falseflag results.txt
I’l break that one down a little since it took some poking.
for
each text file…convert
the text file into an image. This turned out to be stretched vertically, owing to the fact that we’re using text as rectangular “pixels” instead of squares.convert
this first image, resizing the image to a 600x600 square. The\!
bypasses the usual aspect ratio lock.zbarimg
decodes the jpg file into text (eg:QR-Code:falseflag:{decolorized}
) and puts it into a text filegrep
the results, stripping out false flags.
Four of the images didn’t decode properly for whatever reason - I’ll have to work that out another day (I won’t) - but it gave me what I needed:
EAN-13:0001000001189
EAN-13:0001000001189
EAN-13:0065478000068
QR-Code:truthflag:{<redacted>}
EAN-13:5446476968232
Oh, you thought I was going to give you the flag? Nah, but here’s the file if you want to play along yourself.