为什么环境变量的位置变化如此大?


9

阅读乔恩·埃里克森(Jon Erickson)的《黑客:利用的艺术》一书,我正在尝试估算环境变量的地址SHELLCODE以利用程序。

每次我跑到getenv("SHELLCODE");位置时,结果都是完全不同的。

从我的外壳中提取:

> for i in $(seq 10); do ./a.out SHELLCODE; done
SHELLCODE is at 0xff9ab3a3
SHELLCODE is at 0xffcdb3a3
SHELLCODE is at 0xffb9a3a3
SHELLCODE is at 0xffa743a3
SHELLCODE is at 0xffdb43a3
SHELLCODE is at 0xfff683a3
SHELLCODE is at 0xffef03a3
SHELLCODE is at 0xffc1c3a3
SHELLCODE is at 0xff85a3a3
SHELLCODE is at 0xff8e03a3

我了解如果修改了程序名称或添加了新的环境变量,则位置会稍有不同,但是为什么位置会有很大的不同?


getenv手册说它返回一个指向包含变量值的字符串的指针。其他所有内容均未指定,因此您的内核和/或编译器可以将值粘贴在所需的任何位置,只要该指针承诺始终为真即可。我猜想确切的答案可能是沉重的巫术,取决于各种内存映射实现细节和月相。(我还不够向导,无法为您提供确切的答案。)
Anko

“我知道,如果程序名称被修改或添加了新的环境变量,位置将稍有不同,但是为什么位置会有如此大的差异?” 在所有可能的实现中,最简单的实现是正确的,但肯定不是必需的。
dmckee ---前主持人小猫,2014年

Answers:


13

您所描述的是一种称为地址空间布局随机化(ASLR)的反利用功能。基本上,每次内核从磁盘加载程序的ELF文件时,内核都会将程序的函数调用堆栈的最高地址放在稍有不同的(“随机”)地址上。argv您的shellcode为1 的地址和环境变量在每次程序调用时都以不同的地址结尾。

ASLR应该使利用缓冲区溢出和其他与堆栈相关的漏洞变得更加困难。开发人员必须编写代码或执行某些操作以解决函数调用堆栈上变量和值的变化地址。

看起来您可以通过执行以下操作来禁用ASLR:

echo 0 > /proc/sys/kernel/randomize_va_space

作为root用户。由于您明确引用了Ubuntu,因此上述命令有所不同:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

是的,这就是窍门。我注意到该书的作者使用的Ubuntu 10.04还没有ASLR。
Janman 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.