这是一个set-root-uid程序
$ls -l -rwsr-sr-x 1 root root 7406 2011-12-13 22:37 ./x*
int main(void) { printf( " UID GID \n" "Real %d Real %d \n" "Effective %d Effective %d \n", getuid (), getgid (), geteuid(), getegid() ); seteuid(600); printf( " UID GID \n" "Real %d Real %d \n" "Effective %d Effective %d \n", getuid (), getgid (), geteuid(), getegid() ); setuid(1000); printf( " UID GID \n" "Real %d Real %d \n" "Effective %d Effective %d \n", getuid (), getgid (), geteuid(), getegid() ); setuid(0); // HOW DOES THIS SUCCEED IN SETTING THE EUID BACK TO 0 printf( " UID GID \n" "Real %d Real %d \n" "Effective %d Effective %d \n", getuid (), getgid (), geteuid(), getegid() ); return 0 ; }
UID GID Real 1000 Real 1000 Effective 0 Effective 0 UID GID Real 1000 Real 1000 Effective 600 Effective 0 UID GID Real 1000 Real 1000 Effective 1000 Effective 1000 UID GID Real 1000 Real 1000 Effective 0 Effective 1000
手册页指出setuid将更改实际,保存和有效的uid。因此,在通话后setuid(1000),所有三个都更改为1000。那setuid(0)让我如何更改euid为0?
setuid(1000)
1000
setuid(0)
euid
0
有两种情况
您想在执行setuid程序时暂时放弃root特权 您想在执行setuid程序时永久放弃root特权…
情况1:
setuid程序开始执行后
1.seteuid(600); 2.setuid(1000); 3.setuid(0);
在这种情况下,可以再次获得root特权。
+----+------+------------+ | uid|euid |saved-uid | |----|------|------------| 1.|1000| 0 | 0 | 2.|1000| 600 | 0 | 3.|1000| 1000 | 0 | 4.|1000| 0 | 0 | | | | | +------------------------+
情况2:
setuid程序开始执行后 ,
1.setuid(1000); 2.setuid(0); +----+------+------------+ | uid|euid |saved-uid | |----|------|------------| 1.|1000|0 | 0 | 2.|1000|1000 | 1000 | | | | | +------------------------+
在这种情况下,您无法取回root特权。可以通过以下命令进行验证,
cat / proc / PROCID / task / PROCID /状态| 减
Uid: 1000 0 0 0 Gid: 1000 0 0 0
此命令将显示一个Uid和Gid,它将具有4个字段(前三个字段是我们关注的字段)。像上面的东西
这三个字段代表uid,euid和saveed-user-id。您可以在setuid程序中引入一个暂停(来自用户的输入),并检查cat /proc/PROCID/task/PROCID/status | less命令的每个步骤。在每个步骤中,您都可以检查保存的uid是否如前所述进行更改。
cat /proc/PROCID/task/PROCID/status | less
如果您的euid是root用户,并且更改了uid,则特权将被永久删除。如果有效的用户ID不是root用户,则保存的用户ID不会被触及,您可以在程序中随时重新获得root特权。