实验6:环境变量与set-uid实验
在本实验室中,学生将了解环境变量是如何工作的,它们是如何从父进程到子进程,以及它们如何影响系统/程序行为。我们特别感兴趣的是如何环境变量影响Set-UID程序的行为,这些程序通常是特权程序。
- Task1
使用 `printenv` 或 `env` 命令可以打印当前shell中的全部环境变量
- Task2
使用fork()函数创建一个子进程,分别在父子进程中打印环境变量
使用`diff`命令发现父子进程的环境变量相同,说明子进程会继承父进程的环境变量,还包括父进程的堆栈、内存等,但进程id和fork()函数返回值不同
- Task3
- Task4
system()函数也可以用来执行新的程序,与`execve()`函数不同,system()函数实际上执行"/bin/sh -c命令",即打开了一个新的shell,并要求shell执行该命令
- Task5
我们在seed用户下使用export命令设置环境变量,我们设置的Task5=Task5 被成功传入,但 LD_LIBRARY_PATH 传入失败;
- Task6
由于/bin/sh默认链接到dash,而dash的保护机制会组织有效ID和真实ID不一致的程序的执行,所以需要将/bin/sh链接到zsh
把假的ls文件所在的目录添加到PATH环境变量的开头,这时再使用system()函数调用ls执行的就是我们写的ls程序
eid指的是用户的有效用户ID(effective user ID),也就是用户在执行特定进程时所拥有的权限
将我们编写的ls程序加上调用`id`命令的语句,发现打印的eid是root,证明文件执行时是以root权限执行的
- Task7
这里只是修改了sleep函数,但实际攻击中可以放入恶意代码,当用户的正常程序链接到我们的恶意动态库时就会执行这些恶意代码
环境变量LD_PRELOAD用于在程序运行时强制优先加载指定的共享库文件。这个功能可以用来替换已经存在的库中的函数或者添加新的函数,修改这个环境变量到我们的动态链接库
- Task8
在root权限下创建一个名为task8的文件,发现在seed用户下无法将其删除
换成execve()函数,发现无法执行,原因是execve()函数并不会启动一个shell,传入的字符串整个作为一个程序去执行,自然会报无法找到这个程序/命令的错误
- Task9
在程序的执行过程中,遇到下面的语句时,程序会将程序的用户ID设置成当前用户ID,即seed,这样看起来程序之后就不会再以root权限执行了
我们发现在这个shell中还是成功地对zzz文件进行了写操作
这是因为程序在切换权限之前没有关闭该文件,在新权限下继承了该文件描述符,文件描述符泄露,在关闭文件描述符之前,root操作都能成功执行
- 结论