Skip to main content

Adding Back Doors to the Standard C Library

Adding Back Doors to the Standard C Library

Hacked by chrootstrap December 2003

(GNU Free Documentation License)

In computer terms, a library is an archive of reusable functions, data, and types. When a program uses parts of a library, the library is said to be statically linked when the library's parts are copied into the program and dynamically linked when the parts are loaded when the program are running. Libraries which support dynamic linking are said to be shared libraries because their parts may be used by many different programs, even at the same time. Only one copy of the parts needs to be on the system and any updates to a part apply to all programs using the part. Because of these advantages, shared libraries are very popular on many operating systems including Linux.

Normally when a shared library is updated or changed, it has to be rebuilt from all of the original parts and the new library simply replaces the old library. It is possible, however, to modify the library without the original objects. This is usually done with the BFD library, which allows the internal structures of programs and libraries to be operated in a fairly high level way. However, BFD does not allow for the alteration of a library in place; it is necessary to create a new library from the previous one while, perhaps, changing some of its properties. The code to this (viz. object_copy in objcopy.c of binutils) is fairly laborious and heavy handed.

I will explain the use of a somewhat different technique in order to modify the operations of an existing library, the standard C library, in place without changing the file size or internal structure. The end result will be used to make a 'back door' in the open function that will allow us to handle any file name that starts with "http://" by return the file handle of a socket ready for the reading of the file requested by HTTP. Any program that uses the shared library and calls open will have this functionality added to it.

Our example will be for x86 ISA Linux. The code is easily adapted to other architectures (assuming a familiarity with elementary assembly language) and the ideas can be generally applied to systems with ELF shared libraries. To begin, I write the specialized handler for the open function with typical Posix library calls. Please study this version first to get a quick understanding of how the operation is accomplished:

openbackdoor_library.c

However, within the C standard library we should not be loading other libraries and can make things simpler by foregoing the use of standard library calls as well. Furthermore, we are not going to insert from any other section that .text and therefore may not overly use string constants or global variables. In order to meet these criteria we must rewrite the function using system calls and restricted techniques. The most complex rewrite has to do with providing basic gethostbyname functionality. Here is the version that is completely independent of position and other functions:

openbackdoor_systemcalls.c

You'll notice that at the very end of our function we handle the case of a pathname that doesn't start with "http://". We simply use the open system call.

Now we are ready to compile the function and prepare it for insertion into the library. This done simply by entering:

gcc -c openbackdoor_systemcalls.c

Now we need to extract our code into the raw function data:

objcopy -O binary openbackdoor_systemcalls.o

openbackdoor_systemcalls.o is now purely the function's contents. All ELF structures and additional sections have been stripped away. It is ready to be introduced into the standard library. It is time now to prepare the library for insertion. We will test our changes on a disposable copy of the library. Begin by making an empty directory, e.g. one called bdoor. Inside the new directory make two subdirectories, one named lib and one named etc. Into etc copy resolv.conf from /etc/resolv.conf. Now make a small test program named test.c. The test program should have these contents:

#include 
#include

