
Linux ELF x32/x64 下的 ASLR 与 DEP/NX 绕过利用(堆栈喷射)
Linux ELF x32/x64 ASLR DEP/NX 绕过利用,采用栈喷射技术

属性:
依赖条件:
局限性:
你可能听说过堆喷射攻击?嗯,栈喷射与其类似,但在大多数情况下被认为不实用,尤其是在 x86-64 上的ASLR。
我的工作将证明相反。
对于32位系统,理论上有2^32(4 294 967 296)个地址,然而,内核在虚拟化内存中执行时,仅允许控制大约一半的位(2^(32/2) = 65 536),这意味着如果我们能在栈中控制超过50 000个字符,几乎可以肯定能指向我们的shellcode,无论地址如何,这得益于内核的重定向和重翻译。根据我的测试,如果被调用的函数不包含其他变量创建,甚至100或10个字符就足够了,这将允许ROP风格的攻击。
这可以通过shell变量实现,它们实际上没有特定的长度限制,但实际限制大约为十万个字符,否则会使TTY饱和。
因此,为了使用任意shellcode成功利用,我们需要将NOP sled放在shellcode之后并放入shell变量,然后只用随机地址利用二进制文件。注意,NOP sled并非必需,这只是为了使利用更具通用性。
在64位系统中,情况有所不同,但据我发现的并非如此之大。
当然,你不需要覆盖所有2^64种可能性,事实上,内核只允许48位,加上其中一部分是可预测且静态的,这给我们留下了大约2^(4x8+5)(137 438 953 472)种可能性。
我已经提到了shell变量的大小限制,但还有一个计数限制,似乎是大约10个,因此允许我们存储一个1 000 000字符的shellcode,只留下大约几万种可能性,可以快速自动测试。然而,这次你需要暴力破解并使用NOP sled来加快速度。
也就是说,32位和64位上的ASLR都可以在几分钟内用几行shell轻松绕过...
另一方面,DEP/NX可以在x32上使用return-to-libc技术绕过,结合对不同操作系统的统计研究,更具体地说,它们的ASLR限制和实现,这可以出于两个原因导致成功利用。 第一个原因是ASLR在它的选择上并非那么随机,并且有一些常量和较差的熵(容易猜测libC地址,每个操作系统都有自己的常量)。 第二个原因是将用于libC的shell参数喷射到环境中(容易找到并将其传递给libC)。
总之,32位上的DEP/NX因为ASLR而被削弱。
更详细的描述可以在Hakin9-12-14期刊中找到。
如果你一生中至少利用过一次缓冲区溢出,可以跳过,但以防万一:
apt install gcc libc6-dev-i386 || kill -9 $$
chmod u+x ASLRay.sh
sudo gcc -z execstack test.c -o test
sudo gcc -m32 -z execstack test.c -o test32
sudo chmod +s test test32
source ASLRay.sh test32 1024
source ASLRay.sh test 1024
source ASLRay.sh test 1024 \x31\x80...your_shellcode_here
sudo gcc -m32 test.c -o test32x
sudo chmod +s test test32
source ASLRay.sh test32x 1024
为了证明在Debian x32上NOP sled不是必需的:
!!!警告!!! 这会修改你的/etc/passwd并改变/etc/shadow的权限,建议在虚拟机中执行
chmod u+x PoC.sh
source PoC.sh
grep ALI /etc/passwd
如果仍然不起作用,只需在开头添加一些NOP(\x90)。
证明在Debian x32上甚至环境变量也不是必需的:
chmod u+x PoC2.sh
source PoC2.sh
因此,你可以直接将shellcode放入一个变量中,并向寄存器提供随机地址,以获得带有ASLR的shell,这是因为特定上下文中函数只有一个变量,它将被重写,所以栈只会弹出到EIP,这更像是ROP攻击。
对于Arch/Ubuntu,你还需要禁用栈破坏保护,并且暴力破解可能需要更长时间(执行延迟,可能是由于brk(NULL/0)系统调用和/或canary):
sudo gcc -z execstack -fno-stack-protector test.c -o test
sudo gcc -m32 -z execstack -fno-stack-protector test.c -o test32
sudo gcc -m32 -fno-stack-protector test.c -o test32x
在Debian 10中,这个问题已部分修补,特别是由于AppArmor。
始终依赖多重保护,而不是单一保护。
我们需要新的系统安全机制。
“从我们站立的地方看,雨似乎是随机的。如果我们能站在别处,就会看到其中的秩序。”
托尼·希勒曼,郊狼在等待