2

我希望从“set-user root”程序启动一个 root 命令,所以我编写了以下 C 示例程序:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

void main(int argc, char *argv[])
{
    if(argc > 2) {
        setuid(0);
        printf("setuid(0) executed\n");
    } else
        printf("setuid(0) NOT executed\n");

    system(argv[1]);
}

在 Debian 6(64 位)上测试它,我注意到"/bin/sh"作为参数传递,我总是得到一个ROOT SHELL,即使argc == 2

$ gcc foo.c -o foo  
$ su  
Password: *****  
# chown root:root ./foo  
# chmod 4755 ./foo  
# ls -l foo  
-rwsr-xr-x 1 root root 6887 11 dic 17.44 foo  
# exit  
exit  
$ ./foo /bin/sh  
setuid(0) NOT executed  
# exit                 <<<<< ROOT SHELL  
$ ./foo /bin/sh 12345  
setuid(0) executed  
# exit                 <<<<< ROOT SHELL  

在 Slackware 14(32 位)上,它的行为不同:

$ gcc foo.c -o foo  
$ su   
Password: *****  
bash-4.2# chown root:root ./foo  
bash-4.2# chmod 4755 ./foo  
bash-4.2# ls -l foo  
-rwsr-xr-x 1 root root 6292 dic 11 17:53 foo  
bash-4.2# exit  
exit  
$ foo /bin/sh  
setuid(0) NOT executed  
sh-4.2$ exit             <<<<< USER SHELL  
exit  
$ foo /bin/sh 12345  
setuid(0) executed  
sh-4.2# exit             <<<<< ROOT SHELL  
exit    

如果我将“/usr/bin/dolphin”作为参数,也会有不同的行为。
在 Debian 上我无法让它工作:

$ ./foo /usr/bin/dolphin  
setuid(0) NOT executed  
<unknown program name>(28884)/: KUniqueApplication: Cannot find the D-Bus session server:  "Unable to autolaunch when setuid"  
<unknown program name>(28883)/: KUniqueApplication: Pipe closed unexpectedly.    

在 Slackware 上,它仅适用于argc == 2,因此我无法以 root 身份启动 dolphin。
为什么?

4

1 回答 1

2

要解释稍微奇怪的 setuid 行为,您需要了解它/bin/sh实际上可能是bash,并且默认行为bash是删除euid,除非它被调用-p

这意味着如果您使用 -p 调用 bash,那么您应该会看到一个类似于 shell 的“root”:-

natsu ~> id -a
uid=1000(me) gid=1000(me) groups=1000(me),4(adm),15(kmem)
natsu ~> ./foo "/bin/bash -p"
setuid(0) NOT executed
bash-4.2# id -a
uid=1000(me) gid=1000(me) euid=0(root) egid=0(root) groups=0(root),4(adm),15(kmem),1000(me)

而在没有-p选项的情况下调用会产生观察到的行为:

pshanahan@natsu ~> ./foo /bin/bash
setuid(0) NOT executed
bash-4.2$ id -a
uid=1000(me) gid=1000(me) groups=1000(me),4(adm),15(kmem)

但实际上,您只有有效的用户 id 0,而不是真正的用户 id 0。

让 GUI 在这种情况下运行……这完全是另一回事;但这应该可以帮助您理解这种情况下的行为。

于 2013-12-11T17:50:32.423 回答