【发布时间】:2014-10-14 12:47:02
【问题描述】:
更具体地说,为什么/如何做到这一点?我在我的 Mac 上处理缓冲区溢出问题,我编写了一个程序 genv 来输出环境变量的内存地址。我最终得到了 3 个不同的地址(显然这些地址会随着每次运行而改变 - 这不是这里发生的情况)
SHELLCODE ADDR 1) 我从命令行运行程序
ben:~/scripts$ genv SHELLCODE
SHELLCODE &0x7fff5c455d3d
SHELLCODE ADDR 2) 我通过 LLDB 运行程序并在设置一些断点后检查寄存器
ben:~/scripts$ lldb genv SHELLCODE
### intermediary steps
(lldb) x/2s $rsp+0x137
0x7fff5fbffd3f: "PROGRAM=Apple_Terminal"
0x7fff5fbffd56: "SHELLCODE=helloworld"
SHELLCODE ADDR 3) 我从断点继续,让 genv 输出到 stdout
(lldb) c
Process 2748 resuming
SHELLCODE &0x7fff5fbffd60
Process 2748 exited with status = 0 (0x00000000)
所以 SHELLCODE 的 2) 和 3) 地址相差 10
ben:~$ python -c 'print hex(0x7fff5fbffd60 - 0x7fff5fbffd56)'
0xa
但是 2) 和 1) 差别更大
ben:~$ python -c 'print hex(0x7fff5fbffd60 - 0x7fff5c455d3d)'
0x37aa023
下面是我的 genv 程序
// genv.c
// print address in memory of environment vars
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
int i;
if (argc == 1)
{
printf("Improper Usage: No env args\n");
exit(-1);
}
for (i = 1; i < argc; i++)
printf("%-36s%p\n", argv[i], getenv(argv[i])); // Format into columns w/ "%-36s"
return 0;
}
显然,当它在 LLDB 中运行时,genv 的堆栈是在不同的地方构建的,我想这是有道理的(这是为了让缓冲区溢出和其他以内存为目标的黑客更难还是完全不同的东西?)。但是 - 为什么在同一次运行中注册检查和实际打印到标准输出之间会有 10 的偏移量?
【问题讨论】:
-
0x37aa023 (2) 和 (1) 之间的差异几乎可以肯定是由于address space layout randomization。
-
好吧,这就是我的想法。那么我该如何解决呢? ;)
-
您可以通过将
-no_pie选项传递给链接器(或等效地将-Wl,-no_pie传递给编译器,然后编译器将其传递给链接器)来禁用您自己构建的可执行文件中的ASLR,尽管通常不建议这样做,除非作为实验练习。当然,如果你想利用一个用 ASLR 编译的可执行文件,那就更难绕过了。 -
大声笑,我想这就是重点。谢谢
-
默认情况下,lldb(以及之前的 gdb)会为在 OS X 的调试器下运行的程序禁用 ASLR。您可以通过“settings set target.disable-aslr false”关闭调试器中的禁用 aslr。但默认是禁用它。