Skip to content

Sedl/ld_preload

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 

Repository files navigation

Purpose of this repo

This repository demonstrates the use of LD_PRELOAD and discusses some security issues.

bind.so

By default, Linux uses the source IP address of the interface that the packet is sent on, you can use bind.so to override this behavior.

This shared library will override the connect call to libc and calls bind on the socket passed to it before connect is called. It can be used to set the source IP address of the connection if the binary doesn't support it by itself.

The idea to this was out of necessity; I had to check if a PostgreSQL connection could be made from a specific IP address, as psql doesn't support this. Using LD_PRELOAD was the easiest, non-invasive way (to the system) to do this.

This is just an example and has some limitations:

  • Only IPv4 addresses are supported
  • UDP might not work as expected
  • Can break DNS resolution as the new source address is used for DNS queries as well (use IP address instead of hostname)
  • Works only on dynamically linked binaries
  • Might not work if the binary calls bind itself
  • Only works on Linux
  • Some things I forgot

How to use:

LD_PRELOAD=${PWD}/bind.so BIND_ADDR=10.0.0.2 psql -h 192.168.1.100 -U postgres

This changes the source IP address of the connection to 10.0.0.2.

What are dynamically linked binaries?

Dynamically linked binaries need some mechanism to load shared libraries.

The man page for ld.so (man 8 ld.so) describes dynamically linked binaries as follows:

   The dynamic linker can be run either indirectly by running some dynami‐
   cally linked program or shared object (in which  case  no  command-line
   options  to  the dynamic linker can be passed and, in the ELF case, the
   dynamic linker which is stored in the .interp section of the program is
   executed) or directly by running:
   
   /lib/ld-linux.so.*  [OPTIONS] [PROGRAM [ARGUMENTS]]
   ...

What does LD_PRELOAD do?

With the LD_PRELOAD environment variable you can inject a shared library into a process and override functions in libraries that are already loaded. You don't need to recompile the program or the libraries, and you even don't need to know the name of the library (or the path to it).

Some things about LD_PRELOAD

  • You don't need to know the name of the library (or the path to it).
  • You don't need to recompile the program or the libraries.
  • You don't need special privileges to use LD_PRELOAD.
  • You don't need to be a root user.
  • The dynamic library used for LD_PRELOAD doesn't need the executable bit set.
  • Binaries with suid or sgid bits set ignore LD_PRELOAD for security reasons, but setting suid or sgid bits causes other security issues.

Security

Attack surface

I've done some post-compromise analysis for customers and seen a lot of attackers using this technique. If the attacker can get into your www-root directory (open (S)FTP, web application flaws, ...), they can inject a shared library that will be loaded before the original shared library. Some web applications will use system binaries like ping or host which can be misused for this purpose.

Some Linux rootkits also use this technique to hide themselves. You won't find any malware on a running Linux system, ps, top, htop and others will not show any malicious processes or activity, but the malware is still there.

ls will not show any files or traces belonging to the malware. To find an infection, you have to check the filesystem while the system is NOT running. You have to boot into a live CD or USB stick and check the filesystem with a tool like rkhunter. The /tmp directory is also a good place to look for malicious files.

Security measures

  • If possible, use a read-only filesystem for the web application.
  • Use AppArmor or SELinux to restrict access to the filesystem or to sanitize the environment before executing a binary.
  • Only use statically linked binaries.
  • In containers, use a read-only filesystem and drop all capabilities.

These are just examples, but you should be aware of these issues. A more complete list would go beyond the scope of this README.

What else can I do with LD_PRELOAD?

  • Override malloc to use a custom allocator
  • Decrypt code from code "encryption" tools (already done this with some Perl scripts)
  • Hook into libssl.so to log cleartext TLS traffic
  • The possibilities are endless

About

Demonstrates the use of LD_PRELOAD

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published