Skip to content

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