Stack Smashing Protection(SSP) is one of the oldest and fundamental protections against exploits, and is now supported by most compilers and modern operating systems.
One technique for SSP is using stack canaries, which verify if a stack buffer has been overflown by checking the integrity of a value stored immediately after the buffer.
Previously, the main methods to bypass stack canaries were to exploit different vulnerabilities to either avoid the canary validation completely, or to provide the correct canary value by leaking the value.
In this talk I will propose a new technique to bypass stack canaries in SSP which takes a different approach from the previous two methods.
2. 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
5. 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?
7. 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
9. ● Append an “indicator” to a stack frame
Stack Canary
return address
frame pointer
canary
0xdeadbeef
local variables
10. ● When BOF occurs...
Stack Canary
canary
overwritten
11. ● The attack will be detected since the value changed
Stack Canary
modified
0x41414141
12. ● The attack will be detected since the value changed
Stack Canary
modified
0x41414141
Not 0xdeadbeef
Attack Detected
13. 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
14. 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??
15. ● The attack won’t be detected unless the value changed
Stack Canary
modified
0xdeadbeef
16. ● The attack won’t be detected unless the value changed
Stack Canary
modified
0xdeadbeef
return address
becomes any value
17. ● The attack won’t be detected unless the value changed
Stack Canary
⇒ACE(Arbitrary Code
Execution)
18. 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.
26. ● 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
27. method #2: leak a canary
$ gdb ./ex2 -q
(gdb) b 4
Breakpoint 1 at 0x8048532: file ex2.c, line 4.
(gdb) r
Breakpoint 1, main () at ex2.c:4
4 scanf("%s", buf);
(gdb) x/12xw $esp
0xffffce60: 0xffffd129 0x0000002f 0x0804a000 0x080485e2
0xffffce70: 0x00000001 0xffffcf34 0xffffcf3c 0xf7e3539d
0xffffce80: 0xf7faa3c4 0xf7ffd000 0x0804859b 0x48d09200
(gdb) c
%11$x
48d09200
28. ● 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
29. ● 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
32. ● Where is the master canary located?
○ Let’s read glibc
Master Canary Forging
static void
security_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
33. ● Where is the master canary located?
○ Let’s read glibc
Master Canary Forging
static void
security_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
34. ● Where is the master canary located?
○ Let’s read glibc
Master Canary Forging
static void
security_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
35. ● 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
36. ● To overwrite the master canary
○ When it lies in .bss
■ It is just “Arbitrary Memory Write”
Master Canary Forging
37. ● 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
38. ● 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
40. ● 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
41. ● One of the characterics of areas allocated by mmap:
○ The areas are always adjacent to some region
Master Canary Forging
42. ● Mapped Area Based Buffer Overflow
Master Canary Forging
target area
43. ● 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
44. ● 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
45. ● Mapped Area Based Buffer Overflow
○ This seems to be able to overwrite the master canary
○ Wait, can attackers invoke mmap?
Master Canary Forging
46. ● Mapped Area Based Buffer Overflow
○ This seems to be able to overwrite the master canary
○ Wait, can attackers invoke mmap?
■ YES
Master Canary Forging
47. ● 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
48. ● 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
49. ● Mapped Area Based Buffer Overflow
○ following 2 conditions required:
■ Attackers can control allocation
■ Heap Based BOF occurs
Master Canary Forging
50. 1. Overwrite the master canary
a. 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 BOF
2. Cause a stack based BOF
Master Canary Forging
52. ● 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
53. ● Countermeasures
○ Use random XOR canaries
■ canary = master canary ^ stack pointer
○ Establish a guard page
Evaluation and Countermeasures