日々drdrする人のメモ

今日もdrdr、明日もdrdr

SECCON 2016 オンライン予選に参加した話

現実逃避のついでに、12/10 ~ 12/11にあったSECCON 2016のオンライン予選に出てた。
CTFあんまりやってなくて上位は厳しいので、のんびり解ける問題を解くことにした。
(のんびりしてたので、途中AtCoder出たり、寝たりしてた)


SECCON 2016 オンライン予選

score-quals.seccon.jp
オンライン予選は12/10 15:00 ~ 12/11 15:00の24時間に行われた。

最初数問あって、そこから時間が経つと問題が追加されていく形式だった。

結果として、100点問題4問解いて400点だった。

f:id:smijake3:20161212025956p:plain

競技中の流れ + writeup

とりあえず、全体的に一番解かれている問題から手を付けるようにした。
順番は解いた順序。

VoIP (100)

pcapファイルを渡されて、そこから音声ファイルを抜き出せという問題。
pcapなので、とりあえずwiresharkに投げ込む。そしたら、RTP(Real-time Transport Protocol)で音声を送信してそうな通信内容が見えた。
wiresharkでは一連のRTPから音声ファイルを取り出せる機能*1があるらしくて、それを使ったら音声を聞けた。
その音声は、flagを伝えていて、それを聞き取ればOKだった。しかし、英語リスニング力0すぎて、flagを正しく聞き取るのに3時間くらい使ってしまった。("V"の発音が"D"とか"G"とか"B"に聞こえてた)
アルファベットを正しく聞き取るのがつらい問題だった。

flag: "SECCON{9001IVR}"

Vigenere (100)

ヴィジュネル暗号*2を使って暗号化されたflagを、md5とかからうまく計算する、みたいな問題。
とりあえずpythonでコード書いて求めた。

まず、pの文字列とcの文字列からkの一部の文字列を計算して、"VIGEREN?????"を得た。
次に、得たkの文字列で未決定の部分を総当りで決めながら、そのkの文字列に対するpの文字列を計算して、そのmd5を求めてmd5(p)と一致するかをチェックしてた。そしたらpの文字列が決まってflagを得ることができた。

実装したやつ : https://gist.github.com/tjkendev/f006f6630686a36753e765c5908541ce
flag: "SECCON{ABABABCDEDEFGHIJJKLMNOPQRSTTUVWXYYZ}"

Memory Analysis (100)

メモリのデータ(圧縮されて90MB程度)を与えられて、偽のsvchostがアクセスしていたURLを見つけろという問題。
ヒントとして、Volatility Framework*3を使うこと、hostsファイルを見ることが書いてあった。ツールの使い方をググりながらがんばってhostsファイルとURLを探した。

以下が求めるまでの流れ

# OSを特定 (WinXPSP2x86またはWinXPSP3x86であることがわかる)
$ ./volatility_2.5_linux_x64 -f ../forensic_100.raw imageinfo

# 開いているコネクションを表示 => Pid(1080)が"153.127.200.178:80"と通信していることがわかる
$ ./volatility_2.5_linux_x64 -f ../forensic_100.raw --profile=WinXPSP2x86 connections

# プロセスツリーの表示 => Pid(1080)はIEXPLORE.EXEであることがわかる。また、親子関係としてPPid(380)があることがわかる。
$ ./volatility_2.5_linux_x64 -f ../forensic_100.raw --profile=WinXPSP2x86 pstree

# 各プロセスのコマンドライン引数の表示。ここで、IEXPLORE.EXE(Pid: 380)が開いたURLがわかる。
# => Command line : "C:\Program Files\Internet Explorer\iexplore.exe" http://crattack.tistory.com/entry/Data-Science-import-pandas-as-pd
$ ./volatility_2.5_linux_x64 -f ../forensic_100.raw --profile=WinXPSP2x86 cmdline

# 存在したファイルの一覧表示。hostsファイルのフルパスとそのファイルのメモリ上の位置(0x000000000217b748)がわかる。
# => 0x000000000217b748      1      0 R--rw- \Device\HarddiskVolume1\WINDOWS\system32\drivers\etc\hosts
$ ./volatility_2.5_linux_x64 -f ../forensic_100.raw --profile=WinXPSP2x86 filescan

# hostsファイルのダンプ。この中でIEXPLORE.EXEが開いていたURLのhost部分(crattack.tistory.com)が"153.127.200.178"に置き換えられているのを見つけた。
$ ./volatility_2.5_linux_x64 -f ../forensic_100.raw --profile=WinXPSP2x86 dumpfiles -Q 0x000000000217b748 -D ../

ダンプしたhostsファイルの情報とIEXPLORE.EXEが開いていたURLからアクセス先がわかった。
そこにアクセスしてみたらflagが手に入った。

flag: "SECCON{_h3110_w3_h4ve_fun_w4rg4m3_}"

Anti-Debugging (100)

PEファイルを渡されて、逆アセンブリする問題。
とりあえず、Ollydbgに投げ込んで入力からパスワード判定あたりまでの実行を観察する。そしたら、"I have a pen."がパスワードであることがわかった。
それで、パスワードが一致したあとの実行を観察してたら、めっちゃデバッガ検出している処理があった(IsDebuggerPresent判定とかNtGlobalFlag判定とかプロセス検索とかしてた)。
そこからは実行観察が面倒なので、objdumpしたバイナリの流れを読んでたら、0=1で比較してからjneで飛んでいっているところを見つけたで、jneをjeに書き換えてから実行したらflagが出てきた。

以下のコードを

  40164d:	e8 3c 08 00 00       	call   0x401e8e
  401652:	c7 45 88 00 00 00 00 	movl   $0x0,-0x78(%ebp)
  401659:	83 7d 88 01          	cmpl   $0x1,-0x78(%ebp)
  40165d:	0f 85 ea 00 00 00    	jne    0x40174d
  401663:	b9 07 00 00 00       	mov    $0x7,%ecx

以下のように変更した

  40164d:	e8 3c 08 00 00       	call   0x401e8e
  401652:	c7 45 88 00 00 00 00 	movl   $0x0,-0x78(%ebp)
  401659:	83 7d 88 01          	cmpl   $0x1,-0x78(%ebp)
  40165d:	0f 84 ea 00 00 00    	je     0x40174d
  401663:	b9 07 00 00 00       	mov    $0x7,%ecx

flag: "SECCON{check_Ascii85}"

その他の問題

上の4問は11日のうちに解けて、そのあとはcheer msg (100)に手をつけた。
しかし、不正入力を与えてflagを得る問題はあんまり解いたことなくて慣れてなかったので、結局わからずじまいで、そこで終了だった。