我现在正在做io-wargames的乐趣,level3:
我确实理解为什么此代码中存在堆栈溢出(strlen(argv[1])
),但我不明白的是为什么它会溢出函数指针functionpointer
。
functionpointer
之前char buffer[50];
在堆栈上声明过,所以它是如何覆盖它的???
这是主要的易受攻击代码:
int main(int argc, char **argv, char **envp)
{
void (*functionpointer)(void) = bad;
char buffer[50];
if(argc != 2 || strlen(argv[1]) < 4)
return 0;
memcpy(buffer, argv[1], strlen(argv[1]));
memset(buffer, 0, strlen(argv[1]) - 4);
printf("This is exciting we're going to %p\n", functionpointer);
functionpointer();
return 0;
}
这是shell利用stackoverflow:
level3@io:~$ /levels/level03 11111111
This is exciting we're going to 0x80484a4
I'm so sorry, you're at 0x80484a4 and you want to be at 0x8048474
level3@io:~$ /levels/level03 111111111111111111111111111111111111111111111111111111111111111111111111111111111
This is exciting we're going to 0x31313100
Segmentation fault
这是objump -d
可执行文件的:
080484c8 <main>:
80484c8: 55 push %ebp
80484c9: 89 e5 mov %esp,%ebp
80484cb: 83 ec 78 sub $0x78,%esp
80484ce: 83 e4 f0 and $0xfffffff0,%esp
80484d1: b8 00 00 00 00 mov $0x0,%eax
80484d6: 29 c4 sub %eax,%esp
80484d8: c7 45 f4 a4 84 04 08 movl $0x80484a4,-0xc(%ebp)
80484df: 83 7d 08 02 cmpl $0x2,0x8(%ebp)
80484e3: 75 17 jne 80484fc <main+0x34>
80484e5: 8b 45 0c mov 0xc(%ebp),%eax
80484e8: 83 c0 04 add $0x4,%eax
80484eb: 8b 00 mov (%eax),%eax
80484ed: 89 04 24 mov %eax,(%esp)
80484f0: e8 a7 fe ff ff call 804839c <strlen@plt>
80484f5: 83 f8 03 cmp $0x3,%eax
80484f8: 76 02 jbe 80484fc <main+0x34>
80484fa: eb 09 jmp 8048505 <main+0x3d>
80484fc: c7 45 a4 00 00 00 00 movl $0x0,-0x5c(%ebp)
8048503: eb 74 jmp 8048579 <main+0xb1>
8048505: 8b 45 0c mov 0xc(%ebp),%eax
8048508: 83 c0 04 add $0x4,%eax
804850b: 8b 00 mov (%eax),%eax
804850d: 89 04 24 mov %eax,(%esp)
8048510: e8 87 fe ff ff call 804839c <strlen@plt>
8048515: 89 44 24 08 mov %eax,0x8(%esp)
8048519: 8b 45 0c mov 0xc(%ebp),%eax
804851c: 83 c0 04 add $0x4,%eax
804851f: 8b 00 mov (%eax),%eax
8048521: 89 44 24 04 mov %eax,0x4(%esp)
8048525: 8d 45 a8 lea -0x58(%ebp),%eax
8048528: 89 04 24 mov %eax,(%esp)
804852b: e8 5c fe ff ff call 804838c <memcpy@plt>
8048530: 8b 45 0c mov 0xc(%ebp),%eax
8048533: 83 c0 04 add $0x4,%eax
8048536: 8b 00 mov (%eax),%eax
8048538: 89 04 24 mov %eax,(%esp)
804853b: e8 5c fe ff ff call 804839c <strlen@plt>
8048540: 83 e8 04 sub $0x4,%eax
8048543: 89 44 24 08 mov %eax,0x8(%esp)
8048547: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp)
804854e: 00
804854f: 8d 45 a8 lea -0x58(%ebp),%eax
8048552: 89 04 24 mov %eax,(%esp)
8048555: e8 02 fe ff ff call 804835c <memset@plt>
804855a: 8b 45 f4 mov -0xc(%ebp),%eax
804855d: 89 44 24 04 mov %eax,0x4(%esp)
8048561: c7 04 24 c0 86 04 08 movl $0x80486c0,(%esp)
8048568: e8 3f fe ff ff call 80483ac <printf@plt>
804856d: 8b 45 f4 mov -0xc(%ebp),%eax
8048570: ff d0 call *%eax
8048572: c7 45 a4 00 00 00 00 movl $0x0,-0x5c(%ebp)
8048579: 8b 45 a4 mov -0x5c(%ebp),%eax
804857c: c9 leave
804857d: c3 ret
804857e: 90 nop
804857f: 90 nop
我看到编译器在 main 的 prolog 函数帧0x78
字节中为本地 main 函数变量保留了字节。