Environ



在linux应用程序运行时,内存的最高端是环境/参数节(environment/arguments section)
用来存储系统环境变量的一份复制文件,进程在运行时可能需要。
例如,运行中的进程,可以通过环境变量来访问路径、shell 名称、主机名等信息。
该节是可写的,因此在格式串(format string)和缓冲区溢出(buffer overflow)攻击中都可以攻击该节。
*environ指针指向栈地址(环境变量位置),有时它也成为攻击的对象,泄露栈地址,篡改栈空间地址,进而劫持控制流。

环境表

环境表是一个表示环境字符串的字符指针数组,由name=value这样类似的字符串组成,它储存在整个进程空间的的顶部,栈地址之上
其中value是一个以”\0″结束的C语言类型的字符串,代表指针该环境变量的值
一般我们见到的name都是大写,但这只是一个惯例

下面就是一个环境表的示意图:

可见,环境指针environ指向这个环境表,该表中的字符指针又指向环境值
如果环境标量的个数是num,则env[num]=NULL

UNIX内核并不查看这些字符串,他们的解释完全取决与应用程序,当然也能够增加或者修改

environ

在历史上,大多数UNIX系统中支持main函数带3个参数,其中第3个参数就是表示环境表的地址

int main(int argc,char *argv[],char *envp)

现在main函数一般只有两个参数,argc与argv
第三个参数env以后改用environ指针来处理,如果想要查看整个环境,必须使用整个environ
environ 全称为environment pointer 环境指针,在glibc中存储程序运行时所需要的环境变量

全局变量environ包含该指针数组,因为env[num]=NULL,所以我们可以通过下例将环境变量的内容打印:

示例

我们下面来调试找到environ指针,并在程序中观察环境变量的管理,示例程序是一个简单的hello world

首先我们根据在libc中的偏移确定程序运行时变量environ这个在libc bss段上的变量的位置和值

我们知道environ中储存的就是当前栈的地址,环境表的位置是栈空间中的高地址。
我们完全可以利用envrion来泄露栈的地址,适当减一些就可以了,只要不更改环境表中的值,防止程序abort
我们来看环境表的内容。

和我们看到的上一个程序打印出的环境标量类似
可见该表中存储着所有的环境的地址,形式就是”name=value”

大多数环境变量是继承自父程序的,部分环境变量对程序的运行有着至关重要的作用,如果环境变量发生篡改,就可能产生严重的安全问题。同样,*envrion指向的是栈的地址,可以通过泄露它的值来泄露栈空间地址,从而获得编辑栈的可能。

发表评论