CSAW CTF 2014

https://ctf.isis.poly.edu/scoreboard

前回 (HITCON CTF 2014) 参加した時に、これは面白いけど一人でやると真剣にしんどいなーと思ったので、まわりの人を適当に誘ってチームで参加してみました。名前のアイデアが誰もなかったので、僕が適当に決めた nop-or という名前で。由来は自社名。

僕は真剣にやるけど他の人は暇な時に適当でよいよーというスタンスだったんだけど、妙に真剣に参加してくれる人が多くて、結果は13位。予想より良い結果だったと思う。

残った問題は cryptography * 2 と recon * 2 だけ。チームが全部解けてると、 write-up 見なくてもどういう問題でどう解いたのか勉強が終了してて、それも良いなと思った。

メンバーは僕以外は全員初参加で、7人くらいいたんだっけ? ksnctf を紹介してあった人もいたので、少しだけ練習した人もいたけど、そういう人達は一生懸命 "FLAG_" という文字列を探してたりして、むしろ練習は逆効果だったのではないか。

僕は簡単な問題は初参加の人たちが景気付けに解いてくれるだろーという期待のもと、バイナリばかり読んでた。初参加の人が楽しめるようにという少しの配慮と、自分がバイナリだけ読みたいという本音が混じった一石二鳥の作戦だった。あとで思うに別に少しの配慮はいらなかった。

時系列で

saturn (Exploitation 400)

ほどほどに難しそうなやつ、てことで400。もう内容覚えてないけど3つくらいコマンドがあって、1つ目のコマンドで得た情報を2つ目にわたすと良いとかそんなだっけ。超簡単で、なんだこのコンテストレベル低いて聞いてたけど低すぎないか…と思ってたが、後になって思うとほどほどに難しかった。むしろ例年よりは難化していたらしい。

trivia 10 一問を他の人が解いた直後がこれということで、簡単さがしのばれます。というか他の人が起きてくるころには解けてたと思う…

pybabbies (Exploitation 200)

これは他の人がやると良さそうな問題だなーと思ってたら、まさに向いてそうな @phoenixstarhiro が起きてきたので、やってみたら、と勧めてみたらサックリと解いておでかけしに行った。かっこいい。

s3 (Exploitation 300)

ish も見てたのだけど、どうも s3 の方が簡単な気がしてきたのでこっちにシフト。 key value store を CUI で操作する。

あまり理屈はわかってないけど、作ったキーを更新してから表示すると、何故か最初に渡した文字列におもむろに call してくれるという問題だった。やることは簡単だけど、コードがでかくて読むのがめんどくさかったなあと思った。

やること簡単と言いつつ、 x86-64 の shellcode を書くのに少しだけ時間がかかっていかんなと思った。 syscall のかわりに int 0x80 と書いたりとね…

dumpster diving (Forensics 100)

起きてきた @mayahjp が Firefox のコアがーとか言ってる。コアか少し面白そうだな解くのは任せるにしても、問題の雰囲気見てみるかと objdump -s してみる…と flag{...} があって解けてしまった。 "FLAG_" を探していたらしい…

Obscurity (Forensics 200)

@mayahjp がマウスドラッグしたらフラグあった楽勝とか言ってた。おいこれなんで 200 なんだと思った。

why not sftp? (Forensics 200)

@mayahjp が wireshark の使いかたを理解して瞬殺した。おいこれなんで略。

bo (Exploitation 100)

これも strings で瞬殺されてた。実行する必要すら無いてすごい。

Big Data (Networking 100)

@mayahjp が wireshark ながめてログの文字つないでいけば良いと気付いたぽい。今思うとこの人エスパー力問われる問題の悪口言いながらエスパー力問題ばっか解いてるな、ツンデレかな…

eggshells (Reverse Engineering 100)

fork bomb が入ってるので、二人くらいのマシンが破壊される。誰だったかが utils.pyc を strings して終了。 strings で 3 問解けるとか…

