きゅうり。

主にCTF関係のことを書いていく気がします

Tokyo Westerns/MMA CTF 2nd 2016 greeting writeup

いわゆるpwn challenges listを片っ端からやっていこうというやつ。

実は前に15問ぐらい解いたものの、半年?くらい暗号以外触っていなかったのでリハビリも兼ねて最初からやる。

ところでwebもやりたいんだけど、問題が生きてないからつらい。

greeting

挙動

名前入力を求められ、入力すると返事が来ておしまい。単純。

$ ./greeting
Hello, I'm nao!
Please tell me your name... Kyuri
Nice to meet you, Kyuri :)

脆弱性

パッと思いつくのはバッファオーバーフローだが、適当に入力してみてもできないことがわかる。

そこで詳しく見てみると、最後の Nice to meet you, Kyuri :) の処理が怪しいことに気づく。

sprintf で Nice to meet you, に入力した文字列をくっつけた後にprintfで出力する。

つまり、Format String Bugがある。

解法

内部にnaoという関数があり、systemが呼ばれている。

そこで方針としては、GOT overwriteで何かしらの関数をsystemに飛ばすことを考える。

書き換える候補としては、自由に引数を渡しやすい(入力がそのまま引数となる)strlenとなる。

が、これを実現するためにはプログラムを2周する必要がある。

1周目でGOT overwriteをした後に2周目で/bin/shを入力するとstrlen(system)が呼ばれる。

あとはどのようにループさせるかだが、printfの後に呼ばれるものがない。

(__stack_chk_failはあるが、オーバーフローしないため呼ばれない)

結論としてはデストラクタ(.fini_array)を書き換えることになる。

デストラクタはプログラム終了時に必ず呼ばれ、今回はこれが書き込み可能領域にある。

なのでデストラクタを書き換えてmainにもう一度飛ばしてやればよい。

 

$ python solver.py
Nice to meet you, AA
(snip)
AA6RP4 :)
Please tell me your name... /bin/sh
id
uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant)
exit
Nice to meet you, /bin/sh
 :)
*** Connection closed by remote host ***