在 setuid root 二进制文件中提示输入 sudo 密码

在 setuid root 二进制文件中提示输入 sudo 密码

我有一个 setuid root 二进制文件,with_sudo.bin其源代码如下:

/* with_sudo.c */
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int main() {
    printf("\n\n ruid : %d \n euid : %d \n\n", (int)getuid(), (int)geteuid());
    system("/usr/bin/sudo cat /root/key.txt");
    return 0;
}

 

akshay@bluebox ~ $ ls -l with_sudo.bin
-rwsr-sr-x 1 root root 8684 Feb  1 22:09 with_sudo.bin

即使它是一个 setuid root 二进制文件,也会要求输入 sudo 密码。

akshay@bluebox ~ $ ./with_sudo.bin
ruid : 1000  euid : 0 
[sudo] password for akshay:

当我运行另一个没有sudo在 中system(),它以超级用户权限运行。

/* without_sudo.c */
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int main() {
    printf("\n\n ruid : %d \n euid : %d \n\n", (int)getuid(), (int)geteuid());
    system("cat /root/key.txt");
    return 0;
}

 

akshay@bluebox ~ $ ls -l without_sudo.bin
-rwsr-sr-x 1 root root 8677 Feb  1 22:09 without_sudo.bin

akshay@bluebox〜$ ./without_sudo.bin

ruid:1000 euid:0

:::这是一个秘密密钥:::

Real UID使用0时,二进制文件以超级用户权限运行Effective UIDsetreuid(geteuid(), 0);而无需提示输入 sudo 密码,尽管sudo被使用。

/* with_sudo_ruid_elevated.c */
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int main() {
    setreuid(0, geteuid());
    printf("\n\n ruid : %d \n euid : %d \n\n", (int)getuid(), (int)geteuid());
    system("/usr/bin/sudo cat /root/key.txt");
    return 0;
}

我有用于EUID评估进程执行特定操作的权限。那么为什么sudoRUID即使出现EUID了,也会提示输入 sudo 密码0

答案1

有点复杂。操作系统核心使用进程的有效 UID 和 GID 来确定其权限/授权;它们用于

  • 根据用户/组/其他规则允许/禁止普通文件系统操作(例如打开、链接/取消链接),
  • 设置新创建文件的所有权,
  • 确定某个进程可以向哪些其他进程发送信号,以及
  • 决定进程是否可以挂载和卸载文件系统、更改日期、关闭系统等。

可能还有其他事情。但问题是,当程序需要做出某种访问/授权决定,通常需要使用真实 UID 和 GID。考虑一下:当您的with_sudo.c程序执行时sudo,有效 UID 是 root (0),而真实 UID 是您 (1000),如您的printf。  sudo但这与从非特权 shell运行时发生的情况完全相同。  每当 sudo运行时,有效 UID 为 0 – 因此sudo无法使用它来决定如何操作。它必须使用真实 UID 来确定您到底是谁,这样它才能确定您被允许在 中执行的操作sudo。只有当真实 UID 为 0 时,它才会sudo断定您是“真正的”root,或者至少它无法可靠地确定您的真实身份,因此它不知道要对您应用什么限制,它只会执行 而不cat要求您进行任何进一步的身份验证。

相关内容