我正在尝试做安全的事情,并且有一个程序需要以root用户身份运行,以便在不需要时删除其权限。如果我chmod
我的二进制文件与SUID位,并使其属于root,这很好用,因为现在我有UID =某个用户,EUID = root,所以我可以使用seteuid(0)
和{{ 1}}分别提升和放弃管理员权限。
但是如果我使用seteuid(getuid())
而不是设置SUID,那么UID == EUID == 0,因此调用sudo
将不会产生任何影响。而且我不能只将seteuid(getuid())
更改为某个随机用户的某个值,因为UID
手册页明确指出如果从以root身份运行的程序调用它,则会丢失权限,没有希望让他们回来。
那么,在使用setuid()
?
答案 0 :(得分:10)
seteuid(some random uid)
以seteuid(0)
运行时,删除权限root
以取回权限。
答案 1 :(得分:6)
似乎seteuid(x)应该努力放弃并重新提升私人......
$ cat > t12.c
#include <stdio.h>
#include <unistd.h>
void p(void) { printf("euid=%4d uid=%4d\n", geteuid(), getuid()); }
int main(void) { p(); seteuid(100); p(); seteuid(0); p(); return 0; }
$ cc -Wall t12.c
$ sudo chown root a.out && sudo chmod 4555 a.out
$ sudo ./a.out
euid= 0 uid= 0
euid= 100 uid= 0
euid= 0 uid= 0
$ ./a.out
euid= 0 uid= 501
euid= 100 uid= 501
euid= 0 uid= 501
$
答案 2 :(得分:3)
不是直接回答,只是想指出privilege separation的想法。这是OpenBSD创始人Theo de Raadt的一个伟大的presentation。
答案 3 :(得分:1)
Fork()。等待父任务,直到完成权限降低的子进程,然后在具有root的父进程中继续。
seteuid不适用于所有unices,也有其他缺点。