Shared libraries: LD_PRELOAD / LD_LIBRARY_PATH
It is common for Linux programs to use dynamically linked shared object libraries. Libraries contain compiled code or other data that developers use to avoid having to re-write the same pieces of code across multiple programs.
Two types of libraries exist in Linux:
static librariesĀ (denoted by the .a file extension)- andĀ
dynamically linked shared object librariesĀ (denoted by the .so file extension).
When a program is compiled, static libraries become part of the program and can not be altered. However, dynamic libraries can be modified to control the execution of the program that calls them.
There are multiple methods for specifying the location of dynamic libraries:
- Using theĀ
-rpathĀ orĀ-rpath-linkĀ flags when compiling a program, - using the environmental variablesĀ
LD_RUN_PATHĀ orĀLD_LIBRARY_PATH - placing libraries in theĀ
/libĀ orĀ/usr/libĀ default directories - or specifying another directory containing the libraries within theĀ
/etc/ld.so.confĀ configuration file
Additionally, theĀ LD_PRELOADĀ environment variable can load a library before executing a binary. The functions from this library are given preference over the default ones.
The shared objects required by a binary can be viewed using theĀ lddĀ utility. For instance, this command Ā lists all the libraries required byĀ /bin/ls, along with their absolute paths.
LD_PRELOAD Privilege Escalation
Let's see an example of how we can utilize theĀ LD_PRELOADĀ environment variable to escalate privileges.
Output:
This user has rights to restart the openssl service as root, but since this isĀ NOTĀ aĀ GTFOBinĀ and theĀ /etc/sudoersĀ entry is written specifying the absolute path, this could not be used to escalate privileges under normal circumstances.
However, note here env_keep+=LD_PRELOAD. This lets us override functions and execute arbitrary code inside a privileged process. Specifically:
- The system does NOT clear LD_PRELOAD when using sudo.
- We can force
opensslto load a malicious library (library.so).
So we can exploit theĀ LD_PRELOADĀ issue to run a custom shared library file. Let's compile the following library:
We can compile this as follows:
-fPIC: Position-independent code (required for shared libraries).-shared: Compile as a shared library (.sofile).-nostartfiles: Exclude standard startup files (smaller payload).
Finally, we can escalate privileges by executing Openssl restart with our malicious library injected. We need to specify the full path to the malicious library file.
openssl restartloadslibrary.sointo memory.- The
_init()function executes before Openssl even starts. - It grants us root privileges and spawns a root shell.
How to Defend Against This?
- Remove
env_keep+=LD_PRELOADfrom sudoers!
- Remove or comment out the line:
- Use
secure_pathrestrictions to prevent attackers from loading malicious libraries. - Ensure sudoers rules are specific and minimal (e.g., avoid
NOPASSWDwhere unnecessary).