4

I'm trying to find a way to exploit the buffer overflow vulnerability in the following source code so the line, printf("x is 1") will be skipped:

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

void func(char *str) {
     char buffer[24];
     int *ret;
     strcpy(buffer,str);
}

int main(int argc, char **argv) {
    int x;
    x = 0;
    func(argv[1]);
    x = 1;
    printf("x is 1");
    printf("x is 0");
    getchar();
}

In order to do this, I want to modify the "func" function. I know that I will need to use the ret variable in order to modify the return address to just past the line I want to skip, but I'm not sure how to actually do that. Does anyone have a suggestion?

EDIT:

By using gdb, I was able to find the following calls in the main function:

Temporary breakpoint 1, 0x00000000004005ec in main ()
(gdb) x/20i $pc
=> 0x4005ec <main+4>:   sub    $0x20,%rsp
   0x4005f0 <main+8>:   mov    %edi,-0x14(%rbp)
   0x4005f3 <main+11>:  mov    %rsi,-0x20(%rbp)
   0x4005f7 <main+15>:  movl   $0x0,-0x4(%rbp)
   0x4005fe <main+22>:  mov    -0x20(%rbp),%rax
   0x400602 <main+26>:  add    $0x8,%rax
   0x400606 <main+30>:  mov    (%rax),%rax
   0x400609 <main+33>:  mov    %rax,%rdi
   0x40060c <main+36>:  callq  0x4005ac <func>
   0x400611 <main+41>:  movl   $0x1,-0x4(%rbp)
   0x400618 <main+48>:  mov    $0x4006ec,%edi
   0x40061d <main+53>:  mov    $0x0,%eax
   0x400622 <main+58>:  callq  0x400470 <printf@plt>
   0x400627 <main+63>:  mov    $0x4006f3,%edi
   0x40062c <main+68>:  mov    $0x0,%eax
   0x400631 <main+73>:  callq  0x400470 <printf@plt>
   0x400636 <main+78>:  callq  0x400490 <getchar@plt>
   0x40063b <main+83>:  leaveq
   0x40063c <main+84>:  retq
   0x40063d:    nop

Although, I'm confused as of where to go from here. I know that the function will return to the line of 0x400611 and that I need to cause it to jump to 0x400631, but I'm not sure how to determine how many bits to jump or how I should be modifying the ret variable.

user2276280
  • 603
  • 2
  • 10
  • 24

1 Answers1

1

The idea is to find where the return address to the main function is on the stack and then add to this address the offset to the command you'd like to get. To do that:

  1. Use the disassembly to find the difference between the original return address and the new one:

    enter image description here

  2. Find the func frame address on the stack using a local variable (e.g. the function parameter):

    enter image description here

  3. Finally find the relative location of the return address on the stack comparing the address of the local variable:

    enter image description here

Using the above your code would look something like:

void func(char *str) {
    // 1. Get the address of an object on the stack
    long *ret = (long*)(&str);      

    // 2. Move ret to point to the location of the return address from this function. 
    //    Per the example above on my system (Windows 64bit + VS) it was just -1
    ret -= NUMBER_OF_ITEMS_IN_THE_STACK_BEFORE_RETURN_ADDR;

    // 3. Modify the return address by adding it the offset to command to go to (in my 
    //   (case 33).
    *ret = *ret + OFFSET_TO_COMMAND;

    // The rest of your code
    char buffer[24];
    strcpy(buffer, str);
}

As noted above, the exact numbers are system dependent (i.e. OS, Compiler, etc.). However, using the techniques above you should be able to find the right numbers to set.

As a final note, modern compilers (e.g. VS) may have security guards for protecting stack corruption. If your program crashed because of it check in your compiler options how this option can be disabled.

Community
  • 1
  • 1
Amnon Shochot
  • 8,998
  • 4
  • 24
  • 30
  • Could you explain jpw you determined the address ret points to after the first step? I am trying to print the address out to the command line but it doesn't seem to match up with anything in my assembly dumps. The pointer looks like "0xf201edd6" when I print it to the command line, but my dumps of the main function all look similar to "400600". – user2276280 Apr 16 '15 at 20:03
  • Added some images to my answer to make it clearer. – Amnon Shochot Apr 16 '15 at 20:44