如何防止进程在进程本身内将其 setuid 位更改回 RUID

如何防止进程在进程本身内将其 setuid 位更改回 RUID

我将 SETUID 位设置为非 root 用户,以便该进程始终拥有该可执行文件的所有权。但我发现 setuid 位可以在脚本本身中更改回 RUID。

有什么方法可以阻止它,使 setuid 位无法更改回其原始用户 ID 吗?

我尝试了下面的实验。

chown 1000 /usr/local/bin/php
chmod u+s  /usr/local/bin/php

测试.php

<?php

echo "RUID: " . posix_getuid() . "\n";
echo "EUID: " . posix_geteuid() . "\n";
echo file_put_contents('/root/euid_root.txt', 'test');
echo "\n\n";


// return EUID to root
// a process can change it's EUID back to RUID/SUID
posix_seteuid(0);

echo "RUID: " . posix_getuid() . "\n";
echo "EUID: " . posix_geteuid() . "\n";
echo file_put_contents('/root/uid_apache.txt', 'test');
echo "\n";

/usr/local/bin/php test.php

RUID: 0
EUID: 1000
PHP Warning:  file_put_contents(/root/euid_apache.txt): failed to open stream: Permission denied in /root/test.php on line 17

RUID: 0
EUID: 0
4

答案1

在 C 中,你会做类似的事情:

egid = getegid();
setresgid(egid, egid, egid);

euid = geteuid();
setresuid(euid, euid, euid);

将您的真实、有效并保存的用户/组 ID 设置为有效的 ID,从而防止将来发生任何更改。您可以编写一个简单的包装程序来执行此操作,然后exec使用 PHP,但实际上,对于安全的 set-uid 程序,还有很多其他事情需要考虑,值得庆幸的是,包装程序已经存在......我猜您就是那个包装程序寻找的是 Apache 的苏执行程序

相关内容