int main (int argc, char **argv)
{
int fd;
char buf [1024];

if ((fd = open("test.c", O_RDONLY, 0)) < fd =" open(">

Compile this program ordinarily ("gcc test.c"). Into the subdirectory, lib, copy two files, ld-linux.so.2 and libc.so.6. These two libraries will be somewhere on your system already, probably in /lib. libc.so.6 is the standard C library and ld-linux.so.2 is the dynamic linker which will our test program will need to load the standard library. Right above the bdoor directory you can switch to using this library copy with your test program by chrooting (you will need to be root to this):

chroot bdoor /a.out

If you do this before patching the standard library, it should simply print out the source code for test.c Now, we need to discover some details about the standard library. We need to learn the location of the current open function, the location of the vfwprintf function, the location of the dynsym symbol, and the location of the open symbol. The vfwprintf function is used because we are going to commandeer its location as it's a bloated function that is never called by anything on nearly every system. Start by getting a print out of the dynamic symbol table of libc.so.6 by doing this:

objdump -T libc.so.6 > symboldump

Open symboldump and remove the first four lines to reach the point where the SYMBOL TABLE listings begin. Search for dynsym. Record the leftmost number; it is the location of what this symbol points to (the dynamic symbols), probably between 0x3000 and 0x4000. Now search for open . You will find many instances of open, but you need the one that is only "open" and doesn't have any other text in its identifier. Now record the location (leftmost entry) along line number at which this symbol occurs in the symboldump file. The line number will be used to calculate where it is in the dynsym listing. Finally, find and record the location of vfwprintf. The size is listed after what section is in (.text). Your inserted function can only be up to this size. For example, here are the values in my library:

dynsym symbol location = 0x339C
open function location = 0xD5A20
open line number = 1997
vfwprintf function location = 0x51E10

Now we need to calculate the location of the open symbol. This is (open_line_number * 0x10 + dynsym_symbol_location). In my example it is 0xb06c. Finally, you will need the size of your new function, which is its file size after objcopy -O binary. In my case the new size is 4631. Now write an inserter program using your values in the define statements:

#include 
#include

#define OPEN_SYM 0xb06c - 128
#define OPEN_FUNC 0xd5a20
#define NEW_OPEN_SIZE 4631
#define VFWPRINTF_FUNC 0x51e10

int main ()
{
int x, fd;
char buf [2048];
char c = 0xe9;

fd = open("libc.so.6", O_RDWR, 0);
lseek(fd, OPEN_FUNC, SEEK_SET);
write(fd, &c, 1);
x = VFWPRINTF_FUNC - OPEN_FUNC + 4;
write(fd, &x, 4);
lseek(fd, OPEN_SYM, SEEK_SET);
x = OPEN_FUNC;
x = (int)memmem(buf, read(fd, buf, 2048), &x, 4) - (int)buf;
lseek(fd, OPEN_SYM + x, SEEK_SET);
x = VFWPRINTF_FUNC;
write(fd, &x, 4);
x = NEW_OPEN_SIZE;
write(fd, &x, 4);
lseek(fd, VFWPRINTF_FUNC, SEEK_SET);
while((x = fread(buf, 1, 2048, stdin)) > 0) {
write(fd, buf, x);
}
close(fd);
return 0;
}

What we have done is changed the description of the v symbol's contents. They describe the location and size of our code which we copy into the vfwprintf location. Calculating the location of the open symbol from the line number of the print out gives a result that varies a few bytes more or less from the actual location. This is why we back track a little from the estimate and then search to find the precise location. We also change the contents of the existing open function to simply jump to our back door. This way any standard library function which uses the open function (and has already had its address hard-coded into it) will be redirected to our back door. Cool beans!

Now compile it and run it in the lib directory as:

./a.out <>

Now try your test program again through chroot and ensure that everything works correctly. If everything went correctly, you should now have a back door in the open function that handles pathnames that start with "http://". You can put several functions in vfwprintf, ensuring correct offsets each time. If you want to be nice, you can add a small bit of code to return -1 at the start of vfwprintf and put your functions after that. If you're brave, copy your new library to where the original was, backing up the original first, and give it a try. Now all your binaries that use the shared open function can easily work with HTTP addresses. Happy hacking!

Comments

Popular posts from this blog

How to Hack a Website in Four Easy Steps

Every wondered how Anonymous and other hacktivists manage to steal the data or crash the servers of websites belonging to some of the world biggest organisations? Thanks to freely available online tools, hacking is no long the  preserve of geeks , so we've decided to show you how easy it is to do, in just four easy steps. Step 1: Identify your target While  Anonymous  and other online hacktivists may choose their targets in order to protest against perceived wrong-doing, for a beginner wanting to get the taste of success with their first hack, the best thing to do is to identify a any website which has a vulnerability. Recently a hacker posted a list of 5,000 websites online which were vulnerable to attack. How did he/she identify these websites? Well, the key to creating a list of websites which are likely to be more open to attack, is to carry out a search for what is called a Google Dork. Google Dorking , also known as Google Hacking, enables you find sen

How to Hack Facebook Password in 5 Ways

Check out the following post from  fonelovetz blog  on facebook account hacking. This is one of the most popular questions which I'm asked via my email.And today I'm going to solve this problem one it for all.Even though i have already written a few ways of hacking a facebook password.Looks like i got to tidy up the the stuff here.The first thing i want to tell is.You can not hack or crack a facebook password by a click of a button.That's totally impossible and if you find such tools on the internet then please don't waste your time by looking at them! They are all fake.Ok now let me tell you how to hack a facebook account. I'll be telling you 5 of the basic ways in which a beginner hacker would hack.They are: 1.Social Engineering 2.Keylogging 3.Reverting Password / Password Recovery Through Primary Email 4.Facebook Phishing Page/ Softwares 5.Stealers/RATS/Trojans I'll explain each of these one by one in brief.If you want to know more about them just

How to Hack Someone's Cell Phone to Steal Their Pictures

Do you ever wonder how all these celebrities continue to have their private photos spread all over the internet? While celebrities' phones and computers are forever vulnerable to attacks, the common folk must also be wary. No matter how careful you think you were went you sent those "candid" photos to your ex, with a little effort and access to public information, your pictures can be snagged, too. Here's how. Cloud Storage Apple's iCloud service provides a hassle free way to store and transfer photos and other media across multiple devices. While the commercial exemplifies the G-rated community of iPhone users, there are a bunch of non-soccer moms that use their iPhones in a more..."free spirited" mindset. With Photo Stream enabled (requires OS X Lion or later, iOS 5 or later), pictures taken on your iPhone go to directly to your computer and/or tablet, all while being stored in the cloud. If you think the cloud is safe, just ask Gizmodo

How to Hack Samsung Phone Screen Lock

I have discovered  another  security flaw in Samsung Android phones. It is possible to completely disable the lock screen and get access to any app - even when the phone is "securely" locked with a pattern, PIN, password, or face detection. Unlike another recently released flaw, this doesn't rely quite so heavily on ultra-precise timing. Video . Of course, if you are unable to download a screen unlocker, this security vulnerability still allows you to  dial any phone number and run any app ! HOWTO From the lock screen, hit the emergency call button. Dial a non-existent emergency services number - e.g. 0. Press the green dial icon. Dismiss the error message. Press the phone's back button. The app's screen will be briefly displayed. This is just about long enough to interact with the app. Using this, you can run and interact with any app / widget / settings menu. You can also use this to launch the dialler. From there, you can dial any phone