[英]SETUID at filesystem level
假设我们正在研究以下情形:
文件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位。 这就是为什么观察到的行为会发生吗? 如果是这样,是否有一种方法可以使其表现为好像由root执行而没有setuid(.)
?
看起来bash(由system()执行)会删除特权。 在我的测试中,替换指向破折号(而不是bash)的符号链接/ bin / sh使它按预期工作。
还有bash
execl("/bin/bash", "bash", "-c", "whoami", NULL);
给蛋糕,而
execl("/usr/bin/whoami", "whoami", NULL);
给根。
Georg的回答在技术上是正确的1 ,但值得一提的是system(3)
手册页明确指出不建议在setuid程序中使用system()
:
不要使用具有set-user-ID或set-group-ID特权的程序中的system(),因为某些环境变量的奇怪值可能会用来破坏系统完整性。 请改用exec(3)系列函数,而不要使用execlp(3)或execvp(3) 。 实际上,system /()无法在/ bin / sh为bash版本[> =] 2的系统上从具有set-user-ID或set-group-ID特权的程序正常工作,因为bash 2在启动时会放弃特权。 (Debian使用修改后的bash,当它作为sh调用时不会执行此操作。)
这在您的示例中尤其重要,因为您没有完整路径就呼叫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
这意味着,无需更改系统外壳(或使用Debian),代码应仅使用exec()
,如下所示:
int main(int argc, char** argv){
execl("/usr/bin/whoami", "whoami", NULL);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.