master canary forging by yuki koike - code blue 2015
TRANSCRIPT
Master Canary ForgingA new exploitation method to bypass stack canaries
Who am I?
● 小池 悠生(Koike Yuki)○ a 16-year-old student
● I had been fascinated with CTF○ DEF CON 2014 Finalist○ CODEGATE Junior 2015 Winner○ now focusing on real world bug hunting and
exploitation techniques
Agenda
● Motivation● Stack Canary● Previous Bypass Techniques● Master Canary Forging● Evaluation and Countermeasures
Agenda
● Motivation● Stack Canary● Previous Bypass Techniques● Master Canary Forging● Evaluation and Countermeasures
Motivation
● I love ROP○ so I love Stack Based Buffer Overflows○ and hate Stack Canaries
● Stack Canaries can be strong protection○ It is worth finding ways to bypass them○ Are there any good methods?
Agenda
● Motivation● Stack Canary● Previous Bypass Techniques● Master Canary Forging● Evaluation and Countermeasures
Stack Canary
● For preventing BOF attacks○ Detect if the return address was overwritten
■ Kill the process if it has been tampered○ Design an “indicator”
■ The value of it should be changed before and after BOF occurred
Stack Canary
return address
frame pointer
local variables
● Append an “indicator” to a stack frame
Stack Canary
return address
frame pointer
canary 0xdeadbeef
local variables
● When BOF occurs...
Stack Canary
canaryoverwritten
● The attack will be detected since the value changed
Stack Canary
modified0x41414141
● The attack will be detected since the value changed
Stack Canary
modified0x41414141
Not 0xdeadbeefAttack Detected
Stack Canary
● For preventing BOF attacks○ Detect if the return address was overwritten
■ Kill the process if it has been tampered○ Design a “indicator”
■ The value of it should be changed before and after BOF occurred
Stack Canary
● For preventing BOF attacks○ Detect if the return address was overwritten
■ Kill the process if it has been tampered○ Design a “indicator”
■ The value of it should be changed before and after BOF occurred● Can this be ensured??
● The attack won’t be detected unless the value changed
Stack Canary
modified0xdeadbeef
● The attack won’t be detected unless the value changed
Stack Canary
modified0xdeadbeef
return address
becomes any value
● The attack won’t be detected unless the value changed
Stack Canary
⇒ACE(Arbitrary Code Execution)
Stack Canary
● Types of Stack Canaries○ Random
■ hide the original value from attackers■ randomly generate values when the
program starts○ Terminator
■ should include something like ‘\0’.■ It is hard for attackers to fit the
overwritten value to the original value.
Stack Canary
● Comparing a master canary and a canary on a stack
Agenda
● Motivation● Stack Canary● Previous Bypass Techniques● Master Canary Forging● Evaluation and Countermeasures
● ex1.c
method #1: avoid __stack_chk_fail
#include <stdio.h>void bof(int (*print)(const char *)) { char buf[16]; scanf("%s", buf); print(buf);}int main(void) { bof(puts);}
● ex1.c
#include <stdio.h>void bof(int (*print)(const char *)) { char buf[16]; scanf("%s", buf); print(buf);}int main(void) { bof(puts);}
method #1: avoid __stack_chk_fail
return addressframe pointer
canary
local variables
arguments
● ex1.c
method #1: avoid __stack_chk_fail
overwritten
arguments
#include <stdio.h>void bof(int (*print)(const char *)) { char buf[16]; scanf("%s", buf); print(buf);}int main(void) { bof(puts);}
● ex1.c
method #1: avoid __stack_chk_fail
overwritten
arguments
#include <stdio.h>void bof(int (*print)(const char *)) { char buf[16]; scanf("%s", buf); print(buf);}int main(void) { bof(puts);} a function pointer && an argument
● ex2.c
method #2: leak a canary
#include <stdio.h>
int main(void) { char buf[16]; scanf("%s", buf); printf(buf); fread(buf, sizeof(char), 32, stdin);}
● ex2.c
method #2: leak a canary
#include <stdio.h>
int main(void) { char buf[16]; scanf("%s", buf); printf(buf); fread(buf, sizeof(char), 32, stdin);}
format string bug
method #2: leak a canary
$ gdb ./ex2 -q(gdb) b 4Breakpoint 1 at 0x8048532: file ex2.c, line 4.(gdb) rBreakpoint 1, main () at ex2.c:44 scanf("%s", buf);(gdb) x/12xw $esp0xffffce60: 0xffffd129 0x0000002f 0x0804a000 0x080485e20xffffce70: 0x00000001 0xffffcf34 0xffffcf3c 0xf7e3539d0xffffce80: 0xf7faa3c4 0xf7ffd000 0x0804859b 0x48d09200(gdb) c%11$x48d09200
● Where do canaries fail in these methods?○ method #1: avoid __stack_chk_fail
■ when detecting or terminating attacks○ method #2: leak a canary
■ the canary value on the stack
The essence of bypass methods
● Where do canaries fail in these methods?○ method #1: avoid __stack_chk_fail
■ when detecting or terminating attacks○ method #2: leak a canary
■ the canary value on the stack○ method #3: overwrite the master canary
■ the original value(master canary)
The essence of bypass methods
Agenda
● Motivation● Stack Canary● Previous Bypass Techniques● Master Canary Forging● Evaluation and Countermeasures
● Following assumption:■ Linux Kernel 3.19■ glibc 2.21■ ASLR enabled
Master Canary Forging
● Where is the master canary located?○ Let’s read glibc
Master Canary Forging
static voidsecurity_init (void){ /* Set up the stack checker's canary. */ uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);#ifdef THREAD_SET_STACK_GUARD THREAD_SET_STACK_GUARD (stack_chk_guard);#else __stack_chk_guard = stack_chk_guard;#endif
● Where is the master canary located?○ Let’s read glibc
Master Canary Forging
static voidsecurity_init (void){ /* Set up the stack checker's canary. */ uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);#ifdef THREAD_SET_STACK_GUARD THREAD_SET_STACK_GUARD (stack_chk_guard);#else __stack_chk_guard = stack_chk_guard;#endif
Being assigned here
● Where is the master canary located?○ Let’s read glibc
Master Canary Forging
static voidsecurity_init (void){ /* Set up the stack checker's canary. */ uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);#ifdef THREAD_SET_STACK_GUARD THREAD_SET_STACK_GUARD (stack_chk_guard);#else __stack_chk_guard = stack_chk_guard;#endif
● Where is the master canary located?○ THREAD_SET_STACK_GUARD
■ defined in 7 architectures■ stores the canary in TLS(thread local storage)■ If not defined, the canary is stored in .bss
Master Canary Forging
● To overwrite the master canary○ When it lies in .bss
■ It is just “Arbitrary Memory Write”
Master Canary Forging
● To overwrite the master canary○ When it lies in .bss
■ It is just “Arbitrary Memory Write”○ Then, how about when it lies in TLS?
Master Canary Forging
● To overwrite the master canary○ When it lies in .bss
■ It is just “Arbitrary Memory Write”○ Then, how about when it lies in TLS?
■ In the first place, where is TLS allocated?
Master Canary Forging
● Where is TLS?○ Let’s read glibc
Master Canary Forging
void * internal_function _dl_allocate_tls_storage (void){ void *result; size_t size = GL(dl_tls_static_size);#if TLS_DTV_AT_TP size += (TLS_PRE_TCB_SIZE + GL(dl_tls_static_align) - 1) & ~(GL(dl_tls_static_align) - 1);#endif /* Allocate a correctly aligned chunk of memory. */ result = __libc_memalign (GL(dl_tls_static_align), size);
● Where is TLS?○ _dl_allocate_tls_storage is responsible for allocation
■ Inside, __libc_memalign is called● __libc_memalign calls mmap
○ So in brief, TLS is created somewhere by mmap■ ASLR makes it difficult to overwrite that area
Master Canary Forging
● One of the characterics of areas allocated by mmap:○ The areas are always adjacent to some region
Master Canary Forging
● Mapped Area Based Buffer Overflow
Master Canary Forging
target area
● Mapped Area Based Buffer Overflow○ create a new area by invoking mmap○ The new area and the target should be successive
Master Canary Forging
mapped area
target area
● Mapped Area Based Buffer Overflow○ create a new area by invoking mmap○ The new area and the target should be successive○ cause BOF in the new area○ With enough size of BOF, the target area can be
overwritten
Master Canary Forging
overwritten
● Mapped Area Based Buffer Overflow○ This seems to be able to overwrite the master canary○ Wait, can attackers invoke mmap?
Master Canary Forging
● Mapped Area Based Buffer Overflow○ This seems to be able to overwrite the master canary○ Wait, can attackers invoke mmap?
■ YES
Master Canary Forging
● Mapped Area Based Buffer Overflow○ This seems to be able to overwrite the master canary○ Wait, can attackers invoke mmap?
■ YES■ malloc
Master Canary Forging
● Mapped Area Based Buffer Overflow○ This seems to be able to overwrite the master canary○ Wait, can attackers invoke mmap?
■ YES■ malloc■ “When allocating blocks of memory larger than
MMAP_THRESHOLD bytes, the glibc malloc() implementation allocates the memory as a private anonymous mapping using mmap(2).”
Master Canary Forging
● Mapped Area Based Buffer Overflow○ following 2 conditions required:
■ Attackers can control allocation■ Heap Based BOF occurs
Master Canary Forging
1. Overwrite the master canarya. When it is located in .bss
i. Use an “Arbitrary Memory Write”b. When it is located in TLS
i. Use a mapped area based BOF2. Cause a stack based BOF
Master Canary Forging
Agenda
● Motivation● Stack Canary● Previous Bypass Techniques● Master Canary Forging● Evaluation and Countermeasures
● Evaluation○ NOT so useful
■ It requires 2 types of vulnerabilities■ Heap Based BOF is usually sufficient for ACE
○ Mapped Area Based BOF itself is useful■ Sometimes a function pointer array is in TLS
Evaluation and Countermeasures
● Countermeasures○ Use random XOR canaries
■ canary = master canary ^ stack pointer○ Establish a guard page
Evaluation and Countermeasures
https://github.com/potetisensei/MasterCanaryForging-PoC/
PoC
Thank you for listeningPlease ask me anything