master canary forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 -...

55
Master Canary Forging 新しいスタックカナリア回避手法の提案

Upload: code-blue

Post on 23-Jan-2018

799 views

Category:

Software


1 download

TRANSCRIPT

Page 1: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

Master Canary Forging新しいスタックカナリア回避手法の提案

Page 2: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

自己紹介

● 小池 悠生(こいけ ゆうき)○ 16歳、学生

● CTFにハマっていた

○ DEF CON 2014 Finalist○ CODEGATE Junior 2015 Winner○ 引退視野

Page 3: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

概要

● 動機

● Stack Canary● これまでの回避手法

● Master Canary Forging● 手法の評価と対策

Page 4: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

概要

● 動機

● Stack Canary● これまでの回避手法

● Master Canary Forging● 手法の評価と対策

Page 5: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

動機

● 僕はROPが好き

○ だからStack Based Buffer Overflowが好き

○ だからStack Canaryは嫌い

● Stack Canaryは強い

○ 回避出来る条件を考えるのは価値がある

○ 良い回避方法はないか?

Page 6: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

概要

● 動機

● Stack Canary● これまでの回避手法

● Master Canary Forging● 手法の評価と対策

Page 7: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

Stack Canary

● BOFによる攻撃を阻止したい

○ return addressが書き換えられたか判定したい

■ されていたらプロセスを殺す

○ 指標を作ればいい

■ BOFの前後で値が変わるようにする

Page 8: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

Stack Canary

return address

frame pointer

local variables

Page 9: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● 指標を追加する

Stack Canary

return address

frame pointer

canary 0xdeadbeef

local variables

Page 10: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● BOFが起こると...

Stack Canary

canaryoverwritten

Page 11: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● canaryの値が変わるので、攻撃を検知出来る

Stack Canary

modified0x41414141

Page 12: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● canaryの値が変わるので、攻撃を検知出来る

Stack Canary

modified0x41414141

Not 0xdeadbeefAttack Detected

Page 13: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

Stack Canary

● BOFによる攻撃を阻止したい

○ return addressが書き換えられたか判定したい

■ されていたらプロセスを殺す

○ 指標を作ればいい

■ BOFの前後で値が変わるようにする

Page 14: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

Stack Canary

● BOFによる攻撃を阻止したい

○ return addressが書き換えられたか判定したい

■ されていたらプロセスを殺す

○ 指標を作ればいい

■ BOFの前後で値が変わるようにする

● これ、保証できる??

Page 15: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● canaryの値が変わらないと検知できない

Stack Canary

modified0xdeadbeef

Page 16: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● canaryの値が変わらないと検知できない

Stack Canary

modified0xdeadbeef

return address

任意の値に出来る

Page 17: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● canaryの値が変わらないと検知できない

Stack Canary

⇒ACE(任意のコード実行)

Page 18: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

Stack Canary

● Stack Canaryの種類

○ Random■ 元となる値が分からないようにする

■ プロセスの起動時に値をランダムに決める

○ Terminator■ ’\0’ 等が含まれるようにする

■ 元の値にしづらい

Page 19: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

Stack Canary

● master canaryとstack上のcanaryの比較

Page 20: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

概要

● 動機

● Stack Canary● これまでの回避手法

● Master Canary Forging● 手法の評価と対策

Page 21: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● ex1.c

回避手法1: __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);}

Page 22: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● ex1.c

#include <stdio.h>void bof(int (*print)(const char *)) { char buf[16]; scanf("%s", buf); print(buf);}int main(void) { bof(puts);}

回避手法1: __stack_chk_failを避ける

return addressframe pointer

canary

local variables

arguments

Page 23: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● ex1.c

回避手法1: __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);}

Page 24: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● ex1.c

回避手法1: __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);} 関数ポインタかつ引数

Page 25: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● ex2.c

回避手法2: canaryをリークする

#include <stdio.h>

int main(void) { char buf[16]; scanf("%s", buf); printf(buf); fread(buf, sizeof(char), 32, stdin);}

Page 26: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● ex2.c

回避手法2: canaryをリークする

#include <stdio.h>

int main(void) { char buf[16]; scanf("%s", buf); printf(buf); fread(buf, sizeof(char), 32, stdin);}

書式指定子攻撃

Page 27: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

回避手法2: 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

Page 28: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● stack canaryのどこを突破口にしているか?

○ 回避手法1: __stack_chk_failの回避

■ 検知、強制終了を行うところ

○ 回避手法2: canaryをリークする

■ stackに入ったcanary

回避手法の本質

Page 29: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● stack canaryのどこを突破口にしているか?

