fr33f0r4llスマートフォン用の表示で見るfr33f0r4ll自分用雑記この広告は、90日以上更新していないブログに表示しています。exploitationのお勉強、初めてWriteup途中で見ずに解けて嬉しい。参考にしたのはshellphishのhow2heap。解く上でlibcが必要になるが、Hintととして動作環境が出されているし脆弱性を突けば任意のGOT領域の関数アドレスを表示できるので、該当するlibcのバージョンを特定して入手するのは容易のはず。今回はそれを省いてローカルのlibcをいきなり使っている。問題stkofというバイナリだけが降ってくる。fileとchecksecの出力は以下。(0x400000)普通の64bitバイナリといった感じになっている。動作させてみると、何も出力されず何をしていいか分からなかった。リバーシングしてみたところ、ほとんど何も出力しないが入力は受け付けるようになっていた。解析しないことには動作させることもままならなかったので、手動デコンパイルした。0;}1から4までの数字を受け付けて、malloc、キー入力、free、長さのチェックができることが分かる。キー入力で長さのチェックがないため、ヒープでのバッファオーバーフローが存在していることが分かる。mallocしたチャンクはグローバル領域の配列で管理されていて、ASLRでもアドレスがランダム化されない。freeするとアドレスは0クリアされるので、double-freeはできない。unlinkという手法を使う。mallocしたチャンクを書き換えてfree済みであると誤認させ、unlinkという機能を使わせることによって、あるメモリ領域を書き換えることができるという手法である。手法自体はhow2heapとかkatagaitaiのスライドとかに解説がある。unlinkで、unlinkするチャンクのアドレスが格納されている場所を、その場所から0x18上ぐらいの位置のアドレスに書き換えることができる。配列にチャンクが格納されていることと併せて考えると、配列の中身を配列自身のアドレスに書き換えられることになる。すると、配列に格納されたアドレスへの書き込みで配列中のアドレスを任意の値に設定できるので、任意のアドレスへの書き込みができることになる。これを利用してfree@GOTをputs@PLTに書き換えたあと、配列中のアドレスをGOTに設定することで関数アドレスを表示させたり、smallbinを指すfdを表示させたりして、libcベースをリークさせる。smallbinを指すfdを表示させる方法を使った。RCEを呼び出してシェルを起動すればいい。呼び出しは、libcベースのリークと同じように適当なGOTの関数アドレスを書き換えてやればいい。putsを途中で書き換えるためタイムアウトさせる。PREV_INUSEを1にする(2はunlinkしないので)。userdata、余った領域を適当に埋める。oneshot_rceio.interactive()libc内のオフセットは環境によって違うので適宜読み替えて欲しい。まとめ初めてほぼ自力で解けたのでとても嬉しい。unlinkを使っていたのもあって、解法を簡単に思い付けた。やっている最中にチャンクのサイズとかヒープのレイアウトとかも間違えていたりしたので、まだまだ練習が必要だと感じた。速く解くことを目標にする。(1)はてなブログをはじめよう!hiziriAIさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。