Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
LLVM meets kernel @ntddk
Slide 2
Slide 2 text
whoami ● Yuma Kurogome(@ntddk) ● 慶應義塾大学 SFC B1, 武田研 ● 留年の危機 ● Synclogue Inc. ● Windows kernel, RCE, LLVM ← new!
Slide 3
Slide 3 text
whoami ● CTF – EpsilonDelta(一応) – sutegoma2(潜入) – Kazusa ● HackInTheBox KL – ROPが解けなかった
Slide 4
Slide 4 text
今回話すこと ● LLVM ● Return-oriented programming(ROP) ● LLVMによるROP緩和技術 ● LLVMLinux
Slide 5
Slide 5 text
LLVM
Slide 6
Slide 6 text
詳しくは...
Slide 7
Slide 7 text
LLVM ● プログラムの最適化を支援するコンパイラ基盤 ● 任意の言語 → LLVM IR → 任意の言語
Slide 8
Slide 8 text
LLVMの構成 ● Frontend ● Middlend ● Backend
Slide 9
Slide 9 text
Frontend ● 字句解析 ● 構文解析 ● 意味解析 ● コード生成 – LLVM IR ● Frontendを実装するだけで任意の言語のコンパ イラが作れる – MiddlendとBackendはLLVMデフォルトでも十分
Slide 10
Slide 10 text
Middlend ● PassによるLLVM IRの解析と最適化 – 関数全てに対するPass – ループ文に対するPass – ジャンプのない一連の処理に対するPass – etc... ● 自分だけのPassでみんなと差をつけろ
Slide 11
Slide 11 text
Backend ● アセンブリ生成 ● 実行オブジェクト生成 ● LLVM IRの実行(JIT) ● コード生成(トランスレータ) ● 独自の言語のソースコードを生成したい場合は Backendを実装する必要がある
Slide 12
Slide 12 text
Clang ● C, C++, Obj-C, Obj-C++のFrontend ● C++14(N3797)の機能を完全に実装 ● BSDライクなライセンス – gccはGPLv3
Slide 13
Slide 13 text
ROP
Slide 14
Slide 14 text
脆弱性対策技術 ● scanf("%s", buf); – EIP 0x41414141からが戦い ● プログラムに脆弱性があっても悪用されない機 能の実現
Slide 15
Slide 15 text
脆弱性対策技術 ● StackGuard – リターンアドレス付近に乱数を配置 ● StackSheild – リターンアドレスを離れた位置に保存 ● ASLR – アドレスのランダマイズ – 攻撃の成功率を下げる ● Exec Shield – データ実行防止
Slide 16
Slide 16 text
ROP ● 脆弱性攻略のための一技術 – Exec Shieldを突破する ● Return-oriented programming ● 短いコードブロックを組み合わせてシェルコー ドとする – ROP gadgets – シェルコードとして使える命令とリターンのセット – 命令をずらして解釈することも – ASLRがかかっていないファイルを利用
Slide 17
Slide 17 text
ROP gadgets 684a0f4e: pop eax ret 684a2367: pop ecx ret 684a123a: mov[ecx], eax ret 0x684a123a 0xfeedface 0xdeadbeef 0x684a2367 0x684a0f4e
Slide 18
Slide 18 text
No content
Slide 19
Slide 19 text
Return-oriented rootkit ● Rootkit – カーネル構造体などを書き換える – 悪意のあるプログラムを隠蔽 ● Return-oriented rootkit – Return-Oriented Rootkits: Bypassing Kenrel Code Integrity Protection Mechanism – ROPを利用したrootkit – ROPでカーネルの整合性検証をバイパスする
Slide 20
Slide 20 text
Return-oriented rootkit ● カーネルの整合性検証 – 未許可のLKMを実行しない ● LKMにシグネチャを付加して検証 – みんな大好きVMM ● BitVisorとか – 書き込み可能なアドレスの実行権限を外す
Slide 21
Slide 21 text
Return-oriented rootkit ● rootkitと名が付いているがLKMをロードする わけではない ● 要するにカーネルモードでのROP ● LKMにバッファオーバーフローなどの脆弱性が ある場合の攻撃手法
Slide 22
Slide 22 text
LLVMによるROP緩和技術
Slide 23
Slide 23 text
Return-less kernel ● ROPでは任意の命令とリターンを組み合わせる ● じゃあカーネルから リターンをなくせば いいじゃん ● Defeating Return-Oriented Rootkits With “Return-less” Kernels ● せっかくだから俺はLLVMを使うぜ
Slide 24
Slide 24 text
LLVMのFreeBSD対応 ● まともに動くFreeBSDカーネルをビルドできる ようになったのは2009年2月25日 ● Return-less kernelが発表されたのは2010年4月 ● FreeBSD 8.0対象
Slide 25
Slide 25 text
Return-less kernel ● 3つの手法でカーネルからreturnを除去 – Return indirection – Register allocation – Peephole optimization ● LLVM backendを中心に実装 – マシン語の最適化 – 1命令を減らす最適化はバックエンドでのみ可能
Slide 26
Slide 26 text
Return indirection ● リターンアドレスをテーブルから取得してくる – retは直接スタック上の戻り先アドレスを読み込む – 別の位置にあるリターンアドレスを読み込んでから そのアドレスにジャンプするようにすればガジェッ トを無効化できる
Slide 27
Slide 27 text
Return indirection ● call, retを新しい形式に置き換える push $index jmp dst ... pop %reg jmp *RegAddrBase(%reg)
Slide 28
Slide 28 text
Register allocation ● Return indirectionだけでretを除去できるとは 限らない ● x86は可変長であるためコンパイラがretを生成 してしまうことがある mov %eax, %ebx -> 89 c3 ● movなのに何故かret(0xc3)に... ● LLVM IRの仮想レジスタマッピング時に調整
Slide 29
Slide 29 text
Register allocation ● llvm::Spiller ● LLVMのレジスタ割り当てアルゴリズム – Simple scan – Local scan ● これら2つは仮想レジスタから直接マッピング – Linear scan ● より高度な割り当て
Slide 30
Slide 30 text
Register allocation ● Linear scanを利用 ● X86RegisterInfo.tdを拡張 – x86におけるレジスタ記述ファイル ● 危険なレジスタ割り当てにアノテーション ● 再割り当て ● ご安全に!
Slide 31
Slide 31 text
Peephole optimization ● コード中の0xc3を書き換える – 即値でもretと解釈してROPに使える cmp $0xc3,%ecx → mov $0xc4, %reg dec %reg cmp %reg, %ecx
Slide 32
Slide 32 text
Peephole optimization ● FreeBSD 8.0におけるコード 0xFFFFFFFF801A4F01: E9 C3 00 00 00 jmpq 0xFFFFFFFF801A4FC9 ● この0xc3の意味は?
Slide 33
Slide 33 text
Peephole optimization ● jmpq命令の直後からのオフセット ● 相対アドレスの調整で0xc3を排除できる 0xFFFFFFFF801A4F01: E9 C4 00 00 00 jmpq 0xFFFFFFFF801A4FCA 0xFFFFFFFF801A4F06: 90 nop
Slide 34
Slide 34 text
LLVMLinux
Slide 35
Slide 35 text
+
Slide 36
Slide 36 text
LLVMLinux
Slide 37
Slide 37 text
現状 ● LLVMでLinuxカーネルをビルドしたい! – Linuxカーネルはgccの拡張機能と癒着 – LLVM/Clangはgccの規格違反の挙動を絶対に実装 しない ● LLVMへの機能追加とカーネルへのパッチで実 現 – gcc拡張の闇を取り除く
Slide 38
Slide 38 text
gcc拡張の闇 ● Variable length arrays in structs (VLAIS) – Variable length arrayの拡張 – 構造体内で配列の長さを実行時指定 – iptablesやHMACなどで利用されている struct foo_t { char a[n];/* Explicitly not allowed by C99/C11 */ } foo;
Slide 39
Slide 39 text
gcc拡張の闇 ● __builtin_constant_pによる定数検出の回避 – LLVM Bug 4898 ● Inline syntax handling – GNU89 ● __initと__exit ● レジスタ変数 – x86 register unsigned long current_stack_pointer asm("esp") __used; – ARM register unsigned long current_sp asm ("sp");
Slide 40
Slide 40 text
Return-less Linux kernel ● そろそろLLVMでLinuxをビルドできそう ● LinuxでもReturn-less kernelを実現できたらい いよね ● GSoCとか... ● OSvってどうなの