HackIT CTF 2018 writeup
はじめに
TokyoWesternsで参加した。 結果は8731点の2位だった。 トップ5にはHackITのカンファレンスチケットが貰えて、さらにトップ3にはスポンサーから何かしらのソフトウェアのライセンスが貰えるらしい。 自分はArmy, A Heap Interface, Bank Reimplemented, KAMIKAZE, HashManを解いた。つまりpwnを全完した。 良い問題だったので楽しかった。
Army
実行すると3つの選択肢を選ぶことができる。Beginner's Luck
としてlibcのアドレスを教えてくれるので、アドレスリークは必要ない。
Join the Army
でmalloc()
に失敗するようなサイズを入れると、heap上に持っているサイズと、bssで保持しているサイズが合わなくなる。
なのでalloc()
とread()
で呼ばれるサイズが異なり、stack bofを起こせる。
canaryはなくlibcのアドレスは既に得られているので、ropをする。
A Heap Interface
unsortedbin attackをglobal_max_fastに対して行う。通常0x80までがfastbinsに入るが、0x90以上のサイズのチャンクもfastbinsに入るようになる。あとは適当にlibcのアドレスをリークさせて、_dl_open_hook
に適当な値を書き込んでstdoutのvtableを上書きして制御を取った。
HackIT CTF 2018 HashMan · GitHub
Bank Reimplemented
直下のチャンクのサイズを1byteだけ書き換えることができるのでチャンクをオーバーラップさせる。__malloc_hook
は監視されているので、FSOPで_IO_str_jump
を使って制御を取った。
HackIT CTF 2018 Bank Reimplemented · GitHub
KAMIKAZE
MMAPEDビットを立ててcalloc()が0初期化しないようにする。calooc()の初期化が起きないと未初期化バグが発現する。
HackIT CTF 2018 KAMIKAZE · GitHub
HashMan
race conditionとtype confusion。sha1の処理で用いる構造体をxorの処理で用いる構造体に見せかけるために、race conditionを使う。 別スレッドでは同一のkeyがあるか定期的に確認しており、同一のkeyが登録されているとkeyを消す処理が実行される。これはkeyを0にすることと同じであり、xorのkeyの制限範囲と合致する。 同じkeyのsha1を2つ作り、edit/print時のkey入力時に別スレッドの処理を待つことでrace conditonが発動する。