UNIX LD_PRELOAD trick

Posted by Preacher on

First let me clarify what LD_PRELOAD is. On UNIX, ld is the program which takes care of linking executables with their needed shared libraries, or object files when building a single executable.
ld.so or ld-linux.so, located in /lib/, takes care of loading dynamically linked executable into memory, it contains a special section which allows us to run it as an executable. Some environment variables tell the linker where to look for the needed libs.

This LD_PRELOAD variable is used to specify the libs which will be loaded before the others in the default paths. Thus, some functions in some lib can be overridden using this variable.

I think things are quite clear about our opportunities here. We can hook some functions quite easily this way, and thus hijack a program's execution flow.

Lets build a simple program protected by a password, I call it vuln.c.

Compile this with gcc vuln.c -o vuln -s and run it, absolutely nothing surprising:
$./vuln
Password required: dsd
Access denied

The obvious target here is the strcmp function. So lets hook it. We want the strcmp() call to succeed even with a wrong password. So here's the code for 'hook.c':

And that's all. This strcmp() version will always return 0, and thus, password testing using it with the LD_PRELOAD trick will always fool the target program into thinking both the password and user input match.

Now we need to compile our library with: gcc hook.c -fPIC -shared -o hook.so. We indicate gcc to build a shared lib using the -shared flag, -fPIC is required when building a shared lib. Basically, it tells gcc to use Position Independant Code (PIC): use relative addresses instead of absolute.

Let's run our vulnerable program with our hook lib:
$export LD_PRELOAD="./hook.so"
$./vuln
Password required: rekt
Access granted

Note: this trick does not work on SUID binaries, unless your library is SUID as well.