我正在尝试使用 NOP 雪橇绕过 ASLR。这是 vuln() 的程序集,抱歉我没有源代码:
0804878a <vuln>:
804878a: 55 push %ebp
804878b: 89 e5 mov %esp,%ebp
804878d: 53 push %ebx
804878e: 81 ec a4 00 00 00 sub $0xa4,%esp
8048794: e8 77 fe ff ff call 8048610 <__x86.get_pc_thunk.bx>
8048799: 81 c3 67 18 00 00 add $0x1867,%ebx
804879f: 83 ec 0c sub $0xc,%esp
80487a2: 8d 85 64 ff ff ff lea -0x9c(%ebp),%eax
80487a8: 50 push %eax
80487a9: e8 52 fd ff ff call 8048500 <gets@plt>
80487ae: 83 c4 10 add $0x10,%esp
80487b1: 83 ec 0c sub $0xc,%esp
80487b4: 8d 85 64 ff ff ff lea -0x9c(%ebp),%eax
80487ba: 50 push %eax
80487bb: e8 80 fd ff ff call 8048540 <puts@plt>
80487c0: 83 c4 10 add $0x10,%esp
80487c3: 8b 83 fc ff ff ff mov -0x4(%ebx),%eax
80487c9: 8b 00 mov (%eax),%eax
80487cb: 83 ec 0c sub $0xc,%esp
80487ce: 50 push %eax
80487cf: e8 1c fd ff ff call 80484f0 <fflush@plt>
80487d4: 83 c4 10 add $0x10,%esp
80487d7: 90 nop
80487d8: 8b 5d fc mov -0x4(%ebp),%ebx
80487db: c9 leave
80487dc: c3 ret
二进制是 32 位的,堆栈是可执行的,所以我决定使用 NOP sled。我的有效载荷如下:
'A'*160 + return address + '\x90'*1024 + shellcode
如果我的理解是正确的,如果我多次运行漏洞利用,返回地址可能会指向 NOP sled 中的某个位置,这将导致处理器执行我的 shellcode。
但是,我不知道如何近似返回地址。我尝试使用 gdb 二进制文件,它告诉我原始返回地址是 0xfc3fc758,所以我只使用该值。当我将有效负载提供给二进制文件时,它会以 SIGSEGV 退出。
[*] Process './vuln5' stopped with exit code -11 (SIGSEGV) (pid 9240)
经过一些调试后,我发现 vuln() 返回时会引发段错误,因此我尝试仅提供垃圾字节以查看发生了什么。事实证明,任何超过 152 字节的填充都会导致段错误,但我不知道为什么。我认为 160 字节必须是正确的,因为程序集告诉缓冲区从 ebp-0x9c 开始。
那么我是否正确使用了 NOP 雪橇?我怎样才能近似返回地址?