psifer school (Cryptography 200)

明らかに簡単な問題が解かれ終わって、 free lunch is over なムードになったころ、少しずつ進めていた omoikane さんが解く。暗号 3 つ詰め合わせって感じ?

ish (Exploitation 300)

ish わからないな、スタックの一部を表示させることはできるんだけど、どうやってもスタックずれないような?と思ってた。少し寝て起きたあと、いややっぱ明らかにスタックの一部を表示させることができるんだから、どっかずらせる場所あるだろうと思ったら意味不明に alloca ぽいことしてる場所があったので、適当にずらせると判明。

わかってからも適切な調整が結構大変だった。まぁ良い問題だったのかなと思うんだけど、コードやけに大きいなぁというのと、 shell 実行したいな…と思うのとで不満気味であった。

csaw2013reversing2.exe (Reverse Engineering 200)

おにゅーのマシンを買ってきたとか言ってた @ttuusskk が別におにゅーじゃない Windowswindbg で step 実行しながらメモリ見てたらあったとか言って解いた。

wololo (Exploitation 400)

地道に iOS 用ぽい ARM コードを gas に喰わせられるように変換できるスクリプトを書いて、あとは実行しながらデータベースを調整していったら解けた。変換なんてしなくても読めばわかる気もするんだけど、動いてるものが無いものを考えるの苦手なんだよな。よく考えるとコード読みとかも gdb 使ってやるとか結構多い。

Julian Cohen (Recon 100)

@mayahjp が起きたらヒントが出てたとかで、アカウント作って解いた。

aerosol can (Reverse Engineering 500)

この問題は大変だけどやるだけの問題に見えて、そのやるだけ度が簡単そうなら解いちゃおう、と僕も見てたのだけど、その大変度合いがすさまじそうだったので、早い段階で放棄した。そしたら @phoenixstarhiro が根性で解いた。正直時間内に解けないかもな、と思ってたので、やはりこの人の根性はすごいなと思った。

greenhornd (Exploitation 400)

いやーしんどかった。バグの位置は教えてくれてるので、ちょっとしたチェックを理解すれば、あとはちょっと ROP してメモリ確保してから shellcode を渡すだけなんだけど、なんせ Windows なんだ…

例のごとく exe を linux のメモリ空間に mmap して実行したいとこだけ実行できるようにしながら、任意コード実行できるようにした。

shellcode は shell-storm で適当に拾ってきた cmd.exe 動かすやつだとうまく使えなくて、まぁ AppJailLauncher てのがシステムコールをいくつかつぶしていて、問題に書いてある通り ReadFile WriteFile だけで解けて趣旨なのかな、と理解した。しかしそんなことはなくて cmd.exe 動かせたらしい…

さてこれのためのコードを書くのはすごく大変だった。とりあえず kernel32.dll 内の関数の位置が EC2 で借りた Windows 2012 Server と同じ CreateFile なら動くよ、ってのを書いてみたが、本番環境では動かない。うーんまあ Windows 8 って言ってるから違うんだろうなぁと。 @ttuusskk が Windows 8 あるとのことで kernel32.dll をくれたのはいいが、どう見てもこれは 64bit バイナリでござる。

まぁ勉強もかねて Export Table 読むコード書くか、と書いた。ただ疲れていたので、無駄に時間がかかった。あと昔同じようなコード書いた記憶があるね…

そんでそれをアセンブリに手で変換。めんどくさいめんどくさい。。できた!と思うも動かない。まぁ Windows のバージョン依存はなくなっているので、自分の Windows 7 マシンで試してみると、たしかにクラッシュしている。

最初は shellcode 実行開始時点で ebp が腐っているという、自分の凡ミスだったんだけど、あとは gas の謎のバグとたたかっていた。なんでクラッシュするのーと windbg で step 実行していくとなぜか call が少しズレる。実際コード見てみるとズレてるので、なんか gas のバグだったんだと思う。 label のまわりに nop を入れまくって回避。 linux 上で windows バイナリ作って、それを windows にコピーして windbg 、ていうイテレーションがめんどくさくてめんどくさくて…

とまあ解けたけど気力が燃えつきた。

xorcise (Exploitation 500)

@tzik_tack が地道にがんばっていた。進捗を聞くと、 return address が書きかえられて、その下の stack に好きなデータを 128 byte だか書けるようになった、とか言っている。えっそれもうおわってるんじゃ…と思ってハラハラしてたんだけど、 greenhornd 終わって燃えつきかけだったので、進捗を共有してた docs を見てみる。

これはすごいなーと感心する。ループの中でループ変数が変わってて、これは大変だ、と思う。しかし感心するけど、ここまで行ったら、んーやはりこの問題終わってるように見えるよ…と手元で同じのを再現してみて、僕が pass 取れるコードを作ると同時くらいに @tzik_tack も終了。

あとはなんか簡単な手続きで flag をもらえたぽい。

hashes (Web 300)

何人かが頑張っていた。主に @mayahjp と @ttuusskk かな。 @mayahjp が jQuery が古いとか言うので、 jQuery脆弱性を僕がぐぐってみたところ、トップに CVE 。見てみると location.hash て書いてある。これじゃね、と言ったら @mayahjp がすごい勢いで色々やって flag をもぎとっていた。

weissman (Reverse Engineering 300)

aerosol can で燃えつきてないのがすごい @phoenixstarhiro が、地道にフォーマットを解釈していって、読みにくい jpg を復元して解いた。いやー感心した。

Fluffy No More (Forensics 300)

これも主に @mayahjp と @ttuusskk が色々探してた。諦めて @mayahjp が寝たあとで、少し僕も見てみるかとファイルを展開とかしてみる。多い!こんなもん見る気起きない、とあきらめる。しかし彼らの残した記録を読んでみると、なにやら不審な pdf の URL がある。

ファイル一つなら読む気力残ってるな、と pdf に決め打ってながめる。そういえば steganography 的なの見てないな、と画像を取り出したくなった。でもよく知ってる画像のヘッダは中に無いぽい。 dff-gui とかいうファイル解析ツールにかけてみる…が、 pdf はサポートされてないぽい気がした。

うーんどういうふうに画像入ってるのかな、と中身を lv でながめてると、どうも圧縮されてるらしい記述がある。そして圧縮されててすごくサイズが小さいところとかもある。これ flag 隠しそうな場所じゃね、と思う。

deflate を自分で展開するのがめんどくさかったので、適当にぐぐって調べてみる。ねむくて珍妙なコマンドラインインターフェイスの理解に時間がかかったけど、展開できた。あとは lv でふたたびながめてると \xXX\xXX と続く不審な文字列。ちょっと見るとこれ ASCII の範囲じゃん、と irb に入れたら flag ゲット。まぁ pdf 取るところまでをやったのがえらいと思う…

cfbsum (Cryptography 300) 解けなかった

@kinaba が最初の方考えてたけどわからないまま歩きに行ってしまったので、少しだけ遊んでみたりした。最初よくわからんなーという感じだったんだけど、 CFB でぐぐると、ああこういうのがあるのかと勉強になった。 initialization vector を guess するのかな、と思って、実際それがあってたぽい?ので、早い段階で CFB というのを理解してやってみていれば…と少し悔やまれる。

Feal (Cryptography 300) 解けなかった

omoikane さんががんばってたけど解けなかったようだった。この手のやつ解けた試しがないから write-up 読もうと思う…

Recon * 2

左はよくわからない。右は dota2 ならゲームっ子として解かねば!と思って色々探したけどわからなかった。

まとめ

チームでやると負担がかなり少ないなあと感じた。一人でやると、バイナリ読みたいけど、みんなが解いてるアレをやってみた方がいいかな…とか気が散るんだよね。というかチームでプログラミングコンテストに参加したのってはじめてな気がしますね…

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h