ED CTF my_sandbox writeup
解いたのでwriteupです。
プログラムとlibcが渡されてます。
事前確認
$ ./my_sandbox Your name please: hoge Welcome to my echo program! This program has an bug. I couldn't fix this bug... :( But, I developed sandbox for this bug. Hackers will never be able to get shell, haha! :) Enter your message: 1 Entered: 1 (snip) Enter your message: 10 Entered: 10 It seems cracker couldn't crack my program, I'm winner! See you.
入力をそのまま返すのを10回繰り返すようなプログラム。バグがあるけどsandbox化してやったからシェルとれないやろ???みたいなやつ。
バグがあると言っている通り、FSBがあります。
続いてchecksec
CANARY : disabled FORTIFY : disabled NX : disabled PIE : disabled RELRO : FULL
方針
FSBがあるので、まずは素直にlibcのアドレスをリークします。この時点で最後はret2libcに帰着しそうなことがなんとなくわかります。
あとはreturnアドレスを書き換えるためにスタックのアドレスをリークする必要があります。しかし、sandbox化(?)により、FSBは通常のスタックではなくmallocによって確保された領域(擬似スタックと呼称)で発生します。なので、都合よくリークできそうなアドレスが積まれていません。
ここで擬似スタックがlibcの直前にあることに注目すると、libcのベースアドレスから、入力した値が積まれる擬似スタックのアドレスが計算できます。そして計算したアドレスからsnprintfの第一引数にあたるアドレスを計算しリークさせることでスタックのアドレスがリークできます。
これを図解すると、snprintf(buf,size,user_input);
が呼ばれる際の擬似スタックは、
addr_buf size addr_user_input xxx xxx xxx xxx xxx user_input
となっており、libcのベースアドレスからuser_inputのアドレスが計算できます。これが計算できるということは通常のスタックにあるbufのアドレス、つまりaddr_bufが計算できるためスタックのアドレスもリークできます。
ここまでできたら後はリークしたスタックのアドレスからreturnアドレスの場所を計算して書き換えてsystemを呼んで終了。