CTF Writeup SECCON 2016¶
結果&感想¶
某チームでSECCON2016に参加しました。
今年は全体的に難易度が高かったですね。。ExploitとCryptoが多めでした。
どっちも専門知識や職人芸的な技能が試されるので、全体的に苦戦されたんじゃないかと思います。
いちおう200点問題ができたのと、ちょっとアシストできたと思われる100点の問題について、writeupを書きます。
Vigenere¶
Crypto問 100点 777チーム回答
以下、問題前文
k: ???????????? p: SECCON{???????????????????????????????????} c: LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ k=key, p=plain, c=cipher, md5(p)=f528a6ab914c1ecf856a1d93103948fe |ABCDEFGHIJKLMNOPQRSTUVWXYZ{} -+---------------------------- A|ABCDEFGHIJKLMNOPQRSTUVWXYZ{} B|BCDEFGHIJKLMNOPQRSTUVWXYZ{}A C|CDEFGHIJKLMNOPQRSTUVWXYZ{}AB D|DEFGHIJKLMNOPQRSTUVWXYZ{}ABC E|EFGHIJKLMNOPQRSTUVWXYZ{}ABCD F|FGHIJKLMNOPQRSTUVWXYZ{}ABCDE G|GHIJKLMNOPQRSTUVWXYZ{}ABCDEF H|HIJKLMNOPQRSTUVWXYZ{}ABCDEFG I|IJKLMNOPQRSTUVWXYZ{}ABCDEFGH J|JKLMNOPQRSTUVWXYZ{}ABCDEFGHI K|KLMNOPQRSTUVWXYZ{}ABCDEFGHIJ L|LMNOPQRSTUVWXYZ{}ABCDEFGHIJK M|MNOPQRSTUVWXYZ{}ABCDEFGHIJKL N|NOPQRSTUVWXYZ{}ABCDEFGHIJKLM O|OPQRSTUVWXYZ{}ABCDEFGHIJKLMN P|PQRSTUVWXYZ{}ABCDEFGHIJKLMNO Q|QRSTUVWXYZ{}ABCDEFGHIJKLMNOP R|RSTUVWXYZ{}ABCDEFGHIJKLMNOPQ S|STUVWXYZ{}ABCDEFGHIJKLMNOPQR T|TUVWXYZ{}ABCDEFGHIJKLMNOPQRS U|UVWXYZ{}ABCDEFGHIJKLMNOPQRST V|VWXYZ{}ABCDEFGHIJKLMNOPQRSTU W|WXYZ{}ABCDEFGHIJKLMNOPQRSTUV X|XYZ{}ABCDEFGHIJKLMNOPQRSTUVW Y|YZ{}ABCDEFGHIJKLMNOPQRSTUVWX Z|Z{}ABCDEFGHIJKLMNOPQRSTUVWXY {|{}ABCDEFGHIJKLMNOPQRSTUVWXYZ }|}ABCDEFGHIJKLMNOPQRSTUVWXYZ{
問題タイトルからヴィジュネル暗号であることが解る。暗号の仕組みとしては難しくない。
暗号文、平文、キーの内、2つが分かっていれば暗号化・復号化ができる。
基本的な考え方¶
1文字目を例にキーを求めてみよう。
平文の1文字目(p):S
暗号文も1文字目(c):L
上の表のSの行を抜き出してみる
|ABCDEFGHIJKLMNOPQRSTUVWXYZ{} -+---------------------------- S|STUVWXYZ{}ABCDEFGHIJKLMNOPQR
表の中のLの位置を確認、対応する列はVになっている。
ということで、1文字目のキー(k)は、Vとなる。
これを繰り返すと、ここまで解る。
k: VIGENER?????VIGENER?????VIGENER?????VIGENER p: SECCON{?????BCDEDEF?????KLMNOPQ?????VWXYYZ} c: LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ
残り5文字について¶
正解時のMD5ハッシュが問題にあるので、総当りすればよい。
この手の古典案号のキーは、だいたい4~5文字だったら、現実的な時間で解けると考えてよさげ。
あとヴィジュネル暗号の英語の綴りは"VIGENERE"なので、キーの次の文字は"E"であろうという予想がつきます。
CTF時はチームメイトがJavaScriptで総当りプログラムを作ってくれました。
ちょっと勉強がてらPythonで書いてみました。5文字の総当りだと、それなりに時間がかかります。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import hashlib
from itertools import combinations
charset= "ABCDEFGHIJKLMNOPQRSTUVWXYZ{}"*5
chiper = "LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ"
itr = combinations(charset,5)
def decode(c, key):
return charset[(charset.index(c)-charset.index(key))%28]
for i in itr:
print i[0],i[1],i[2],i[3],i[4]
a0 = decode('E',i[0])
a1 = decode('D',i[1])
a2 = decode('O',i[2])
a3 = decode('E',i[3])
a4 = decode('E',i[4])
b0 = decode('K',i[0])
b1 = decode('J',i[1])
b2 = decode('W',i[2])
b3 = decode('M',i[3])
b4 = decode('N',i[4])
c0 = decode('V',i[0])
c1 = decode('U',i[1])
c2 = decode('F',i[2])
c3 = decode('W',i[3])
c4 = decode('Y',i[4])
# 不明なキーの最初の1文字目をEと決めつけて実施(VIGENEREの最後のE)
# 以下3行をコメントアウトすれば5文字の総当たりになる
a0 = decode('E','E')
b0 = decode('K','E')
c0 = decode('V','E')
flag = 'SECCON{'+a0+a1+a2+a3+a4+'BCDEDEF'+b0+b1+b2+b3+b4+'KLMNOPQ'+c0+c1+c2+c3+c4+'VWXYYZ}'
md5 = hashlib.md5(flag).hexdigest()
if md5 == "f528a6ab914c1ecf856a1d93103948fe":
print 'Hit!',flag,md5
exit()
ちなみに¶
以下にヴィジュネル暗号のソルバを事前に準備しておいたんだけれど、今回はアルファベットの他に"{}"が入っているという仕様のため、使えなかった。
(あと英文じゃないので、復号結果が正しいか判断ができないとかある)
CTF Crypto Vigenere暗号(ヴィジュネル暗号)
pppppoxy¶
Web問 200点 43チーム回答
ダウンロードしたexeを実行すると、ローカル限定で接続できるWebサーバとブラウザが立ち上がり、idとpasswordの入力を求められる。
正しいパスワードを入力するのが今回の問題。
失敗すると「username or passwaord was incorrect!」が表示される。
ぶっちゃけ力技で解いた。
うさみみハリケーンを使い起動中のpppppoxyのメモリ内容を参照。こちらから入力したパスワードの近辺を検索して参照し、怪しい文字列を見つけた。
という訳で、以下を入力してフラグ取得
-40.01.6102 ,ikazamaY ogieK? thgirypoC
と、言葉にするとすぐ終わるんだけど、実際この手法に行き着くまでに
SSHトンネルして外に繋がるようにして、hydraでブルートフォース
→制限時間内に明らかに終わらない事がわかり諦める。ILSpyでデコンパイルしてソースコードを眺める。
→難読化(?)とか文字化けとかに遭遇して諦める。
という苦労をして時間を溶かしている。
その他の問題のWriteup¶
あのTomoriNaoさんのページが、とても詳しいです。
TomoriNao SECCON 2016 Online
https://hackmd.io/s/HkGx_btmx#