読者です 読者をやめる 読者になる 読者になる

SECCON 2016 Writeup(Vigenère, Anti-Debugging)

今回チャレンジした問題(Vigenère, Anti-Debugging)のWriteupです.
2問しかチャレンジしてないのでちょっとした手順も書いてみました.
# 今度はちゃんとSECCONに向けてスケジュールを調整したい...(去年も同じことを呟いたような)

Vigenère

下記のような問題でした。

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{
Vigenere cipher
https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher

古典暗号の Vigenère Cipher (問題文のリンクを参照)によって暗号化された平文を解読する問題です.
Vigenère Cipher は簡単に言うと、横軸に平文一文字、縦軸に鍵一文字を取り、テーブルを参照したときに該当する文字が暗号化した文字として出力される暗号です(リンクを読んで知った).
平文長 > 鍵長 の場合、暗号化には鍵に用いられた文字列が繰り返し適用されます.
このことから、暗号文の出力は簡易的に以下のように考えることができます.

p[x] = 'plain text'
k[x] = 'key text'
c[x] = 'ciphe text' # 文字数合わせのため、誤字ではありません
table[28] = ABCDEFGHIJKLMNOPQRSTUVWXYZ{}
c[i] = table[(p[i]_index + k[i]_index) mod (table length)]
# ここでは _index は 対象の文字がtableの何文字目か を示しています.

今回の問題だと鍵(k)の長さは ? の数(12)、平文(p)の長さ(=暗号文の長さ)は 43 です.
良い解読手法を知らなかった/思いつかなかったので k は総当りで探し、p が示されている md5(p) と一致した場合に p を出力するスクリプトにします.(圧倒的勉強不足)

  • 事前準備
    今回のテーブルは上記の通り 'ABCDEFGHIJKLMNOPQRSTUVWXYZ{}' で、table 長は 28 です.
    鍵を完全に総当りをすると 2813 (6502111422497947648 = 262 < 2813 < 2663)となってちょっとした時間がかかるため、事前準備として分かる箇所を出します.
    p = SECCON{
    c = LMIG}RP
    上記から k = VIGENER (7 文字) であることがわかります.
    確認できた内容と問題のタイトルからなんとなく 8 文字目は E っぽい(VIGENER(E) かな?)です.
    ひとまず、平文すべてに暗号化を行う際の鍵は以下と仮定します(8文字目(Rの次)の E が不確定).
    k = VIGENERE????VIGENERE????VIGENERE????VIGENER
    次に残りの4 文字の ? について総当りします.

  • 脳直スクリプト

% python vigenere_dec.py
SECCON{ABABABCDEDEFGHIJJKLMNOPQRSTTUVWXYYZ}

正解でした.

Anti-Debugging

bin というファイルをダウンロードし、フラグを見つけ出せ、という問題です.
とりあえず file と strings を叩きます.

% file bin
bin: PE32 executable for MS Windows (console) Intel 80386 32-bit

Windowsデバッグですかね.

# 以下はコメントです
% strings bin
!Enjoy CTF! . # 楽しんでますよ
Richw0B
.text
`.rdata
@.data
.rsrc
(中略)
ollydbg.exe
ImmunityDebugger.exe
idaq.exe
Wireshark.exe
Input password >
I have a pen.
Your password is correct.
But detected debugger!
(But 〜 系が続くため省略)
But detected Debugged.
;aj&@:JQ7HBOt[h?U8aCBk]OaI38 # flagっぽい
check!
password is wrong.
(中略)
Process32Next
Process32First
CreateToolhelp32Snapshot
(アンチでバッグで使用する関数や DLL とかその他諸々. 以下省略)

「Input password >」「I have a pen.」から、起動したらパスワード入力のルーチンがありそうです.
また、アンチデバッグ機能はある程度含まれている模様.
そのあとに暗号化してある文字列を復号してどこかしらに出力してくれる流れでしょうか.(そうであってくれという願望)
Wireshark を検知しているところを見ると通信も見せたくないのかな?なんてことも頭に入れておきました(意味はありませんでした).
とりあえず見た感じアンチデバッグには少なくとも IsDebuggerPresent とプロセス名での検知がありそうです.
ひとまずバイナリエディタで見つけた文字列の exe を ex_ と変更しておきます.(要らない)
次に、おもむろに IDA で bin.exe (拡張子 .exe を付加) を開き、デバッグしていそうなところを特定します.
「Input password >」で検索.

f:id:news-nknskn:20161211204300p:plain

OllyDbg で飛ぶとこんな感じです.

f:id:news-nknskn:20161211205255p:plain

下の方にアンチデバッグしている箇所がちょいちょいあり、フラグを書き換えるのがめんどくさいので暗号文を用意しているっぽい箇所に飛んでみます.
# 00401663 に New origin here

f:id:news-nknskn:20161211205335p:plain

ちょっと動かしてみると for で回っていることがわかります.
めんどくさいのでひとまず MessageBoxA の直後にソフトウェアブレークポイントを設定、F9.

f:id:news-nknskn:20161211205807p:plain

出ました.

flag : SECCON{check_Ascii85}

簡単な感想

Webに触れたかった...
あとuncomfortable webは脆弱性のある kernel だったら権限昇格して楽にささっと解けるかもなー、と思ってバージョンとか見てみたけどダメだったので諦めました.
# CentOS 6.8 2.6.32-642.11.1.el6.x86_64、2016/11/19 にリリースなんですよね...くそう.

以上です.