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
orLD_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
openssl
to 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 (.so
file).-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 restart
loadslibrary.so
into 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_PRELOAD
from sudoers!
- Remove or comment out the line:
- Use
secure_path
restrictions to prevent attackers from loading malicious libraries. - Ensure sudoers rules are specific and minimal (e.g., avoid
NOPASSWD
where unnecessary).