Crikeycon 2019 CTF - 1000 Qways to DieR

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:

base64

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:

cyberchef

If you squint a bit, it looks like a QR code. Let’s take the squinting out and make it more obvious:

ascii QR code

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

file browser

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 file
  • grep 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.

QR Code



#qr #qrcodes #barcodes #imagemagic #zbarimg #ctf #python #programming