10

The Linux dynamic linker includes a mechanism of dynamically loading arbitrary code into every process using the LD_PRELOAD env variable and the /etc/ld.so/preaload file. This sounds dangerous, and is dangerous. As a recent example, the Windigo/Ebury malware relies on it:

https://github.com/eset/malware-ioc/blob/master/windigo/README.adoc

The permanently running process listening to this UNIX socket is started by loading the Ebury payload into a legitimate executable using LD_PRELOAD

Yet this mechanism is on by default in all Linux distributions, even in MUSL-based ones (source code). This seems extremely imprudent, and while there are legitimate use cases for it (like adding instrumentation to closed-source code), they are niche and don't warrant LD_PRELOAD being on by default.

While there are tricks to mitigate arbitrary code loading via this mechanism, they sound too complex and unreliable. I think the best solution would be to nip it in the bud and remove this functionality from the system dynamic linker. The legitimate users would still be able to use it via a custom linker, but the hundreds of thousands of infected web servers would be a lot safer. So why hasn't this been done? Why isn't anyone campaigning against this misfeature?

10
  • 20
    I think you are misunderstanding the Unix-Linux security paradigm. Permissions are granted to users not to programs. And a normal user is allowed to execute arbitrary code, and can even provide its own code (C compiler is normally installed by default). If somebody could add an LD_PRELOAD variable in your environment, it could as well change your path to make you launch a modified copy of the program. So this cannot be used for priviledge escalation. I cannot see how LD_PRELOAD can be a security question, the same way that the set_user_id bit can. May 15 at 7:12
  • 1
    I agree with you that PATH is an error-prone misfeature, too, but it's not as bad. Simply put, launching a program with /usr/bin/program args... is PATH-safe, but not LD_PRELOAD-safe. So LD_PRELOAD is a legitimate security concern May 15 at 7:27
  • 3
    Similarly to specifying the explicit path of the executable to run you can explicitly clear the LD_PRELOAD variable when running the executable from a shell: LD_PRELOAD= /usr/bin/program args... May 15 at 20:56
  • 4
    I don't think Serge was opining that PATH was a misfeature. His point is that a focus on LD_PRELOAD is misplaced. If an adversary has sufficient access to control arbitrary users' environments then the game is already lost. If an adversary can control a particular user's environment then that user's account is already compromised. Tricks with LD_PRELOAD are not a primary vulnerability. They are a possible part of the payload of a separate attack, and not one affording privilege escalation. May 16 at 14:55
  • 1
    As Raymond says: It rather involved being on the other side of this airtight hatchway.
    – Martin
    May 17 at 8:25

2 Answers 2

20

You can't. In the Unix security model, there is no security boundary between a process and its parent process (assuming both run under the same userid). Even if you removed LD_PRELOAD, there would be a zillion other ways to achieve the same end result: e.g., simply modify the application binary, modify it after it was launched using ptrace, modify /proc/PID/mem, change the LD_LIBRARY_PATH, etc. Consequently, removing this feature would not make things any safer. Once an attacker can introduce and execute malicious code onto your server, you're hosed.

10
  • 27
    If the attacker can modify environment variables security is already broken. Unix security model assumes that users does not want to attack themselves.
    – vidarlo
    May 15 at 8:48
  • 9
    @EgorSozonov - What is SSH if not an API... May 15 at 15:44
  • 1
    @EgorSozonov, that's a separate question. Comments are not intended for back-and-forth discussion. If you have a new question, please ask using the 'Ask Question' button. Please don't use comments under this answer to discuss some other topic. Thank you!
    – D.W.
    May 15 at 22:56
  • 3
    The can be a security boundary between parent and child processes, via mandatory access controls (e.g. SELinux). I guess that's not part of the standard UNIX security model, though. May 16 at 14:30
  • 1
    @EgorSozonov, why would you argue that this is a security problem at all? If the user says LD_PRELOAD=/tmp/evil.so ls, then that user deliberately asked for evil.so to be loaded, and moreover has enough permissions to do everything that evil.so wants to do (or else syscalls made by that will fail). May 17 at 15:17
-1
  1. There is no such thing that "default in Linux".

  2. This "malware" is sharedlib, which - injected into a process running as root - can distribute itself into all processes of the system. Fine, but there is nothing special in that, obviously as root you can do everything in the system, including the modification of all binaries.

  3. There is no way to inject anything remotely, or even locally as non-root, into a linux process by LD_PRELOAD. The last security holes using this were closed in the late 90s. In this sense, you can say that yes, LD_PRELOAD is "disabled" (well, not exactly disabled, simply executing things in the name of other users is disabled, including executing them with LD_PRELOAD).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .