我正在尝试进行一个漏洞利用,它会生成一个 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 var
ingdb
只是执行与此相同的操作(甚至可能调用它),并且仅意味着以启动时收到的字符串开头unsetenv()
的所有字符串都不会包含在传递给从现在开始执行的命令的数组中。var=
gdb
envp
gdb
一旦执行命令,他们就可以对envp
收到的数组(将位于堆栈底部)执行任何他们想要的操作,包括environ
使用 libc do 填充变量,例如perl
将其映射到其%ENV
关联数组或 shell,例如使用 libc do 的应用程序。为大多数环境变量创建一个名称与 shell 变量名称兼容的 shell 变量。