Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
LLVM meets kernel
Search
Yuma Kurogome
December 08, 2013
Programming
4
2.4k
LLVM meets kernel
第九回 カーネル/VM探検隊 発表資料
http://peatix.com/event/22490
#kernelvm
Yuma Kurogome
December 08, 2013
Tweet
Share
More Decks by Yuma Kurogome
See All by Yuma Kurogome
The Art of De-obfuscation
ntddk
16
27k
死にゆくアンチウイルスへの祈り
ntddk
55
39k
Windows Subsystem for Linux Internals
ntddk
10
3k
なぜマルウェア解析は自動化できないのか
ntddk
6
4.2k
Linear Obfuscation to Drive angr Angry
ntddk
4
840
CAPTCHAとボットの共進化
ntddk
2
1.1k
マルウェアを機械学習する前に
ntddk
3
1.6k
Peeling Onions
ntddk
7
3.6k
仮想化技術を用いたマルウェア解析
ntddk
8
27k
Other Decks in Programming
See All in Programming
体得しよう!RSA暗号の原理と解読
laysakura
3
540
DomainException と Result 型で作る型安全なエラーハンドリング
karszawa
0
240
生成AIの使いどころ
kanayannet
0
100
The Evolution of Enterprise Java with Jakarta EE 11 and Beyond
ivargrimstad
0
1k
AtCoder Heuristic First-step Vol.1 講義スライド
terryu16
2
1k
コンテナでLambdaをデプロイするときに知っておきたかったこと
_takahash
0
150
eBPF Updates (March 2025)
kentatada
0
130
プログラミング教育のコスパの話
superkinoko
0
120
家族・子育て重視/沖縄在住を維持しながらエンジニアとしてのキャリアをどのように育てていくか?
ug
0
240
Go1.24 go vetとtestsアナライザ
kuro_kurorrr
2
480
PHPのガベージコレクションを深掘りしよう
rinchoku
0
240
GDG Super.init(version=6) - From Where to Wear : 모바일 개발자가 워치에서 발견한 인사이트
haeti2
0
560
Featured
See All Featured
Designing Experiences People Love
moore
141
23k
Unsuck your backbone
ammeep
670
57k
Rails Girls Zürich Keynote
gr2m
94
13k
Code Review Best Practice
trishagee
67
18k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
30k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.1k
Docker and Python
trallard
44
3.3k
BBQ
matthewcrist
88
9.5k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Testing 201, or: Great Expectations
jmmastey
42
7.4k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
227
22k
Transcript
LLVM meets kernel @ntddk
whoami • Yuma Kurogome(@ntddk) • 慶應義塾大学 SFC B1, 武田研 •
留年の危機 • Synclogue Inc. • Windows kernel, RCE, LLVM ← new!
whoami • CTF – EpsilonDelta(一応) – sutegoma2(潜入) – Kazusa •
HackInTheBox KL – ROPが解けなかった
今回話すこと • LLVM • Return-oriented programming(ROP) • LLVMによるROP緩和技術 • LLVMLinux
LLVM
詳しくは...
LLVM • プログラムの最適化を支援するコンパイラ基盤 • 任意の言語 → LLVM IR → 任意の言語
LLVMの構成 • Frontend • Middlend • Backend
Frontend • 字句解析 • 構文解析 • 意味解析 • コード生成 –
LLVM IR • Frontendを実装するだけで任意の言語のコンパ イラが作れる – MiddlendとBackendはLLVMデフォルトでも十分
Middlend • PassによるLLVM IRの解析と最適化 – 関数全てに対するPass – ループ文に対するPass – ジャンプのない一連の処理に対するPass
– etc... • 自分だけのPassでみんなと差をつけろ
Backend • アセンブリ生成 • 実行オブジェクト生成 • LLVM IRの実行(JIT) • コード生成(トランスレータ)
• 独自の言語のソースコードを生成したい場合は Backendを実装する必要がある
Clang • C, C++, Obj-C, Obj-C++のFrontend • C++14(N3797)の機能を完全に実装 • BSDライクなライセンス
– gccはGPLv3
ROP
脆弱性対策技術 • scanf("%s", buf); – EIP 0x41414141からが戦い • プログラムに脆弱性があっても悪用されない機 能の実現
脆弱性対策技術 • StackGuard – リターンアドレス付近に乱数を配置 • StackSheild – リターンアドレスを離れた位置に保存 •
ASLR – アドレスのランダマイズ – 攻撃の成功率を下げる • Exec Shield – データ実行防止
ROP • 脆弱性攻略のための一技術 – Exec Shieldを突破する • Return-oriented programming •
短いコードブロックを組み合わせてシェルコー ドとする – ROP gadgets – シェルコードとして使える命令とリターンのセット – 命令をずらして解釈することも – ASLRがかかっていないファイルを利用
ROP gadgets 684a0f4e: pop eax ret 684a2367: pop ecx ret
684a123a: mov[ecx], eax ret 0x684a123a 0xfeedface 0xdeadbeef 0x684a2367 0x684a0f4e
None
Return-oriented rootkit • Rootkit – カーネル構造体などを書き換える – 悪意のあるプログラムを隠蔽 • Return-oriented
rootkit – Return-Oriented Rootkits: Bypassing Kenrel Code Integrity Protection Mechanism – ROPを利用したrootkit – ROPでカーネルの整合性検証をバイパスする
Return-oriented rootkit • カーネルの整合性検証 – 未許可のLKMを実行しない • LKMにシグネチャを付加して検証 – みんな大好きVMM
• BitVisorとか – 書き込み可能なアドレスの実行権限を外す
Return-oriented rootkit • rootkitと名が付いているがLKMをロードする わけではない • 要するにカーネルモードでのROP • LKMにバッファオーバーフローなどの脆弱性が ある場合の攻撃手法
LLVMによるROP緩和技術
Return-less kernel • ROPでは任意の命令とリターンを組み合わせる • じゃあカーネルから リターンをなくせば いいじゃん • Defeating
Return-Oriented Rootkits With “Return-less” Kernels • せっかくだから俺はLLVMを使うぜ
LLVMのFreeBSD対応 • まともに動くFreeBSDカーネルをビルドできる ようになったのは2009年2月25日 • Return-less kernelが発表されたのは2010年4月 • FreeBSD 8.0対象
Return-less kernel • 3つの手法でカーネルからreturnを除去 – Return indirection – Register allocation
– Peephole optimization • LLVM backendを中心に実装 – マシン語の最適化 – 1命令を減らす最適化はバックエンドでのみ可能
Return indirection • リターンアドレスをテーブルから取得してくる – retは直接スタック上の戻り先アドレスを読み込む – 別の位置にあるリターンアドレスを読み込んでから そのアドレスにジャンプするようにすればガジェッ トを無効化できる
Return indirection • call, retを新しい形式に置き換える push $index jmp dst ...
pop %reg jmp *RegAddrBase(%reg)
Register allocation • Return indirectionだけでretを除去できるとは 限らない • x86は可変長であるためコンパイラがretを生成 してしまうことがある mov
%eax, %ebx -> 89 c3 • movなのに何故かret(0xc3)に... • LLVM IRの仮想レジスタマッピング時に調整
Register allocation • llvm::Spiller • LLVMのレジスタ割り当てアルゴリズム – Simple scan –
Local scan • これら2つは仮想レジスタから直接マッピング – Linear scan • より高度な割り当て
Register allocation • Linear scanを利用 • X86RegisterInfo.tdを拡張 – x86におけるレジスタ記述ファイル •
危険なレジスタ割り当てにアノテーション • 再割り当て • ご安全に!
Peephole optimization • コード中の0xc3を書き換える – 即値でもretと解釈してROPに使える cmp $0xc3,%ecx → mov
$0xc4, %reg dec %reg cmp %reg, %ecx
Peephole optimization • FreeBSD 8.0におけるコード 0xFFFFFFFF801A4F01: E9 C3 00 00
00 jmpq 0xFFFFFFFF801A4FC9 • この0xc3の意味は?
Peephole optimization • jmpq命令の直後からのオフセット • 相対アドレスの調整で0xc3を排除できる 0xFFFFFFFF801A4F01: E9 C4 00
00 00 jmpq 0xFFFFFFFF801A4FCA 0xFFFFFFFF801A4F06: 90 nop
LLVMLinux
+
LLVMLinux
現状 • LLVMでLinuxカーネルをビルドしたい! – Linuxカーネルはgccの拡張機能と癒着 – LLVM/Clangはgccの規格違反の挙動を絶対に実装 しない • LLVMへの機能追加とカーネルへのパッチで実
現 – gcc拡張の闇を取り除く
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;
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");
Return-less Linux kernel • そろそろLLVMでLinuxをビルドできそう • LinuxでもReturn-less kernelを実現できたらい いよね •
GSoCとか... • OSvってどうなの