Stack
Stack Smashing¶
Default stack for sample program:
local int sum |
local int zz |
local int yy |
local int xx |
Saved ESP |
Saved Return Address |
paramater a |
paramater b |
paramater c |
Callers Stack Frame |
Format String Vulnerability¶
- Can be used to do an arbitrary write
- Can be used to read values from the stack
Vulnerable Example:
#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
printf("Enter a String\n");
char input[32];
scanf("%s", input);
//Vulnerable part
printf(input);
return 0;
}
Since printf has an arbitrary number of arguments its up to the first argument to determine how many arguments are in the function.
This means that the program will pop values from the stack and read send them as arguments to printf. This means that you can read values that are on the stack.
In ARM will lead to reading values in registers and the stack since it passes parameters in registers for the first 4 arguments in registers, (R1, R2, R3, R4) then it uses the stack. This means that you can read from the first 4 registers and the stack.
Tips¶
- Use the arbitrary write to Write to the global offset table for
__stack_check_fail
- Use Env variables for null bytes
- Use null bytes at the end of the input
DEP (Data Execute Permission) / NX (Non Execute bit)¶
Prevents writing and executing the same memory mapped region.
With this protection the executable will be mapped mutable times in to the memory as RW- and as R-X.
Example¶
vmmap without DEP or NX:
0x400000 0x402000 r-xp 2000 0 /home/test/Downloads/CTF/Hitcon2016/SleepyHolder_noex
0x601000 0x602000 r-xp 1000 1000 /home/test/Downloads/CTF/Hitcon2016/SleepyHolder_noex
0x602000 0x603000 rwxp 1000 2000 /home/test/Downloads/CTF/Hitcon2016/SleepyHolder_noex
0x603000 0x624000 rwxp 21000 0 [heap]
0x7ffff7a0d000 0x7ffff7bcd000 r-xp 1c0000 0 /lib/x86_64-linux-gnu/libc-2.23.so
0x7ffff7bcd000 0x7ffff7dcd000 ---p 200000 1c0000 /lib/x86_64-linux-gnu/libc-2.23.so
0x7ffff7dcd000 0x7ffff7dd1000 r-xp 4000 1c0000 /lib/x86_64-linux-gnu/libc-2.23.so
0x7ffff7dd1000 0x7ffff7dd3000 rwxp 2000 1c4000 /lib/x86_64-linux-gnu/libc-2.23.so
0x7ffff7dd3000 0x7ffff7dd7000 rwxp 4000 0
0x7ffff7dd7000 0x7ffff7dfd000 r-xp 26000 0 /lib/x86_64-linux-gnu/ld-2.23.so
0x7ffff7fda000 0x7ffff7fdd000 rwxp 3000 0
0x7ffff7ff7000 0x7ffff7ffa000 r--p 3000 0 [vvar]
0x7ffff7ffa000 0x7ffff7ffc000 r-xp 2000 0 [vdso]
0x7ffff7ffc000 0x7ffff7ffd000 r-xp 1000 25000 /lib/x86_64-linux-gnu/ld-2.23.so
0x7ffff7ffd000 0x7ffff7ffe000 rwxp 1000 26000 /lib/x86_64-linux-gnu/ld-2.23.so
0x7ffff7ffe000 0x7ffff7fff000 rwxp 1000 0
0x7ffffffde000 0x7ffffffff000 rwxp 21000 0 [stack]
0xffffffffff600000 0xffffffffff601000 r-xp 1000 0 [vsyscall]
vmmap with DEP or NX:
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
0x400000 0x402000 r-xp 2000 0 /home/test/Downloads/CTF/Hitcon2016/SleepyHolder
0x601000 0x602000 r--p 1000 1000 /home/test/Downloads/CTF/Hitcon2016/SleepyHolder
0x602000 0x603000 rw-p 1000 2000 /home/test/Downloads/CTF/Hitcon2016/SleepyHolder
0x603000 0x624000 rw-p 21000 0 [heap]
0x7ffff7a0d000 0x7ffff7bcd000 r-xp 1c0000 0 /lib/x86_64-linux-gnu/libc-2.23.so
0x7ffff7bcd000 0x7ffff7dcd000 ---p 200000 1c0000 /lib/x86_64-linux-gnu/libc-2.23.so
0x7ffff7dcd000 0x7ffff7dd1000 r--p 4000 1c0000 /lib/x86_64-linux-gnu/libc-2.23.so
0x7ffff7dd1000 0x7ffff7dd3000 rw-p 2000 1c4000 /lib/x86_64-linux-gnu/libc-2.23.so
0x7ffff7dd3000 0x7ffff7dd7000 rw-p 4000 0
0x7ffff7dd7000 0x7ffff7dfd000 r-xp 26000 0 /lib/x86_64-linux-gnu/ld-2.23.so
0x7ffff7fda000 0x7ffff7fdd000 rw-p 3000 0
0x7ffff7ff7000 0x7ffff7ffa000 r--p 3000 0 [vvar]
0x7ffff7ffa000 0x7ffff7ffc000 r-xp 2000 0 [vdso]
0x7ffff7ffc000 0x7ffff7ffd000 r--p 1000 25000 /lib/x86_64-linux-gnu/ld-2.23.so
0x7ffff7ffd000 0x7ffff7ffe000 rw-p 1000 26000 /lib/x86_64-linux-gnu/ld-2.23.so
0x7ffff7ffe000 0x7ffff7fff000 rw-p 1000 0
0x7ffffffde000 0x7ffffffff000 rw-p 21000 0 [stack]
0xffffffffff600000 0xffffffffff601000 r-xp 1000 0 [vsyscall]
Check NX with GDB (pwndbg):
pwndbg> checksec
[*] '/home/test/Downloads/CTF/Hitcon2016/SleepyHolder'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
Check NX with Objdump:
>>> objdump -p buf
buf: file format elf32-i386
buf
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x08048340
Program Header:
PHDR off 0x00000034 vaddr 0x08048034 paddr 0x08048034 align 2**2
filesz 0x000000e0 memsz 0x000000e0 flags r-x
INTERP off 0x00000114 vaddr 0x08048114 paddr 0x08048114 align 2**0
filesz 0x00000013 memsz 0x00000013 flags r--
LOAD off 0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
filesz 0x00000514 memsz 0x00000514 flags r-x
LOAD off 0x00000514 vaddr 0x08049514 paddr 0x08049514 align 2**12
filesz 0x0000010c memsz 0x00000114 flags rw-
DYNAMIC off 0x00000528 vaddr 0x08049528 paddr 0x08049528 align 2**2
filesz 0x000000d0 memsz 0x000000d0 flags rw-
NOTE off 0x00000128 vaddr 0x08048128 paddr 0x08048128 align 2**2
filesz 0x00000044 memsz 0x00000044 flags r--
STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
filesz 0x00000000 memsz 0x00000000 flags rw- <======Only read and write permissions for stack