Security issue with set-uid and relative path for INTERP (dynamic linker) in ELF

The combination of set-uid and relative path in the INTERP section of the ELF binary is very dangerous.

I'm not quite sure how and where this issue should be reported, but it seems to me that the general security issue is related to how dynamic linking in linux / glibc works, so let me explain what it is:

Consider creating a dynamically linked binary and specifying a relative path in the ELF INTERP section (using the -dynamic-linker gcc option) so that you can distribute a custom version of glibc with your dynamically linked commercial application (where you are not allowed to statically link to LGPL glibc but still you need to do your binary work on different Linux distributions having different versions of glibc).

If you use the root binary and put the set-uid flag in your binary, it will become a rootkit. By executing it from another directory, you can replace the dynamic linker executable file, which will be executed with root privileges.

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 are currently executing the set-uid binary, like this

 ./issue 

or even just do it

 ldd issue 

instead of getting what you expect, for example:

 (vulnarable) euid:0 

You are getting:

 (rootkit) euid:0 

Now you can replace the ld-linux-x86-64.so.6 binary with whatever you like.

Similar issues seem to have been fixed by not allowing $ ORIGIN in RPATH or ignoring LD_LIBRARY_PATH if the set-uid flag is set.

So I wonder if I should ignore INTERP in ELF when the set-uid flag is set (i.e. using the default dynamic linker - / lib32 / ld-linux.so.2 or / lib 64 / ld-linux -x86-64 .so.2)?

So, where do you think this should be fixed or reported - in glibc or the kernel?

+6
source share
1 answer

Yes, it is not safe to have a setuid binary that defines the interpreter in an unsafe place (you specify a relative path, but a fixed path for writing in the world has the same problem). But logically completing the ELF design and adding a special case to INTERP processing for setuid binaries is not the way to go. This is the case, "Doctor, it hurts when I do this. - Don't do this." Yes, this combination is not safe, so just do not use it! Interaction with the ELF interpreter is in any case something more, so you should not do this if you do not understand what you are doing, in which case you can logically conclude that it is safe or not to do it.

The advanced features of ELF / POSIX / Unix / no matter what you can use to shoot in the foot, because they are powerful. If you want to get rid of any possible bad situation, you will have a system that will be much less flexible and more difficult to program, but there are some holes.

+5
source

Source: https://habr.com/ru/post/906941/


All Articles