I have the following home-grown implementation of su
:
JavaScript
x
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main (int argc, char *argv[]) {
if (argc == 1) {
printf ("Usage: %s command [argument]...n", argv[0]);
return EXIT_SUCCESS;
}
if (geteuid () != 0) {
fprintf (stderr, "%s: permissions are wrong or the setuid bit is not set.n", argv[0]);
return EXIT_FAILURE;
}
argv++;
int ret = execv (argv[0], argv);
if (ret == -1) {
perror (argv[0]);
return EXIT_FAILURE;
}
return ret;
}
To allow for proper execution, the permissions and ownership information are set accordingly:
JavaScript
$ gcc su.c -o su
$ sudo chown root: su
$ sudo chmod 4755 su
When I invoke a shell, such as /bin/sh
, I am able to modify root-owned files and directories:
JavaScript
$ rm -rf /opt/foobar/
rm: cannot remove ‘/opt/foobar/’: Permission denied
$ ./su /bin/sh
# rm -rf /opt/foobar
# exit
However, /bin/bash
doesn’t seem to get root permissions:
JavaScript
$ ./su /bin/bash
bash-4.3$ rm -rf /opt/foobar/
rm: cannot remove ‘/opt/foobar/’: Permission denied
Advertisement
Answer
Shells reset the euid to the uid for security reasons. So if you really want to have a rooted shell, you need to enforce uid and euid to 0. Set-uid bit only change the effective user id.
You need to set the user id to 0 for bash
to be run as root:
JavaScript
setuid(0);
int ret = execv (argv[0], argv);