分组:和20233809黄雅琦一组
实验楼
1.没有 Set-UID 机制的情况
将 passwd 拷贝到 /tmp/
下,权限发生了变化(在原目录下 suid 位 被设置),复件没有了修改密码的权限。
2.运行 Set-UID 程序
运行tmp目录下的zsh获得了root权限
运行tmp目录下的bash不能获得root权限
/bin/bash
有某种内在的保护机制可以阻止 Set-UID 机制的滥用。
3.Bash 内在保护机制
指令将会把默认的shell指向zsh。
4.PATH 环境变量的设置
将环境变量 PATH 设置为当前目录 /tmp
,运行编译的程序 test。就可以获得 root 权限。system(const char * cmd)
系统调用函数被内嵌到一个程序中执行一个命令,system()
调用 /bin/sh
来执行 shell 程序,然后 shell 程序去执行 cmd 命令。但是在一个 Set-UID 程序中 system()
函数调用 shell 是非常危险的,这是因为 shell 程序的行为可以被环境变量影响,比如 PATH;而这些环境变量可以在用户的控制当中。通过控制这些变量,用心险恶的用户就可以控制 Set-UID 程序的行为。
可见修改 sh 连接回 bash,运行 test 程序不能使普通用户获得 root 权限。
5.system() 和 execve() 的不同
SRU.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;
//Set q = 0 for Question a, and q = 1 for Question b
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 ;
}
当文件SRU.c中q=0时,file 文件只有 root 用户有读写权限,但普通用户通过运行该程序,阅读并重命名了 file 文件。
而当令 q=1
, execve()
函数会把 file; mv file file_new
看成是一个文件名,系统会提示不存在这个文件。
6.LD_PRELOAD 环境变量
为了保证 Set-UID 程序在 LD_PRELOAD 环境的操纵下是安全的,动态链接器会忽略环境变量,但是在某些条件下是例外的。
情况1:
情况2:
情况3:
情况4:
由以上四种情况可见:只有用户自己创建的程序自己去运行,才会使用 LD_PRELOAD
环境变量,重载 sleep 函数,否则的话忽略 LD_PRELOAD
环境变量,不会重载 sleep 函数。
7.消除和清理特权
为了更加安全,Set-UID 程序通常会调用 setuid()
系统调用函数永久的清除它们的 root 权限。然而有些时候,这样做是远远不够的。
如图所示文件被修改了,原因在于设置 uid 前,zzz 文件就已经被打开了。只要将语句 setuid(getuid())
移至调用 open 函数之前,就能避免这个问题。
总结
Set-UID 是一种权限控制机制,允许用户以文件所有者的权限来执行文件,而不是以当前用户的权限来执行。
Set-UID 是通过在文件的权限中设置特定的标志位来实现的,当用户执行这个文件时,系统会根据文件的权限进行相应的权限检查,从而决定是否以文件所有者的权限来执行文件。
然而,Set-UID 机制也存在潜在的安全性问题。由于它允许用户以超出当前权限的权限来执行文件,如果没有正确地实现和使用,就可能导致系统的安全漏洞。恶意用户可以利用 Set-UID 程序的漏洞来获取系统权限,从而对系统进行攻击。因此,使用 Set-UID 机制的程序必须经过严格的安全审查和测试,以确保其不会成为系统安全的弱点。
总的来说,Set-UID 机制是必需的,因为它允许特定的程序以超出当前用户权限的权限来执行,但是在使用时必须非常小心,以避免潜在的安全性问题。