我一直在讨论 GNU libc 的fclose()
功能在没有指向 FILE 数据结构的有效指针的情况下调用时阻止成功利用由于分段错误而导致的微不足道的漏洞的有效性(libc 在其他操作系统上的实现会静默失败)。例如,给定一个简单的易受攻击的函数,strcpy()
例如:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void
foo(const char *str)
{
char buffer[256];
int ret = 123456;
FILE *fp = tmpfile();
strcpy(buffer, str);
if (ret != 500)
fclose(fp);
}
int
main(int argc, const char **argv)
{
foo(argv[1]);
return 0;
}
即使在禁用大多数内存保护机制的情况下进行编译:
cc -m32 -ggdb -fno-stack-protector -z execstack -z norelro main.c
该函数,无论是否被覆盖EIP
都不会返回,因为:
(gdb) r $(python -c "print 'A' * 286")
Program received signal SIGSEGV, Segmentation fault.
0xf7e3e307 in fclose@@GLIBC_2.1 () from /lib/libc.so.6
(gdb) ba
#0 0xf7e3e307 in fclose@@GLIBC_2.1 () from /lib/libc.so.6
#1 0x080484bc in foo (str=0x41414141 <error: Cannot access memory...
#2 0x41414141 in ?? ()
#3 0x41414141 in ?? ()
有没有办法实现这种微不足道的功能的代码执行?由于该ret
变量可以被覆盖,是否可以将其设置为 500 以便fclose()
可以绕过确定是否调用的 if 条件?