読者です 読者をやめる 読者になる 読者になる

きゅうり。

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

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を呼んで終了。