Environment Variable and Set-UID Program Lab
Environment Variable and Set-UID Program Lab
Task 1: Manipulating Environment Variables
- 使用 printenv 或 env 命令打印出环境变量。 如果您对某些特定的环境变量(例如 PWD)感兴趣,可以使用“printenv PWD”或“env | grep PWD”。
- 如果您对某些特定的环境变量(例如 PWD)感兴趣,可以使用“printenv PWD”或“env | grep PWD”。
- 使用 export 和 unset 来设置或取消设置环境变量。 需要注意的是,这两个命令不是单独的程序; 它们是 Bash 的两个内部命令(您将无法在 Bash 之外找到它们)。
Task 2: Passing Environment Variables from Parent Process to Child Process
- Step1:编译并运行以下程序
- 这将生成一个名为 a.out 的二进制文件。 让我们运行它并使用“a.out > file”将输出保存到一个文件中。
diff命令没有输出,表示内容相同。
Task 3: Environment Variables and execve()
- Step1:这个程序只是执行一个名为/usr/bin/env 的程序,它打印出当前进程的环境变量。发现执行结果为空。
1 |
|
- 第一个参数为一个可执行的有效的路径名。第二个参数argv系利用数组指针来传递给执行文件,v是要调用的程序执行的参数序列,也就是我们要调用的程序需要传入的参数;envp则为传递给执行文件的新环境变量数。
- 所以在此处,我们赋予新进程的环境变量为空,自然印出环境变量结果为空。
- Step2:将第①行中 execve() 的调用更改为以下内容; 描述你的观察。
- 结论:execve()产生的新进程的环境变量需要在调用时进行传递。
Task 4: Environment Variables and system()
1 |
|
system()调用fork()函数新建一个子进程;在子进程中调用execl()函数去执行command;在父进程中调用wait去等待子进程结束。
Task 5: Environment Variable and Set-UID Programs
- Step1:编写程序,可以打印出当前进程中的所有环境变量
- Step2:编译上述程序,将其所有权改为root,并使其成为Set-UID程序。
- Step3:在您的 shell 中(您需要使用普通用户帐户,而不是 root 帐户),使用 export 命令设置以下环境变量(它们可能已经存在):
-
找不到LD_LIBRARY_PATH(主要用于指定查找共享库(动态链接库)时除了默认路径之外的其他路径):
为了使 Set-UID 程序更加安全,不受LD_LIBRARY_PATH环境变量的影响。如果程序是个 Set-UID 程序 ,运行时的链接器或加载器(ld.so)会忽略该环境变量,
Task 6: The PATH Environment Variable and Set-UID Programs
- 新建并编译所给程序task6.c和恶意程序fake_ls.c
- 将task6设置为setuid程序
- 查看当前目录的路径,通过export设置PATH先查找当前目录。
- 将 /bin/sh 链接到另一个没有防止攻击的对策的 shell;编译生成自己的ls,运行task6。
Task 7: The LD PRELOAD Environment Variable and Set-UID Programs
Step1:
- 构建一个动态链接库。 创建以下程序,并将其命名为 mylib.c
-
使用以下命令编译上面的程序:
-
现在,设置 LD_PRELOAD 环境变量:
-
最后编译下面的程序myprog,和上面的动态链接库libmylib.so.1.0.1在同一个目录下:
Step2:完成上述操作后,请在以下条件下运行 myprog,并观察会发生什么。
-
使myprog 成为常规程序,并以普通用户身份运行它。
会执行我们设定的库中的sleep函数,输出字符串。
-
使myprog 成为Set-UID root 程序,并以普通用户身份运行它。
正常执行程序,sleep 1秒,然后退出程序。
-
使myprog 成为Set-UID root 程序,再次在root 用户中设置LD_RELOAD 环境变量,然后运行它。
首先登入root用户,设置LD_PRELOAD 环境变量:
-
以root用户运行:
会执行我们设定的库中的sleep函数,输出字符串。
-
以普通用户运行:
正常执行程序,sleep 1秒,然后退出程序。
-
-
使 myprog 成为 Set-UID user1 程序(即所有者是 user1,这是另一个用户帐户),在不同用户的帐户(非 root 用户)中再次导出 LD PRELOAD 环境变量并运行它。
- 首先新建用户user1:
- 设置程序的所有者为user1,并设置为Set-UID程序,并设置环境变量
-
以seed用户运行该程序:
正常执行程序,sleep 1秒,然后退出程序。
-
Step3:
设计一个实验来找出并解释Step2中的行为不同的原因。
-
编写并编译程序:print_env,通过改变注释行可以分别打印子进程的环境变量和父进程的环境变量。
 versus execve()
新建一个目录t8,在该目录下创建test.txt文件。
对于普通用户,test.txt是不可写的,尝试删除它,但权限不够
- **Step1:**编译上述程序,使其成为一个root拥有的Set-UID程序。 该程序将使用 system() 来调用该命令。
通过catall得到了root权限的shell,成功删除test.txt。
- **Step2:**注释掉system(command)语句,取消execve()语句; 程序将使用 execve() 来调用命令。
攻击失败。因为execve会执行一个新程序,而不会调用新的shell程序。
Task 9: Capability Leaking
- 以root用户创建一个etc文件夹,文件夹内创建zzz文件,并设置其权限为0644。
-
更改cap_leak.c下zzz的路径
-
编译cap_leak.c,设置为Set-UID root程序。
-
在seed用户下运行,写入zzz:
本博客所有文章除特别声明外,均为博客作者本人编写整理,转载请联系作者!