SECCON 2018 Online CTF Writeup – QRChecker
SECCON 2018 Online CTF の Writeup 2問目です。
QR コードチェッカーのコードを読み解き、画像を作り出す問題です。
開催時間中には解けませんでしたが、記録として残します。
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())
例えば、500x500
と 100x100
で読み取り結果の変わる QR コードが用意できれば、最終的に2件の QR を codes
に格納できるはずです。
2種類の QR コードを用意して入れ子に
QR コードの誤り訂正を逆手に取れば何とかなりそうです。a
と b
の文字を入れた QR コードを用意。QR のススメ などで生成できます。
b
の画像を大きめに拡大して、その中に a
の QR コードを埋めたのがこちら。
この QR コードでは、内側の a
が認識されます。
同じ画像を 100x100
にリサイズすると、
内側が潰れて読めなくなるため、今度は外側の b
が認識されます。
フラグ獲得
SECCON の回答サーバに画像をアップロードすると、QR コードの文字列とともにフラグが出力されました。
SECCON{50d7bc7542b5837a7c5b94cf2446b848}
ディスカッション
コメント一覧
まだ、コメントがありません
フォローする
カテゴリー
最近の投稿
ブログについて