How to Harden Linux Server Security Against Shared Library Hijacking by Locking Down Ld_preload and /etc/ld.so.preload on Ubuntu Server

Knowing how to harden Linux server security against shared library hijacking by locking down LD_PRELOAD and /etc/ld.so.preload on Ubuntu Server is essential for any administrator running production workloads. Attackers who gain limited access to a system can exploit these dynamic linker features to inject malicious shared libraries into running processes. This gives them the ability to intercept system calls, steal credentials, or escalate privileges without touching a single binary. In this tutorial, you will learn exactly what these attack vectors are, why they are dangerous, and how to close them down using file permissions, PAM restrictions, and kernel-level controls. By the end, your Ubuntu Server will be significantly more resistant to this class of attack.

Prerequisites for Locking Down Shared Library Hijacking on Ubuntu Server

Before you start, make sure you have the following in place.

Required access and software:

  • Ubuntu Server 20.04 or 22.04 LTS (these steps work on both)
  • Root or sudo access to the server
  • SSH access or direct console access
  • Basic familiarity with the Linux command line
  • A text editor such as nano or vim

Estimated time to complete: 30–45 minutes.

Assumed knowledge level: Intermediate. You should be comfortable editing system files and restarting services. You don’t need to be a security expert, but understanding what shared libraries do will help. The Linux dynamic linker (ld.so) loads shared libraries when a program starts. The LD_PRELOAD environment variable and the file /etc/ld.so.preload tell the linker to load specific libraries before all others. This is a legitimate feature, but it is also a well-known privilege escalation path.

You can read more about how the Linux dynamic linker works in the official ld.so man page on man7.org.

How to Harden Linux Server Security Against Shared Library Hijacking Step by Step

For a related walkthrough, see: How to Build Interactive WordPress Blocks Using the WordPress Interactivity API and Data-wp-* Directives

Work through these steps in order. Don’t skip any of them. Each one closes a different angle of attack.

Step 1: Check the current state of /etc/ld.so.preload

First, check whether this file exists and what it contains.

sudo cat /etc/ld.so.preload

On a clean server, this file is usually empty or absent. If it contains entries you don’t recognize, investigate them immediately before continuing. An unknown entry here is a red flag.

Step 2: Lock down /etc/ld.so.preload with strict permissions

Even if the file is empty, you should restrict who can modify it. Set ownership to root and remove write access for everyone else.

sudo chown root:root /etc/ld.so.preload
sudo chmod 644 /etc/ld.so.preload

This prevents non-root users from adding malicious library paths to the file. Only root can write to it now.

Step 3: Make /etc/ld.so.preload immutable with chattr

Go one step further. Use the chattr command to set the immutable flag. This stops even root from modifying the file without explicitly removing the flag first.

sudo chattr +i /etc/ld.so.preload

To verify the flag was set correctly, run:

sudo lsattr /etc/ld.so.preload

You should see output like ----i---------e-- /etc/ld.so.preload. The i means immutable.

Step 4: Restrict LD_PRELOAD via PAM environment settings

The LD_PRELOAD environment variable is the other major attack surface. You can restrict it using PAM. Open the PAM environment configuration file.

sudo nano /etc/security/pam_env.conf

Add this line at the bottom to unset LD_PRELOAD for all PAM-authenticated sessions.

LD_PRELOAD DEFAULT=""

Save and close the file. This ensures that any user logging in through SSH or a local session starts with an empty LD_PRELOAD.

Step 5: Disable LD_PRELOAD for setuid binaries using sysctl

Linux already ignores LD_PRELOAD for setuid binaries by default. You should confirm this behavior is active. Check your running kernel settings.

sysctl fs.suid_dumpable

You want this set to 0. If it isn’t, set it now.

sudo sysctl -w fs.suid_dumpable=0

Make it permanent by adding it to /etc/sysctl.conf.

echo "fs.suid_dumpable = 0" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Step 6: Audit existing shared library configurations

Check the /etc/ld.so.conf.d/ directory for unexpected entries. Attackers sometimes drop files here to load malicious libraries system-wide.

ls -la /etc/ld.so.conf.d/
cat /etc/ld.so.conf

Review every file in that directory. Remove any entry that doesn’t correspond to a legitimate installed package. After making changes, run:

sudo ldconfig

This rebuilds the linker cache and removes stale or malicious entries.

Step 7: Monitor /etc/ld.so.preload with auditd

Set up file integrity monitoring on the file using auditd. Install it first if you don’t have it.

sudo apt install auditd -y

Add a watch rule for the file.

sudo auditctl -w /etc/ld.so.preload -p rwxa -k ld_preload_watch

Make this rule permanent by adding it to the audit rules file.

echo "-w /etc/ld.so.preload -p rwxa -k ld_preload_watch" | sudo tee -a /etc/audit/rules.d/hardening.rules
sudo systemctl restart auditd

Now any access attempt on that file will be logged. You can review events with:

sudo ausearch -k ld_preload_watch

Step 8: Restrict user namespaces to limit exploit chaining

Unprivileged user namespaces can be used to chain this attack with container escapes. Restrict them.

echo "kernel.unprivileged_userns_clone = 0" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

This closes an additional privilege escalation path that attackers often use alongside library injection.

Troubleshooting Common Issues When Hardening Shared Library Security

Problem: chattr fails with “Operation not permitted”
This usually means you’re on a filesystem that doesn’t support extended attributes, such as a tmpfs mount. Check your mount type with df -T /etc. On ext4 and xfs, chattr works fine.

Problem: Legitimate software breaks after setting LD_PRELOAD to empty
Some monitoring agents or security tools use LD_PRELOAD to inject themselves into processes. Check with your vendor. You may need to set the variable in a specific service unit file using Environment=LD_PRELOAD=/path/to/lib.so inside the [Service] block rather than relying on a global setting.

Problem: /etc/ld.so.preload doesn’t exist
That’s fine. Create an empty file and then lock it down.

sudo touch /etc/ld.so.preload
sudo chattr +i /etc/ld.so.preload

Problem: auditd rules don’t persist after reboot
Make sure you added the rule to /etc/audit/rules.d/hardening.rules and not just ran auditctl interactively. The auditctl command only sets rules for the current session.

For a deeper look at auditing Linux systems, see the Ubuntu Server security auditing documentation.

Conclusion: Keeping Your Linux Server Hardened Against Library Hijacking

You now know how to harden Linux server security against shared library hijacking by locking down LD_PRELOAD and /etc/ld.so.preload on Ubuntu Server. You’ve restricted file permissions, applied the immutable flag, configured PAM to strip the environment variable, audited linker config directories, and set up real-time monitoring with auditd. Each layer you added makes it harder for an attacker to use

Similar Posts