basic example
0x30 [ ARGS ] <- parameters
0x28 [ RIP ] <- stored return pointer
0x20 [ RBP ] <- stored frame pointer
0x18 [ AAAAAAAAAAAAAAAA ] <- local vars
0x10 [ 0000000000000001 ] <- an int?
0x08 [ DEADBEEFCAFEBABE ] <- a pointer
0x00 [ 5945455459454554 ] <- 4 characters
referenced in relation to rbp
e.g. rbp-0x4
rbp-0x4
rbp+0x8
what happens when you write more content than a buffer can hold
so where exactly does that content go
this could allow us to change the application flow
what functions cause buffer overflows?
char buffer[32] a;
// read content
gets(a);
fgets(a, 0x32, stdin)
// printf, but write to a string not stdout
sprintf(a, "%s %s %d", some, random, vars);
snprintf(a, "%s %s %d", 0x32, and, more, vars);
it’s not just reading content, but also copying?
char buffer[32] a, buffer[64] b;
// copy contents of b into a
strcpy(a, b);
strncpy(a, b, 64);
// append contents of b onto a
strcat(a, b);
strncat(a, b, strlen(a) + strlen(b));
binja is really nice and tells us the distance
if we wrote 40 bytes of padding, and one additional byte into the buffer, we would overwrite the int
kinda like bruteforce but smart
# gets(buffer)
$ AAAABBBBCCCCDDDDEEEEFFFF
# we SIGSEGV at RIP = EEEEEEEE
then we need 16 bytes of padding before the return address
pwntools
cyclic(20) # generate a chunk of length 20
c = cyclic_gen()
c.get(n) # get a chunk of length n
c.find(b'caaa') # (8,0,8): pos 8, which is chunk 0 at pos 8
bash
# you can also do it on commandline
cyclic 12 # aaaaaaabaaac
cyclic -l aaab # -> 1 = find chunk
cyclic -o aaae # -> 13 = find offset
position independent execution
win()
PIE is a binary protection
notice the region is entirely different
# no PIE
$ ./leak
win() is at 0x08041234
# with PIE
$ ./leak
win() is at 0x05650161
$ ./leak
win() is at 0x05650911
address space layout randomization
ASLR is a kernel protection
using ASLR
# turn aslr off
sudo sysctl kernel.randomize_va_space=0
# check if it's on
cat /proc/sys/kernel/randomize_va_space
they save the day and make overflows impossible
__stack_chk_fail()
thing is in some of the source code you’ll have read 0x30 [ ARGS ] <- parameters
0x28 [ RIP ] <- stored return pointer
0x20 [ RBP ] <- stored frame pointer
0x18 [ AAAAAAAAAAAAAAAA ] <- local vars
0x10 [ 0000000000000001 ] <- an int?
0x08 [ DEADBEEFCAFEBABE ] <- a pointer
0x00 [ 5945455459454554 ] <- 4 characters
real value stored somewhere else, and checked before the function returns
memory leaks basically