SECCON 2017 Online CTF WriteUp

SECCON 2017 Online CTFにTeam Caffein H@ck の一員として参加しました. 今回ですが、自動車教習など色々とやることがありあまり貢献できませんでしたが,とりあえず2問解くことが出来たので,WriteUpを書きます. セキュリティエンジニアではないので基本的に解くのは Programming ジャンルです.

Run me!

Run me!

-----  RunMe.py
import sys
sys.setrecursionlimit(99999)
def f(n):
    return n if n < 2 else f(n-2) + f(n-1)
print "SECCON{" + str(f(11011))[:32] + "}"
-----

さてこちらの問題ですが,上のソースを適当に動かして上げればいいということだとでしょう.しかし,誰が見ても再帰が深すぎて終わる気がしません.適当に最適化してあげれば大丈夫です.f(n)が死ぬほど呼ばれることは解ると思います.f(n)の時の値をメモしてそれを参照しながら,f(11011)を求めてあげればいいと言うことが想像できると思います.競プロer御用達メモ化ですね.で、書いたソルバが下のソースです.

あとはこれを実行して出てきた数字時の下32桁を取ってSECCON{}で包めばflagになります.今よくよく見てみたら完全にフィボナッチ数列ですね.

Qubic Rube

Qubic Rube

Please continue to solve Rubic's Cube and read QR code.

さて、伝統的QRコード問題の時間です.問題記載のURLを開くとこんな感じのthree.js使ってくるくる回る立方体を見ることが出来ます. f:id:acquamarine:20171210233336p:plain まず,すべてのQRコードを適当にスマートフォンでスキャンしてみたところ黄色のQRコードから謎のURLを得ることが出来ました.そこを開くと全人類がすべてを察することができるますね. f:id:acquamarine:20171210233638p:plain

考察・戦略

ということで,この問題は模様付きRubic Cubeを解いて各QRコードを復元し、またどんどん次のQubic Rubeを解読していくという問題ですね.これを察してから初め5秒位はどうくるくる回すかを考えてましたが,立体操作ができるほど頭は良くないので別の方法で解くことにしました.とりあえずピクセル単位で画像を分割して,以下のような分割された9の画像からどうやってQRコードを復元するかということを考えたいと思います.

f:id:acquamarine:20171210234448p:plain f:id:acquamarine:20171210234449p:plain f:id:acquamarine:20171210234450p:plain

f:id:acquamarine:20171210234451p:plain f:id:acquamarine:20171210234454p:plain f:id:acquamarine:20171210234456p:plain

f:id:acquamarine:20171210234453p:plain f:id:acquamarine:20171210234457p:plain f:id:acquamarine:20171210234458p:plain

この9つの画像の並べ方はすべてで 49 * 9! = 95126814720 通りあります.この通りをすべてを試してるとかなりの時間がかかり現実的ではありません.そこで画像を以下のようなパターンに分けます.

f:id:acquamarine:20171210235519p:plainf:id:acquamarine:20171210234453p:plainf:id:acquamarine:20171210234451p:plain 真ん中

それぞれは角、辺、真ん中にしか来ないのである程度の位置は確定することが出来ます.これを利用すると, 4! * 4! * 4 = 2304通りになります.ま、これくらいなら調べても良さそうな気がしますね.

解法

まず立方体の各面の画像を取得,それぞれを9分割し,色別にする.その後,辺/角/真ん中のブロックか判定をして、2304通りの画像を生成,それぞれのQRコードを読み取って読めるかどうか見ていくというように実装しました.

実装

すべてを解説すると時間が無限に解けるので画像の取得などポイントだけ話します.あとは気合で最後にあるソースコードを読み解いてください.

画像の取得

QRコードのページの実際にQubic Rubeを回してるソースを抜粋してきました. L15-L20にかけて画像をロードしてるところが見えますね.これには, /images/hogefugapiyo_{R, L, U, D, F, B}.png こんな感じで規則性があるので、それを利用してちょちょっと画像を取得します.昨晩0時位から突然単純にwgetで取得するとconnection refusedされてしまったのでwget --user-agent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)" オプションをつけて偽装して取得しました.

辺/角/真ん中判定

それぞれの端のピクセルをすべて覗いて {R, G, B} = {0, 0, 0} ピクセルを見つけます.黒のピクセルを含んでいる端の列の本数を数えて,4本なら真ん中/3本で辺/2本で角というように判定しました.

QRコードの読み込み

下が,2304通りの一つのQRコードの例です. f:id:acquamarine:20171211003343p:plain

QRコードの読み取りですが,Python使うとこんな感じで読めます.高専プロコンの時といいzbarさんマジ神です.

そ〜すこ〜ど

ソースコードを最後に載せておきます.死ぬほど読みにくいですが、疲れてたんです.ご容赦ください.

終わりに

みなさんお疲れ様でした. 今回終わって,次はどこかでチームの人で集まってやりたいと思う今日この頃です.大会中オンラインだと連絡がとりにくすぎる.