SECCON 2015 オンライン予選 Decrypt it
競技屋なら問題なく解ける問題。ただし罠がひとつある。
Crypto 300. Decrypt it
問題文
$ ./cryptooo SECCON{*************************} Encrypted(44): waUqjjDGnYxVyvUOLN8HquEO0J5Dqkh/zr/3KXJCEnw=
what’s the key? cryptooo.zip
flagと暗号化器があって、暗号化器と暗号化結果が与えられるので、元のflagを求める。
解法
指示されたzipを落として開くと、cryptooo
というバイナリが出てくる。
これを動かしてみて簡単に調べてみると、以下のような性質が分かる。
- 出力はbase64でencodeされている。decode結果はasciiではない
- 入力の長さと出力の長さはほぼ比例している。なんらかの手順で入力を置き変えて出力している
- 特に、base64 decode後の出力の長さは入力の長さと一致する
- 入力の$i$文字目を変化させると、出力の$i$文字目以降が変化する
1番目の性質は、単にdecodeすればよい。 3,4番目の性質から、入力文字列の先頭から順に決定していけばよく、また、そうするしかない。 これをやる。
$ for i in {0..255} ; do echo -n $i' ' ; ./cryptooo 'SECCON{Cry'$(perl -e "print chr $i")'AAAAAAAAAAAAAAAAAAAAA}' | cut -d' ' -f2 | base64 -d | hexdump -C | head -n 1 ; done
などとして、先頭から順に決定していく。
最終的にSECCON{Cry_P\x0ato_Oo_Oo1Oo_oo_Oo_O}
という文字列が得られる。
ただし途中に改行文字が挟まっている。なんだか怪しいが、これを除いて提出すれば通る。
SECCON{Cry_Pto_Oo_Oo1Oo_oo_Oo_O}
。
なんらかのミスで混入したが、改行文字はshellの時点で消えるので./cryptooo
に渡されず影響がなく、残りの部分が求まったように見える。
そういえば、結果はcrypto
になりそうだよね、とか言いながら作業をしていた。
以下のようになった状態で実行して、実際に効いているのは後ろのt
であるのに、\x0a
が効いているのだと勘違いしたのかもしれない。
$ ... ; ./cryptooo 'SECCON{Cry_P'$(perl -e "print chr $i")'toAAAAAAAAAAAAAAAAA}' | ...
余談
線形に決定できそうだなあと思いdijkstraで探索するプログラムを書いたら、_
やを探索範囲に入れていなかったため、求まらなかった。
手動でやって、おかしいなあどうやっても改行文字が入るぞ、などと言いながら全部複合化してしまったため、書いただけで出番はなかった。\x0a