Protostar Heap3 Write-up
Heap 3
#include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <stdio.h> void winner() { printf("that wasn't too bad now, was it? @ %d\n", time(NULL)); } int main(int argc, char **argv) { char *a, *b, *c; a = malloc(32); b = malloc(32); c = malloc(32); strcpy(a, argv[1]); strcpy(b, argv[2]); strcpy(c, argv[3]); free(c); free(b); free(a); printf("dynamite failed?\n"); }
dwordshoot攻击
按照liveoverflow中的解法
Gdb导入heap3,设置下显示格式

在第三个strcpy,在第一个free处,和puts处设置共三个断点


传入参数ABC

C执行到第一个断点,赋值后,查看堆空间内容,ABC传入

首先设置第二个参数B,将空间扩展为0x64,并保存在文件中
B*36+\x65

gdb测试

B值已经正常传入

然后设置C参数

根据call puts语句找到GOT表地址,然后减去12的长度得到地址0x804b11c

构造参数C,使得puts后可以调用shellcode
(共有92个C)


最后需要写shellcode,放在参数A中
找winner地址在0x08048864

Shellcode为:
mov eax, 0x08048864 call eax
转化为shellcode string形式
“\xB8\x64\x88\x04\x08\xFF\xD0”
设置参数A

运行r `cat /tmp/a` `cat /tmp/b` `cat /tmp/c`
执行两次c来到断点,然后si调试,放入的shellcode地址0x0804c008指令发生变化了,why?

查看堆内容,因为free()操作释放了三次,会将此地址处原有内容覆盖掉

修改参数C的shellcode地址,然后将参数A进行填充

再次执行调试,执行到winner()函数

C键执行,输出溢出结果

在gdb之外执行也是ok的

参考资料:
https://conceptofproof.wordpress.com/2013/11/19/protostar-heap3-walkthrough/
http://www.pwntester.com/tag/heap4/
https://gist.github.com/mgeeky/2eea516d7ad732d9f02f530688f55912