Shared library -- security issues

Introduction to shared library

Create shared libraries with a sequence like:
        gcc -c -fPIC filename.c
        gcc -fPIC -shared -o libNAME.so *.o
To link a program against a shared library you do:
        gcc -o program *.o -L /path-to-dir-where-lib-is -lNAME
As mater of fact, this "linking" create in program only some "calling hooks". The code from the library is not linked into the executable, so the program is not completed. The final linkage is done by the operating system at runtime. This require that the shared library to be present into a location so that the operating system dynamic loader can locate it for final linkage. The runtime linker ld.so will search for the library into the paths listed into the variable LD_LIBRARY_PATH, then look into the cashed library listing /etc/ld.so.cache and then into the standard system libraries directories:/lib and /usr/lib. To update the cache, you run ldconfig who will update the cache with the libraries existing into the directories listed into /etc/ld.so.conf.
In case you want to create a "self contained" program you can use:
        gcc -o program *.o -static -L /path-to-dir-where-lib-is -lNAME
This will physically link the code from the library into the executable, so the resulting program is self contained, i.e. no linkage is done(or required) at runtime.

Shared library attack

Let's say your program use the shared library libdemo.so. You linked your program against this library by regular way: gcc -o program *.o -L /the-right-path -ldemo. If a malicious program succeed to alter your environment, it can add in front of the LD_LIBRARY_PATH(i.e. LD_LIBRARY_PATH=/tmp/some-fake-dir/:$LD_LIBRARY_PATH) a directory where it saved a malicious library having the same name libdemo.so and exporting all the symbols used in your program (to avoid runtime linkage error). When you start your program, instead of good library, it get linked with the malicious library.
Another possibility of attack involve altering the LD_PRELOAD variable. This one, hold a list of libraries which will be loaded before any other library. The symbols present in preloaded library will NOT be loaded anymore from the good library, but otherwise, the good library symbols are used. This make the job easier to the hacker, who is now not required to reproduce all the good library, but he can overwrite only the function of interest. This is very handily for writting a small malicious library who is carried as payload of a virus to perform more damaging things. For example, intercepting your stdin when "is just happen" to type your secret PGP passphrase :-) This may be really bad !!!

Hopefully, there are defenses against this kind of attack:

Plug-in's -- dynamically loading shared libraries

Another usefull technique using shared libraries are the ability to load shared libraries on request (programmatically) rather than link your program against it. This enable you to build programs with functionality extensible at runtime, by plug-in new library.
To achieve that, you can use the libdl.so(header file dlfcn.h), who is a library providing support for runtime shared library loading. This library export 4 functions: For more information type man dlopen.

Building a plug-in manager in C++

A plug-in manager, should insure not only loading/unloading the libraries but also the symbol consistency. So, prevent calling a symbol from a unloaded library. Also, there are cases when a plug-in may be updated. In this case the reload method of the plug-in manager, should be able to keep consistency of already taken symbols since chances are that a reload will relocate all the symbols at different addresses.
The demo presented here, will create a plug-in manage to be used for managing task modules for the Trusted programs server. Capabilities:
  1. Using full name module mapping
  2. Each module will have associate a name. Using a separate map (in real life from a config file, but hardcoded in the demo) each module name have associated a full path name of the shared library implementing the module.
  3. Using safe function wrappers
  4. The real address of a function from a module, is hidden inside of a function object. The function object have "intimate relationsheep" with the plug-in manager, so, when a module is unloaded any further call to any symbol taken from that module will be denied(crash prevention).
  5. Dynamically modules update
  6. The plug-in manager provide a reload method to allow reloading a library in case it was updated on the disk. This will be a safe reload, symbols wrappers being deactivated during unload reload process, and then updated to newly values. From the "outside of plug-in manager" the changing of module will be transparent.
  7. Symbol overwritting
  8. If a function from a module need to be updated, but a new module is not available, a workaround is possible. Implement a new module having only the updated function then declare that old_func/old_module is replaced by new_func/new_module.

The class ModuleManager keep inside a map betwen module name and a ModuleData object. The class ModuleData keep a map betwen function name and the function pointer. To call a function we use an ModuleFunction function object. When a ModuleFunction object is created, it register itself into a vector inside the ModuleData object who provide the function it wrap around. When a module is unloaded, it can set the pointers inside the all wrappers to NULL. Any further call to that wrapper will return imediatelly. This way, we can avoid crashes that may result if we keep pointers to functions.
When a ModuleFunction object is initialised with a module a function name, it first check if there is a overwriting record for that function/module. If yes, the new values are used to get the pointer inside. This is the way we can insure transparently update of some functions from some module, by adding a module who overwrite some functions.
Thedemo downloadable here, show a minimal implementation of this plugin manager.


Back to advanced Advanced Unix programming techniques page

Sys++ Project Home page

Visit M.T.M. Home Page