简体   繁体   English

文件系统级别的SETUID

[英]SETUID at filesystem level

Suppose we are looking at the following scenario: 假设我们正在研究以下情形:

File saymyname.c (includes omitted) 文件saymyname.c(包括省略的内容)

int main(int argc, char** argv){
    system("whoami");   
}

Build and set permission bits: 构建并设置权限位:

cake@lie> gcc saymyname.c -o saymyname
cake@lie> sudo chown root:root saymyname
cake@lie> sudo chmod u+s saymyname
cake@lie> ./saymyname
cake

Every resource under the sun tells me that setting the s permission on the user-column should make the program execute with the owner's privileges, not the calling user's. 阳光下的每种资源都告诉我,在用户列上设置s许可权应该使程序以所有者的特权(而不是调用用户的特权)执行。 Why does system("whoami"); 为什么system("whoami"); return cake ? cake吗?

Modifying the program to set the UID manually like so: 修改程序以手动设置UID,如下所示:

int main(int argc, char** argv){
    setuid(geteuid());
    system("whoami");   
}

Yields the expected result 产生预期的结果

cake@lie> ./saymyname
root

Some resources claim that the SUID and GUID bits are often ignored. 一些资源声称通常会忽略SUID和GUID位。 Is this why the observed behavior occurs? 这就是为什么观察到的行为会发生吗? If so, is there a way to make it behave as if it was executed by root without setuid(.) ? 如果是这样,是否有一种方法可以使其表现为好像由root执行而没有setuid(.)

Looks like bash, which is executed by system(), drops the privileges. 看起来bash(由system()执行)会删除特权。 In my tests, replacing the symbolic link /bin/sh pointing to dash (instead of bash) made it work as expected. 在我的测试中,替换指向破折号(而不是bash)的符号链接/ bin / sh使它按预期工作。

Also with bash, 还有bash

execl("/bin/bash", "bash", "-c", "whoami", NULL);

gives cake, whereas 给蛋糕,而

execl("/usr/bin/whoami", "whoami", NULL);

gives root. 给根。

Georg's answer is technically correct 1 , but it is worth to mention that the system(3) man page explicitly states that the use of system() in setuid programs is not recommended: Georg的回答在技​​术上是正确的1 ,但值得一提的是system(3)手册页明确指出不建议在setuid程序中使用system()

Do not use system() from a program with set-user-ID or set-group-ID privileges, because strange values for some environment variables might be used to subvert system integrity. 不要使用具有set-user-ID或set-group-ID特权的程序中的system(),因为某些环境变量的奇怪值可能会用来破坏系统完整性。 Use the exec(3) family of functions instead, but not execlp(3) or execvp(3) . 请改用exec(3)系列函数,而不要使用execlp(3)或execvp(3) system() will not, in fact, work properly from programs with set-user-ID or set-group-ID privileges on systems on which /bin/sh is bash version [>=]2, since bash 2 drops privileges on startup. 实际上,system /()无法在/ bin / sh为bash版本[> =] 2的系统上从具有set-user-ID或set-group-ID特权的程序正常工作,因为bash 2在启动时会放弃特权。 (Debian uses a modified bash which does not do this when invoked as sh.) (Debian使用修改后的bash,当它作为sh调用时不会执行此操作。)

This is especially relevant in your example as you are calling whoami without the full path. 这在您的示例中尤其重要,因为您没有完整路径就呼叫whoami Imagine the following scenario (as unprivileged user): 想象以下情形(以非特权用户身份):

> whoami cat << 'EOF'
#!/bin/not-bash :)
echo "I'm root! let's clean up some trash ..."
# rm -rf /
EOF
chmod +x whoami

PATH="${PWD}" ./saymyname

That means, instead of changing the system shell (or using Debian), the code should just use exec() , like this: 这意味着,无需更改系统外壳(或使用Debian),代码应仅使用exec() ,如下所示:

int main(int argc, char** argv){
    execl("/usr/bin/whoami", "whoami", NULL);   
}

1 newer versions of dash on Ubuntu will also drop privileges Ubuntu上的 1个 较新版本的dash也将失去特权

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM