I have the following home-grown implementation of su
:
#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:
$ 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:
$ 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:
$ ./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:
... setuid(0); int ret = execv (argv[0], argv); ...