7

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.

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. I've been trying to follow along with example 3 from insecure.org/stf/smashstack.html but I've gotten lost when it comes to figuring out how many bits to adjust my variable. Any help?

4

As you have already identified you will need to return to address 0x400631. When you smash the stack with your argument you should control EIP. Ie:

./a.out AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

You should see EIP of 0x41414141. Now you need to determine where in your stack of A's the 4 bytes that becomes EIP are located. You can use tools like metasploit's pattern_create.rb/pattern_offset.rb or since it's such a small buffer you can do it manually:

./a.out AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTT

And based on the address of EIP you can now determine if it's A (x41),B (x42),C (x43), etc. This will tell you how many bytes you need to place before \x31\x06\x40\x00. This is of course not a reliable exploit as the return address is hardcoded, but it will suffice for your learning example.

-2

while I do not agree with your plan,

the way to skip an instruction is to modify the callers' pc register value, that is saved on the called functions' stack

So skipping one instruction is rather simple, because instruction size (in modern CPUs) is relatively consistent.

However skipping a line of C code is a whole different problem because the line could contain any number of instructions.

A number of instructions that can change depending on compiler parameters such as the level of optimization.

  • The gdb output lets him map code to instrution address. He has clearly identified the target address. He's looking for a specific solution, not a generic technique. – wireghoul Apr 16 '15 at 3:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.