root command from a 'set-user root' program

778 views Asked by At

I wish to start a root command from a 'set-user root' program, so I wrote the following C sample program:

#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]);
}

Testing it on Debian 6 (64 bit), I noticed that passing "/bin/sh" as the argument, I always get a ROOT SHELL, even if 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  

On Slackware 14 (32 bit), it behaves differently:

$ 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    

If I give "/usr/bin/dolphin" as argument, there is also a different behaviour.
On Debian I'm not able to get it work:

$ ./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.    

On Slackware, it works only if argc == 2, so I cannot start dolphin as root.
Why?

1

There are 1 answers

0
Anya Shenanigans On

To explain the slightly peculiar setuid behaviour, you need to understand that /bin/sh may actually be bash, and the default behaviour of bash is to drop euid unless it's invoked with -p.

This means that if you invoke bash with -p, then you should see a 'root' like shell:-

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)

Whereas invoked without the -p option yields the observed behaviour:

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)

but in reality, you only have effective user id 0, not real user id 0.

getting the GUI to run in this situation... That's another matter altogether; but this should help you understand the behaviour in this case.