The combination of set-uid and a relative path in the INTERP section of an ELF binary is very dangerous.
I'm not quite sure how and where this problem should be reported, but it seems to me like a general security issue concerning how dynamic linking in linux/glibc works, so let me explain what it is:
Consider building a dynamically linked binary and specifying a relative path in the ELF INTERP section (using the --dynamic-linker gcc option) so you could redistribute a custom glibc version with your dynamically linked commercial application (where you are not allowed to link statically against the LGPL glibc, but still need to make your binary work across different linux distribution having different glibc versions).
If you chown the binary to root, and put the set-uid flag on your binary, it effectively becomes a rootkit. As executing it from a different directory, allows you to replace the dynamic linker executable, that will be executed with root permission.
To demonstrate this, take a look at the following C code (issue.c):
#include <stdio.h>
//
// build with:
// gcc -DNAME=\"vulnarable\" -o issue -Wl,--dynamic-linker,.lib64/ld-linux-x86-64.so.2 issue.c
// sudo chown root issue
// sudo chmod u+s issue
// now build some code to be executed with root permissions (we use the same issue.c):
// mkdir -p .lib64/
// gcc -DNAME=\"rootkit\" -o .lib64/ld-linux-x86-64.so.2 --static issue.c
//
int main(int argc, char* argv[])
{
printf("(%s) euid:%d\n", NAME, geteuid());
}
If you now execute the set-uid binary like this
./issue
or even just doing this
ldd issue
instead of getting what you might expect, e.g.:
(vulnarable) euid:0
you get:
(rootkit) euid:0
Now the point is you could replace the ld-linux-x86-64.so.6 binary with whatever you like.
Similar issues seems to have been addressed, by not resolving $ORIGIN in RPATH or ignoring LD_LIBRARY_PATH if the set-uid flag is set.
So I wonder if the INTERP in ELF has to be ignored, whenever the set-uid flag is set (i.e. by using the default dynamic linker - /lib32/ld-linux.so.2 or /lib64/ld-linux-x86-64.so.2)?
So what do you think, where should this be fixed or reported - in glibc or the kernel?
sudo
. Which means you need root access to do it. – Ungraceful(./issue) euid:0
, which is as expected for a setuid program. – Throughoutsudo
commands in the instructions are just there to create one, so that the issue can be demonstrated. – Throughout