1

I'm trying to suid a shell and it's not working. I need help understanding why, and how to fix it...

I'm following these steps (as root)

cp /usr/bin/bash /usr/bin/bash-emergency
chmod 4755 /usr/bin/bash-emergency

bash-emergency is owned by root:root

I would expect that this should execute bash-emergency as root, resulting in a root shell

I know all the reasons not to do this. This is in a lab. su and sudo, for the sake of this test, are not an option. I need a user to be able to get a root shell without having to authenticate or otherwise be challenged after their initial login.

I'm hoping to be able to do this with a simple suid executable rather than changing the non-root user's UID to 0.

What am I doing wrong?

mikem
  • 470

2 Answers2

3

What you are doing wrong is running face-first into a security measure designed to keep the system safe. Bash, dash, and other shells detect that they're being run setuid root and immediately drop privileges on launch. This is because setting them suid root is a very common privilege escalation tactic.

Fortunately, there's a really easy work around for you. Launch your suid shell as /usr/bin/bash-emergency -p.

Relevant quote from the docs:

If the shell is started with the effective user (group) id not equal to the real user (group) id, and the -p option is not supplied, no startup files are read, shell functions are not inherited from the environment, the SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE variables, if they appear in the environment, are ignored, and the effective user id is set to the real user id. If the -p option is supplied at invocation, the startup behavior is the same, but the effective user id is not reset.

1

While shell programs deliberately don't do what you want, you could create your own program that does. This is an example program that will check if you have euid root, and if so, run a specific command as uid root.

Usage is something like /usr/bin/emergency-backdoor /usr/bin/bash, or /usr/bin/emergency-backdoor "/usr/bin/vim /etc/passwd", and so forth.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv) { if (argc != 2) { puts("Usage: <this> &quot;command and args&quot;"); return 1; } else if (geteuid() == 0) { setuid(0); setgid(0); puts("Executing the following as root"); puts(argv[1]); system(argv[1]); } else { puts("You do not have privs"); } return 0; }