如何在 Linux 中找到环境变量的地址

How to find address of the environment variables in Linux

我目前正在学习使用 'The Art of Exploitation' 中的环境变量进行基于堆栈的缓冲区溢出利用。本章的重点是为 shellcode 使用环境变量,而无需创建 NOP sled。这需要我将要使用的变量的确切地址。这是片段:

With execl() , the existing environment is used, but if you use execle() , the entire environment can be specified. If the environment array is just the shellcode as the first string (with a NULL pointer to terminate the list), the only environment variable will be the shellcode. This makes its address easy to calculate. In Linux, the address will be **0xbffffffa** , minus the length of the shellcode in the environment, minus the length of the name of the executed program.

关键是我使用的是完全不同版本的系统(Kali Linux 64 位,4.19 内核),在我的例子中,作者 (0xbffffffa) 使用的基地址非常不同我不知道去哪里找。有什么方法可以找到它,还是我应该在文档中的某个地方查找?

我假设这个地址在栈底的某个地方。或者它是堆栈基址的确切地址?

好的,所以我去了 gdb 并开始查看 $rsp 下面的地址(具有更高的值),直到我得到这个:

0x7fffffffeffc: ""
0x7fffffffeffd: ""
0x7fffffffeffe: ""
0x7fffffffefff: ""
0x7ffffffff000: <error: Cannot access memory at address 0x7ffffffff000>

这就是我想知道的。谢谢你的时间。

我想,如果您只找到该环境变量的特定地址,您可以使用 getenv() 函数。

% export PAYLOAD=$<whatever_payload>

示例:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
    printf("env address at %p\n", argv[1], getenv(argv[1]));
    return (0);
}

用法:

% ./getenv PAYLOAD

这看起来像是 32 位内核下 32 位进程的 32 位地址,没有堆栈 ASLR。 main 得到 3 个参数:argc、argv 和 envp,最后一个是指向 env[] 数组 above RSP 的指针。当然它不会接近 RSP 但在它之下,它会被函数调用的堆栈增长所踩踏。

在进程入口点(_start),x86-64 System V ABI 指定初始 RSP 指向 argc,在其上方是 argv[0]argv[1], .... 然后是 envp 数组(再次以 NULL 结尾)。

这在 x86-64 System V ABI 中有记录。

除非禁用堆栈 ASLR,否则 RSP 的初始值不固定。

在 gdb 中:

x/10s *((char **)environ)

这会显示前 10 个环境变量。