チームyharimaとして3年目のDEF CON CTF Quals参加。
411ポイントで170位。思った以上に問題を解くことができず無念。
バイナリコンテストとわかっていても、pwnの勉強が進まず今年も本番を迎えた感じ。
変遷
Year | Place | Point |
---|---|---|
2016 | 267 | 21 |
2017 | 102 | 171 |
2018 | 170 | 411 |
解けた問題について供養する。
You Already Know
誰もが取り組む第一問目。問題文のレスポンスの一部がフラグが含まれていた。
OOO{Sometimes, the answer is just staring you in the face. We have all been there}
ELF Crumble
関数の一部が無効なデータで書き換えられたバイナリ本体とバイナリの断片が8つ渡される。
渡された断片を見るとx86バイナリだったので8つをうまい具合につなぎ合わせて、バイナリ本体に埋め合わせる。
使ったスクリプトはこんな感じ。生成されたバイナリを実行するとフラグ。
import shutil
shutil.copy('broken', 'fixed')
fragment_order = [8, 7, 1, 5, 6, 2, 3, 4]
with open('fixed', 'r+b') as f:
f.seek(0x5ad)
for fo in fragment_order:
with open('fragment_%d.dat' % fo, 'rb') as fg:
f.write(fg.read())
$ ./fixed
welcOOOme
8つをまじまじと見つめながら順番を決めていたので、そんなことせずにブルートフォースで8つを総当たりで並べ替えて実行できるかどうかでやっちゃえばよかった。時短。
Easy Pisy
いい感じのPDFをつくってフラグを読むためのLinuxコマンドを食わせる問題。
まず、文字列が書かれた画像を含んでいるPDFを渡すと署名してくれる。
さらに署名とそのPDFを渡すと、PDFに含まれた文字列がEXECUTEで始まる場合はLinuxのコマンドの実行、ECHOで始まる場合はその文字列を出力する処理が走る。
EXECUTEのPDFを作って署名して食わせれば終わりかと思えば、署名は文字列がECHOで始まるものでなければならない。
処理の中身を見るとPHPのopenssl_verify関数とopenssl_sign関数を使って検証と署名をしていた。
また、デフォルトの署名アルゴリズムがSHA-1で結果が衝突するとかあったなーと思い出し、あ、これSHAtteredだと気づく。
コマンドの書かれた2枚の画像を作り https://github.com/sonickun/sha1-collider のスクリプトに通してPDF作成、ECHOの書かれたPDFを先に署名して、コマンド実行はその署名とEXECUTEの書かれたPDFを渡すとフラグが出てくる。
使った画像はこんなの。注意点は同じサイズの画像が必要ぐらい。
OOO{phP_4lw4y5_d3l1v3r5_3h7_b35T_fl4g5}
PHP Eval White-List
WebページとPHP Extensionのバイナリが渡される。(今回はちょこちょこPHP Extension出てた気がする)
WebページにはPHPのコードを書くことができるテキストボックスがあり、そこに処理を書くと実行してくれるらしい。問題としては「親ディレクトリにある ./flag を実行してくれ」というもの。
途中、 echo fread(popen(“cat tmp/flag”, “r”),1024);
をするとflagのような文字列が出てきたので「これや!」と思っておもむろに提出してみるもあえなく撃沈。
後から見返すと本物のフラグから1文字を書き換えたフラグだったようで、どこかの誰かがいたずらで置いたファイルだった。許すまじ。絶許。
PHPのExtensionを読み込ませたり、soバイナリ読んだりしてたけど結局チームメンバーが実行した以下のコマンドでフラグが取れた。
$a = []; $s; exec("../flag 2>&1", $a, $s); var_dump($a); var_dump($s);
↓
array(1) { [0]=> string(91) "OOO{Fortunately_php_has_some_rock_solid_defense_in_depth_mecanisms,_so-everything_is_fine.}" } int(0)
この時のやりとり。
- 自分「この文字列は見たことあるで、それフラグちゃうでー^^」
- メンバー「普通に投げたら正解でしたけど…」
- 自分「ファッ!?」
絶許。
sbva
解けなかった。一番時間を溶かしたので忘れぬよう書いておく。
Webページにアクセスして適切なユーザーエージェントを指定してあげるとフラグが返って来る問題。レスポンスのJSに navigator.battery.charging が含まれていたので「これはモバイルのUA投げれば勝つる!」と思っていたのが運の尽き。
実は他にもブラウザ依存のタグやらヘッダやらがあったらしく、それもパスしないとフラグが返ってこなかったらしい。レスポンスは良く見るべきでしたね。。。
普段と違ったレスポンスがないか注意してみていこう。
レスポンスはこちら。読んだみなさんはどこが怪しいかわかりますか?
わかったあなたはCTF向いているのでぜひやりましょう。
< HTTP/1.1 100 Continue
< HTTP/1.1 302 Found
< Server: nginx/1.10.3 (Ubuntu)
< Date: Sun, 13 May 2018 06:14:32 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: PHPSESSID=bhklpohlr8hr75faf46pdgjea6; path=/
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate
< Pragma: no-cache
< Content-Security-Policy: upgrade-insecure-requests
< Location: wrongbrowser.php
<
<html>
<style scoped>
h1 {color:red;}
p {color:blue;}
</style>
<video id="v" autoplay> </video>
<script>
if (navigator.battery.charging) {
console.log("Device is charging.")
}
</script>
</html>
今回はpwn1問もわからなかったので勉強します。年々レベルが上がっててつらい。
今年もお疲れ様でした。