Can't drop privileges with suid binary?

1.1k views Asked by At

I was wondering if there is a way to drop privileges using a suid binary (using Ubuntu 18.04). Look:

# cp /bin/bash .
# chown www-data bash
# chmod 4700 bash
# ls -lh
-rws------ 1 www-data root 1,1M abr  4  2018 bash
# ./bash
# id
uid=0(root) gid=0(root) groups=0(root)

Is there an explanation of why one can gain privileges but not drop them with suid binaries?

You may be wondering what I'm trying to accomplish, but it's only to learn.

Thanks!

2

There are 2 answers

0
AudioBubble On BEST ANSWER

This works in the general case:

# cp /usr/bin/id .
# chown www-data id
# chmod 4700 id
# ./id
uid=0(root) gid=0(root) euid=33(www-data) groups=0(root)

bash is a special case. From the "INVOCATION" section of bash manual, with added emphasis on the relevant portion:

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.

Passing the -p (privileged) flag will indeed suppress this behavior:

# cp /bin/bash .
# chown www-data bash
# chmod 4700 bash
# ./bash -p
bash-4.4$ id
uid=0(root) gid=0(root) euid=33(www-data) groups=0(root)
0
Barmar On

As far as set-uid is concerned, there's no hierarchy of privileges -- it simply changes the effective userid to that of the program's owner. Root isn't treated any differently from any other user.

What you're seeing is a deliberate action by bash. There are many security implications to running shell scripts setuid, and bash doesn't allow it by default. When bash starts up, it checks whether the effective UID is the same as the real UID. If not, it means that it's running set-uid. Unless it's being run in one of the ways where this is allowed, it calls a function like setuid() to change back to the real UID.

That's what happened here. root ran bash, and the OS changed the effective UID to www-data. bash detected this and changed back to root.