Reputation: 788
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?
Upvotes: 2
Views: 802
Reputation: 94739
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.
Upvotes: 2