프로세스 자체 내에서 프로세스가 setuid 비트를 RUID로 다시 변경하는 것을 방지하는 방법

프로세스 자체 내에서 프로세스가 setuid 비트를 RUID로 다시 변경하는 것을 방지하는 방법

프로세스가 항상 실행 파일의 소유권을 갖도록 SETUID 비트를 루트가 아닌 사용자로 설정했습니다. 하지만 스크립트 자체에서 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로 설정하세요. 이를 수행하고 PHP를 사용하기 위해 간단한 래퍼를 작성할 수 있지만 exec실제로는 안전한 set-uid 프로그램을 위해 고려해야 할 다른 사항이 많이 있으며 고맙게도 래퍼가 이미 존재합니다.... ..당신이 찾고 있는 래퍼인 것 같습니다 아파치의 경우고소 실행 프로그램.

관련 정보