假设我们正在研究以下情形:

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

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

构建并设置权限位:
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

阳光下的每种资源都告诉我,在用户列上设置s权限应使程序以所有者的特权(而不是调用用户的特权)执行。为什么system("whoami");返回cake

修改程序以手动设置UID,如下所示:
int main(int argc, char** argv){
    setuid(geteuid());
    system("whoami");
}

产生预期的结果
cake@lie> ./saymyname
root

一些资源声称通常会忽略SUID和GUID位。这就是为什么观察到的行为会发生吗?如果是这样,是否有一种方法可以使其表现为好像是由没有setuid(.)的root执行的?

最佳答案

Georg's answer在技术上是正确的1,但值得一提的是system(3)手册页明确指出不建议在setuid程序中使用system():



这在您的示例中尤其重要,因为您在不带完整路径的情况下调用whoami。想象以下情况(以非特权用户身份):

> 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

这意味着,无需更改系统 shell (或使用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

关于c - 文件系统级别的SETUID,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53624156/

10-13 03:34