我正在尝试一些安全性的东西,特别是试图理解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
对应缓冲区的64个字符在这里,但其余的没有写入...我不知道为什么?是否由于某种更新?
编辑:buff的GDB日志[64]
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:GDB日志为buff [20]
(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]
答案 0 :(得分:3)
我想我想出来了,至少对于64缓冲区来说。您的计数变量i位于堆栈上比缓冲区更高(根据您的反汇编)。这意味着,您的第65个商店更改了i的值。请注意,它不是i的整个值,因为它可能是一个4字节的整数;所以只有低位字节(little-endian)。在任何情况下,之后,就好像你足够计数,下一个写(66)应该指向由环境变量(过去的ret)填充的区域,这是无害的并且不会污染eip。
我的击球几乎完成了,我无法严格完成。但请按照以下思路思考。
编辑/交叉击球手指:同样,第66次写入可能已经拉入0,因为双方都受到i的污染(你将它存储在相对于&amp;缓冲区;在那里你从相对于argv读取它[1] [0]。