我正在试验一些安全方面的东西,尤其是试图了解 ret2ret 漏洞利用。 我正在试验的代码:
void foo(char * val){
char buffer[64];
int i;
for (i=0; val[i]!=0; i++) buffer[i]=val[i];
return;
}
int main(int argc, char ** argv) {
foo(argv[1]);
return 0;
}
ASLR、N^X 和堆栈金丝雀在我的测试期间关闭。我用 gcc 将它编译成 32 位。 我不知道为什么,但我无法得到通常的“0x41414141 in ?? ()”,说我已经覆盖了 $eip。所以我决定用 gdb 调试并在函数“cop”的 ret 上放置一个断点,奇怪的是,即使在写了超过 300 个“A”之后,堆栈仍然是这样的:
0xbffff46c: 0xb7ee2290 0xbffff496 0xb7e8f5f5 0x41414141
0xbffff47c: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff48c: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff49c: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff4ac: 0x41414141 0x41414141 0x41414141 0x00410043
buffer 对应的 64 个字符在这里,但其余的没有写..我不知道为什么?是因为某种更新吗?
编辑:buff[64] 的 GDB 日志
Dump of assembler code for function main:
0x08048415 <+0>: push %ebp
0x08048416 <+1>: mov %esp,%ebp
0x08048418 <+3>: sub $0x4,%esp
0x0804841b <+6>: mov 0xc(%ebp),%eax
0x0804841e <+9>: add $0x4,%eax
0x08048421 <+12>: mov (%eax),%eax
0x08048423 <+14>: mov %eax,(%esp)
0x08048426 <+17>: call 0x80483dc <foo>
0x0804842b <+22>: mov $0x0,%eax
0x08048430 <+27>: leave
0x08048431 <+28>: ret
Dump of assembler code for function foo:
0x080483dc <+0>: push %ebp
0x080483dd <+1>: mov %esp,%ebp
0x080483df <+3>: sub $0x44,%esp
0x080483e2 <+6>: movl $0x0,-0x4(%ebp)
0x080483e9 <+13>: jmp 0x8048404 <foo+40>
0x080483eb <+15>: mov -0x4(%ebp),%edx
0x080483ee <+18>: mov 0x8(%ebp),%eax
0x080483f1 <+21>: add %edx,%eax
0x080483f3 <+23>: movzbl (%eax),%eax
0x080483f6 <+26>: lea -0x44(%ebp),%ecx
0x080483f9 <+29>: mov -0x4(%ebp),%edx
0x080483fc <+32>: add %ecx,%edx
0x080483fe <+34>: mov %al,(%edx)
0x08048400 <+36>: addl $0x1,-0x4(%ebp)
0x08048404 <+40>: mov -0x4(%ebp),%edx
0x08048407 <+43>: mov 0x8(%ebp),%eax
0x0804840a <+46>: add %edx,%eax
0x0804840c <+48>: movzbl (%eax),%eax
0x0804840f <+51>: test %al,%al
0x08048411 <+53>: jne 0x80483eb <foo+15>
0x08048413 <+55>: leave
0x08048414 <+56>: ret
(gdb) b *foo+56
Breakpoint 1 at 0x8048414: file exploit.c, line 9.
(gdb) r `python -c 'print "A"*64'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/prog `python -c 'print "A"*64'`
Breakpoint 1, 0x08048414 in foo (arg=0xbffff6da 'A' <repeats 64 times>) at exploit.c:9
9 }
(gdb) r `python -c 'print "A"*65'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/prog `python -c 'print "A"*65'`
Program received signal SIGSEGV, Segmentation fault.
0x0804840c in foo (arg=0xbffff6d9 'A' <repeats 65 times>) at exploit.c:6
6 for(i = 0; arg[i] != 0; i++) buff[i] = arg[i];
编辑 2:buff[20] 的 GDB 日志
(gdb) disas foo
Dump of assembler code for function foo:
0x080483dc <+0>: push %ebp
0x080483dd <+1>: mov %esp,%ebp
0x080483df <+3>: sub $0x18,%esp
0x080483e2 <+6>: movl $0x0,-0x4(%ebp)
0x080483e9 <+13>: jmp 0x8048404 <foo+40>
0x080483eb <+15>: mov -0x4(%ebp),%edx
0x080483ee <+18>: mov 0x8(%ebp),%eax
0x080483f1 <+21>: add %edx,%eax
0x080483f3 <+23>: movzbl (%eax),%eax
0x080483f6 <+26>: lea -0x18(%ebp),%ecx
0x080483f9 <+29>: mov -0x4(%ebp),%edx
0x080483fc <+32>: add %ecx,%edx
0x080483fe <+34>: mov %al,(%edx)
0x08048400 <+36>: addl $0x1,-0x4(%ebp)
0x08048404 <+40>: mov -0x4(%ebp),%edx
0x08048407 <+43>: mov 0x8(%ebp),%eax
0x0804840a <+46>: add %edx,%eax
0x0804840c <+48>: movzbl (%eax),%eax
0x0804840f <+51>: test %al,%al
0x08048411 <+53>: jne 0x80483eb <foo+15>
0x08048413 <+55>: leave
0x08048414 <+56>: ret
End of assembler dump.
(gdb) b *foo+56
Breakpoint 1 at 0x8048414: file exploit.c, line 9.
(gdb) r `python -c 'print "A"*200'`
Starting program: /root/prog `python -c 'print "A"*200'`
Breakpoint 1, 0x08048414 in foo (arg=0xbffff652 'A' <repeats 200 times>) at exploit.c:9
9 }
(gdb) c
Continuing.
[Inferior 1 (process 3474) exited normally]
最佳答案
我想我明白了,至少对于 64 位缓冲区而言。您的计数变量 i 在堆栈中的位置高于缓冲区(根据您的反汇编)。这意味着,您的第 65 家商店更改了 i 的值。请注意,它不会是 i 的全部值,因为它可能是一个 4 字节整数;所以只有低字节(小字节序)。无论如何,之后,就好像你把 i 算得足够多了,下一次写入(66)应该指向环境变量(过去的 ret)填充的区域,这是无害的,不会污染 eip。
我的击球快完成了,我不能严格地完成这个。但请按照这些思路思考。
编辑/交叉 batt 手指:另外,第 66 次写入可能已经拉入 0,因为双方都受到 i 污染的影响(你将它存储在相对于 &buffer; 你从相对于 argv[1 读取它的地方) ][0].
关于c - 无法写入堆栈(堆栈溢出),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21504107/