|
features post Articles
(Articles)
online chat server:
irc.xor.cx
channel:
#neworderrandom article
quotable quotes CALLAGHAN: you know nothing of the pain I feel, nothing. Old Skool NO Boards
|
Kung Foo - lesson three - linker hijacking
@ Articles -> Programming
Jun 09 2002, 05:00 (UTC+0) | mstevens writes: Kung Foo - lesson three - linker hijacking Mike Stevens (mike@zemos.net) When you write a program in C you have 6 steps. Editing, where you type the program into a text editor. Preprocessing, where preprocessor macros are evaluated, such as #define and #include. Compiling, which translates C code to machine language object code. Linking, which adds in the necessary functions that your program depends on. Loading, which brings the program into memory. Last is execution, which is the CPU running the code from memory. [Deitel] One of the marvels of modern computing is shared libraries. Some people love them, others despise them. When you go to link in functions that your program needs, the linker used to stick all the functions needed into your programs executable. Now this creates some problems. Obviously commonly used functions, like the C library, will be duplicated in the executable file of every program that uses them. This duplication will carry over into the main memory when it is loaded there for execution. Thus the solution is to keep commonly used libraries in one file, which is loaded into memory when one program needs to use it. After it is loaded into memory, other programs can use the same code, without having to duplicate it in memory. Shared libraries enable some cool things. You can make a library of wonderful functions. This could be so great that you close the source and sell it. Now you want to enable open source applications to use your wonderful library, but don't want the GPL eating your source code or having the application bundled with your code. The answer is to have your clients buy your library and install it, then they can run whatever program they have that depends on your library. Updating code also becomes easier. If you have a bug in a shared library, just replace it with an updated one, all the applications start using the new library. Now this is where the fun comes in. There are two wonderful features that let users do their own linking. These are the environment variables LD_LIBRARY_PATH and LD_PRELOAD. The first, LD_LIBRARY_PATH is like the PATH environment variable, except it is for libraries instead of executables. If you want to have your own personal lib directory with shared libraries, this is the variable to set. LD_LIBRARY_PATH=~/lib will get the linker to check for required shared libraries in your home directory if it can't find them elsewhere. We want to focus on LD_PRELOAD. The form of it we shall use is LD_PRELOAD=/some/library/path/library.so. What this will do is to load the functions from library.so _before_ other shared libraries are checked. This enables the user to take a binary and run it with his library functions, instead of the system's. Let's try it out. mike@jumpgate:/tmp/fs$ cat libgetuid.c int getuid(void); int geteuid(void); int getuid(void) { return 0; } int geteuid(void) { return 0; } mike@jumpgate:/tmp/fs$ gcc -c libgetuid.c mike@jumpgate:/tmp/fs$ gcc -shared libgetuid.o -o libgetuid.so mike@jumpgate:/tmp/fs$ cat getuid.c main() { printf("%d\n",getuid()); } mike@jumpgate:/tmp/fs$ gcc getuid.c mike@jumpgate:/tmp/fs$ ./a.out 1000 mike@jumpgate:/tmp/fs$ LD_PRELOAD=/tmp/fs/libgetuid.so ./a.out 0 mike@jumpgate:/tmp/fs$ It seems to work perfectly. Now you may be wondering, why don't I do a LD_PRELOAD=/my/evil/lib.so /bin/su and have /bin/su read the password file incorrectly and think that I deserve to be root. I have bad news. setuid and setgid programs don't honor the LD_PRELOAD flag. This has been the basis of a few exploits in the past, however most systems are immune to this sort of attack. It might be a good thing to modify if you want to stealthily change system behavior. So where is the practical use you say? I'm sure some of you are thinking of a few programs that make use of this, so am I. My favorite is artsdsp. A brief background on arts. It lets more than one program play sound at the same time, however it operates through /dev/dsp, thus no programs other than the arts daemon may open that file. artsdsp is a little hack to make old programs that write to /dev/dsp work with arts. artsdsp is a shell script that sets LD_PRELOAD to a library which hijacks the functions that are used to open/read/write /dev/dsp and replaces them with wrappers that redirect the data to/from artsd. So shared libraries enable users to make older programs compatible with newer systems. For an example of a good hijacking library check out artsdsp's library. http://arts-project.org/download/arts-0.6.0.tar.gz It is in the arts-0.6.0/arts/artsc/ folder of the tar.gz archive. You will find out that many programs can be modified without having their source code or root access, by this simple method. Deitel - C How to Program, Deitel and Deitel |
| Top of page
|