使用和不使用 GDB 查找环境变量的地址

使用和不使用 GDB 查找环境变量的地址

我正在尝试进行一个漏洞利用,它会生成一个 shell,shellcode 位于环境变量内,并且我使用干净的环境启动程序或 GDB,因此该变量位于顶部。

env -i MYVAR=10 gdb ./prog

问题是,GDB 内部有一些名为 COLUMNS 和 LINES 的变量,并使用以下命令删除它们:

unset env COLUMNS
unset env LINES

然后打印环境:

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

仍然会产生一个输出,其中这些变量可见并且具有相同的地址。我知道我已经删除了它们,因为使用

show env COLUMNS

产生一个错误,指出该变量未定义。

如何显示新更新的环境而不显示已删除的环境?

我的目标是在 GDB 之外找到 MYVAR 的地址,但我无法篡改程序,因此通过复制 GDB 内部的环境而不使用它设置的变量,我可以获得该地址。

谢谢你,乔什

答案1

环境是第二个字符串数组,execve()当进程执行命令时,它作为第三个“envp”参数传递给系统调用,第一个参数是参数(“argv”)。

按照惯例,这些字符串采用以下var=value格式。

execve("/path/to/cmd", ["cmd", "arg1", "arg2"], ["var1=value1", "var2=value2"])

按照惯例,当执行其他命令时(通常是在其子进程中),命令会将执行时收到的环境字符串传递给它们执行的命令。execvp()C 库中的函数本身是系统调用的包装器,默认execve()情况下会执行此操作。在 C 库中(哪些命令可能会链接,也可能不会链接,但通常会链接),该environ变量是根据执行时接收到的 envp 数组填充的。该变量是在后续的execve()s 中通过// / ... 和 //execvp()更新execlp()system()数组popen()作为putenv()envp传递的变量。setenv()unsetenv()environ

unset env varingdb只是执行与此相同的操作(甚至可能调用它),并且仅意味着以启动时收到的字符串开头unsetenv()的所有字符串都不会包含在传递给从现在开始执行的命令的数组中。var=gdbenvpgdb

一旦执行命令,他们就可以对envp收到的数组(将位于堆栈底部)执行任何他们想要的操作,包括environ使用 libc do 填充变量,例如perl将其映射到其%ENV关联数组或 shell,例如使用 libc do 的应用程序。为大多数环境变量创建一个名称与 shell 变量名称兼容的 shell 变量。

相关内容