SECCON 2018 Online CTF Writeup - QRChecker


概要

SECCON 2018 Online CTF の Writeup 2問目です。
QR コードチェッカーのコードを読み解き、画像を作り出す問題です。

開催時間中には解けませんでしたが、記録として残します。

f:id:yuu2634:20181028133907p:plain


QRChecker

問題は以下のサイトで公開されています。
http://qrchecker.pwn.seccon.jp/

まずは公開されている Python のソースコードを確認。
HTML 出力部分は無視して、QR コードの処理周りを抜粋しました。

codes = set()
sizes = [500, 250, 100, 50]

data = form["uploadFile"].file.read(1024 * 256)
image= Image.open(io.BytesIO(data))

for sz in sizes:
    image = image.resize((sz, sz))
    result= zbarlight.scan_codes('qrcode', image)
    if result == None:
        break
    if 1 < len(result):
        break
    codes.add(result[0])

for c in sorted(list(codes)):
    print(c.decode())

if 1 < len(codes):
    print("SECCON{" + open("flag").read().rstrip() + "}")


フラグの出力処理を確認

たどり着きたいのはこの部分のコードです。

if 1 < len(codes):
    print("SECCON{" + open("flag").read().rstrip() + "}")

codes には QR コードの読み取り結果を格納しているため、どうにかして2件以上の QR コードを認識させる必要があります。


1回で1つの QR コードしか認識しない

QR コードの読み取り部分を見てみます。
result に2件以上の結果が格納されると、break で処理が終わってしまいます。

for (略):
    result= zbarlight.scan_codes('qrcode', image)
    if result == None:
        break
    if 1 < len(result):
        break
    codes.add(result[0])

アップロードできる画像は1つだけですが、2つ以上の QR が認識されるとアウトです。
でも、フラグを得るためには2つ以上の QR を認識させたいのです。


リサイズ処理で QR コードを変化させる

ここで、QR 判定の直前に行われているリサイズ処理に注目します。

500x500, 250x250, 100x100, 50x50 の4サイズが定義されており、リサイズ後に QR コードの読み取りを行うところがポイントです。

codes = set()
sizes = [500, 250, 100, 50]

for sz in sizes:
    image = image.resize((sz, sz))
    result= zbarlight.scan_codes('qrcode', image)
    if result == None:
        break
    if 1 < len(result):
        break
    codes.add(result[0])

for c in sorted(list(codes)):
    print(c.decode())

例えば、500x500100x100 で読み取り結果の変わる QR コードが用意できれば、最終的に2件の QR を codes に格納できるはずです。


2種類の QR コードを用意して入れ子に

QR コードの誤り訂正を逆手に取れば何とかなりそうです。
ab の文字を入れた QR コードを用意。QR のススメ などで生成できます。

f:id:yuu2634:20181028164619p:plain f:id:yuu2634:20181028164704p:plain


b の画像を大きめに拡大して、その中に a の QR コードを埋めたのがこちら。
この QR コードでは、内側の a が認識されます。

f:id:yuu2634:20181028170831p:plain:w320

同じ画像を 100x100 にリサイズすると、
内側が潰れて読めなくなるため、今度は外側の b が認識されます。

f:id:yuu2634:20181028170837p:plain


フラグ獲得

SECCON の回答サーバに画像をアップロードするとフラグが出力されました。

f:id:yuu2634:20181028170856p:plain

SECCON{50d7bc7542b5837a7c5b94cf2446b848}


おすすめ記事

blog.yuu26.com

blog.yuu26.com