3

I'm trying to exploit the following code with a buffer overflow and make it run the overflowed function:

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

    void overflowed() {
        printf("%s\n", "Execution Hijacked");
    }

    void function(char *str){
        char buffer[5];
        strcpy(buffer, str); 
    } 
    void main(int argc, char *argv[])
    {
        function(argv[1]);
        printf("%s\n", "Executed normally");
    }

I tried to fuzz the program with 16 A and 4 B and successfully overwrote RBP with B:

ss#1

ss#2

Then I try to make the program run the overflowed function:

ss#3

I tried to overwrite RBP with the following command:

r $(python -c 'print "A" * 16 + "\x44\x05\x40\x00")

ss#4

I think I've overwritten RBP but when I continue running the program I get the error below.

ss#5

Questions

  • Is the issue that I need to overwrite 0x7fff with 0x0000?
  • How would I go about doing that?

NOTE: The platform is Ubuntu 12.04 32 bit.

user1758952
  • 131
  • 1
  • 1
  • 3

1 Answers1

3

It is not rbp what you have to control, but the instruction pointer rip. When the function returns, ret instruction will take whatever is at the top of the stack and send execution there. So, notice those last two instructions, pop rbp and ret. The first one will take whatever is left at the top of the stack at that moment and store it in rbp; the second will take whatever is left at the top of the stack next and store it in rip, the instruction pointer.

Basically, you have to make sure that, when execution reaches that ret instruction, at the top of the stack (where rsp points) you are seeing your target address. If you fail to pop a valid address into rip, you will get a segmentation fault the moment the processor tries to read an instruction from an invalid (i.e. unmapped) location. Alternatively, if you overwrite rbp with some trash value but execution continues undeterred (i.e. leaving the actual return address untouched), you may set the program up for an eventual attempt to read or write to some invalid memory location, also causing a segmentation fault, so you have to account for that.

Also, keep in mind that 64 bit addresses and registers are 8 bytes long. For the exploit to work, you should replace the return address for (in little endian)

0x44 0x05 0x40 0x00 0x00 0x00 0x00 0x00

Hence, ret instruction will pop value 0x0000000000400544 into the instruction pointer, granting you control over the execution path.

If you only use strcpy, though, you may indeed have problems dealing with those null bytes. You see, strcpy exercise are way old, from the 32 bit era; today, in x64, a bad null byte can be a real hassle when trying to overwrite target addresses. Fortunately (or not, actually), misuse of strcpy is not the only way to mess things up. You may want to adjust your example to use memcpy, to read from a file or a socket, to take a bogus index for an out of bounds array access, or even have some loop with an attacker-controllable break condition. Coming up with new, creative ways to screw things up is actually good way to practice your exploitation skills.

user25972
  • 143
  • 1
  • 7