○ 回避手法1: __stack_chk_failの回避

■ 検知、強制終了を行うところ

○ 回避手法2: canaryをリークする

■ stackに入ったcanary○ 回避手法3: master canaryを書き換える

■ stack canaryの元の値

回避手法の本質

Page 30: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

概要

● 動機

● Stack Canary● これまでの回避手法

● Master Canary Forging● 手法の評価と対策

Page 31: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● 以下を仮定

■ Linux Kernel 3.19■ glibc 2.21■ ASLRは有効

Master Canary Forging

Page 32: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● master canaryはどこにある?

○ 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

Page 33: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● master canaryはどこにある?

○ 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

実体への代入

Page 34: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● master canaryはどこにある?

○ 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

Page 35: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● master canaryはどこにある?

○ THREAD_SET_STACK_GUARD■ 7アーキテクチャにて定義

■ canaryがTLS(thread local storage)に入る

■ 定義されていないならmaster canaryは.bssへ

Master Canary Forging

Page 36: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● master canaryを書き換えるには

○ .bssにある時

■ 任意のアドレス書き換えができればいいだけ

Master Canary Forging

Page 37: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● master canaryを書き換えるには

○ .bssにある時

■ 任意のアドレス書き換えができればいいだけ

○ TLSにある時?

Master Canary Forging

Page 38: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● master canaryを書き換えるには

○ .bssにある時

■ 任意のアドレス書き換えができればいいだけ

○ TLSにある時?

■ そもそもTLS領域はどこに確保されるのか?

Master Canary Forging

Page 39: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● TLS領域はどこにある?

○ 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);

Page 40: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● TLS領域はどこにある?

○ _dl_allocate_tls_storageが確保を行う関数

■ 内部で__libc_memalignが呼ばれる

● __libc_memalignは内部でmmapを呼ぶ

○ 結局はmmapによって確保されたどこか

■ ASLRの影響を受けるため書き換えが難しい

Master Canary Forging

Page 41: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● mmapで確保された領域の特徴:

○ 常にどこかの領域と隣接している

Master Canary Forging

Page 42: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● Mapped Area Based Buffer Overflow

Master Canary Forging

target area

Page 43: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● Mapped Area Based Buffer Overflow○ まずmmapを使って領域を確保する

○ 確保した領域が目的の領域の上に来るようにする

Master Canary Forging

mapped area

target area

Page 44: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● Mapped Area Based Buffer Overflow○ まずmmapを使って領域を確保する

○ 確保した領域が目的の領域の上に来るようにする

○ 確保した領域でBOFを起こす

○ 十分なサイズなら、隣接した領域も上書き出る

Master Canary Forging

overwritten

Page 45: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● Mapped Area Based Buffer Overflow○ これでmaster canaryを書き換えられそう!

○ でも、攻撃者はmmapを呼べるの?

Master Canary Forging

Page 46: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● Mapped Area Based Buffer Overflow○ これでmaster canaryを書き換えられそう!

○ でも、攻撃者はmmapを呼べるの?

■ はい

Master Canary Forging

Page 47: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● Mapped Area Based Buffer Overflow○ これでmaster canaryを書き換えられそう!

○ でも、攻撃者はmmapを呼べるの?

■ はい

■ malloc

Master Canary Forging

Page 48: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● Mapped Area Based Buffer Overflow○ これでmaster canaryを書き換えられそう!

○ でも、攻撃者はmmapを呼べるの?

■ はい

■ 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

Page 49: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● Mapped Area Based Buffer Overflow○ 使える条件は以下の2つ

■ heapのallocateを自由に行える

■ Heap Based BOFが起こる

Master Canary Forging

Page 50: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

1. master canaryの書き換え

a. .bssにある時

i. 任意のアドレス書き換えで書き換える

b. TLSにある時

i. Mapped Area Based BOFを使う

2. Stack Based BOFを起こす

Master Canary Forging

Page 51: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

概要

● 動機

● Stack Canary● これまでの回避手法

● Master Canary Forging● 手法の評価と対策

Page 52: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● 評価

○ 使いづらい

■ 2種類の脆弱性が必要

■ 普通Heap Based Buffer Overflowだけで十分

○ Mapped Area Based BOF単体は使いやすい

■ TLSには関数ポインタテーブルがある場合あり

手法の評価と対策

Page 53: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

● 対策

○ Random XOR Canaryを使う

■ canary = master canary ^ stack pointer○ ガードページを設ける

手法の評価と対策

Page 55: Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015

御静聴ありがとうございました

なんでも質問してください。