[CB16]...
-
Upload
code-blue -
Category
Technology
-
view
81 -
download
4
Transcript of [CB16]...
COFIブレイク:実用的な制御フローインテグリティとProcessor Traceによるエクスプロイト阻止
講演者
シュローミ・オーバーマン( Shlomi Oberman)
フリーのセキュリティ研究者
ロン・シナ( Ron Shina)
フリーのセキュリティ研究者
トレース いつ、何が実行さ−れたのか?
コード最適化とプロファイリング◦サンプリング◦インストルメンテーション
Intel Processor Trace(PT)
Intel PTIntelプロセッサの機能は、低オーバーヘッド – ドキュメントによれば、おおよそ 5% – での命令トレースが可能◦速度は従来オプションの数十倍
Intelの Broadwell、 Skylakeプロセッサで使用可能
類似機能のリアルタイム命令トレースが、若干のIntel Atomプロセッサに存在
Intel PT
パケットプロセッサは、トレースをパケットとしてメモリに書き込む
パケットタイプ◦条件分岐用の分岐実行 /不分岐( Taken / Not Taken)パケット◦間接分岐用の IPパケット◦タイムスタンプ・パケット◦ …
命令トレースを再作成するには、バイナリが必要
fooを呼び出し
分岐実行 / 不分岐
復号後のトレースパケット
ユーザーと(または)カーネルのトレーシング
プロセスによるフィルター
アドレス範囲を基にトレースを開始または終了(最近のプロセッサでのみ)
設定オプション
Atomプロセッサは RTITをサポート – ゲストのトレーシングは可能だが、ハイパーバイザは対象外
Broadwell – 完全にサポート対象外
Skylake – フルサポートしている
VMゲストとハイパーバイザのトレーシング
+ トレース後のプログラムのバイナリ
命令トレース
Intel PT 出力
Linuxカーネル4.1は統合PTサポート付きLinuxカーネル4.3はperfユーザーツールを使ったトレーシングをサポート
オープンソースのPT復号ライブラリ – libipt
Gdb 7.10はPTを使ったトレーシングをサポート
simple-pt – LinuxでPTの実装をするオープンソース(前スライドのトレース画像を作るために使用)
* PTサポート対象のプロセッサは別途付属 (◠‿ ー )
今すぐ Processor Traceを使いたい? *
脆弱性攻撃と NXビット
Hi!
シェルコード
pdfが開いている時、実行不可能なシェルコードがメモリ内に存在する – NXビット
攻撃者はこのコードをどのように実行し、攻撃者自身のシェルコードを実行可能にしているか?◦既に実行可能なコードを使う (このプログラムのコード )
脆弱性攻撃の技術には様々なものがある。最も注目すべきは、ROP – リターン指向プログラミング
プログラムに既存する実行可能メモリを使用すると、プロセスの周囲をかなり奇妙に動き回ることになる
例 :
◦関数の呼び出し元に戻らない
◦関数の始まりではなく、途中でアドレスを呼ぶ◦ …
“Jump Around, Jump around…” / ハウス・オブ・ペイン
Hi!
シェルコード
プロセス内でどのようにコードが流れるかルールを定める◦関数は呼び出し元に戻る◦関数の始まりで呼び出しが行われる◦ …
ルールをどのように実行させるか?◦プログラムのバイナリに、ルールのチェッキングを追加する◦実行中のプログラムをトレースし、ログを調べる(この作業)◦他の CPU機能を使って、 "オドロキの "分岐を検知する
“Control Flow Integrity Principles, Implementations, and Applications”, Abadi, Budiu, Erlingsson, Ligatti, 2005
制御フローの整合性( CFI)
“Security Breaches as PMU Deviation”, Yuan, Xing, Chen, Zang 2011
“kBouncer: Efficient and Transparent ROP Mitigation” – Pappas著。Microsoft BlueHatコンテスト 2012の優勝者で、従来の CPU分岐トレーシング機能を使う
“CFIMon: Detecting Violation of Control Flow Integrity using Performance Counters” – Xia, Liu, Chen, Zang 2012
“Taming ROP on Sandy Bridge”, Wicherski of Crowdstrike, 2013
“Transparent ROP Detection using CPU Performance Counters”, Li, Crouse, THREADS 2014
他にも沢山ある…
先行研究
CFIを基にファイルをスキャンする対脆弱性システム(例えば Adobe Readerの pdfと考える)
ROP内などで、“不正な”リターンが行われたどうかを検知する◦呼び出し先をチェックする(呼び出し処理が関数の途中に対して行われない、など…)といった、他の CFI回避機能を追加するのが簡単
(もうすぐに)オープンソース2015年に開発
わたし達の実装
Processor Traceを通して CFIを検証フローは OKか?矢印に従って追跡し、 PTによって生成されたパケットを使って呼び出すだけ
実行を追跡・検証するには、どのような情報が必要か?
制御フローグラフ( CFG)◦関数の位置◦基本ブロックの位置◦ …
プロセスが読み込んだ全ライブラリがこれを必要とする – Adobe Reader dll, Windows dll◦ 必要としない場合 – 誤検出
必要なものは、Windowsバイナリ用のデバッグシンボルと pdbファイルだけ
CFGを取得するために IDAを使用した
IDAは、あまり良く動かなかった◦Adobe Reader/Windowsバイナリの機能や基本ブロックの一部が検知されなかった
静的分析
最新版の Adobe Readerをサポートしていれば、 IDAは初期のCFG(静的分析)を取得するために使われる
以降は、多くの pdfファイルが PTでトレースされている◦トレースを追跡中に新しい基本ブロックまたは関数が発見された時 – CFGが更新される
繰り返し◦新しいCFG上で IDAを実行する◦ IDAの出力先で pdfファイルを実行する◦最後の繰り返しでCFGが更新された場合
繰り返す
動的分析
CFGの最先端は :◦ 現時点の IPに関連する呼び出し(パケットなし)
◦ 条件分岐
トレース検証中にCFGを通過する時、上記のケースで行われる次のノードのフェッチ処理は(かなり)高速でなければならない
CFGは固定であり、前処理でビルドされることもあり、問題にはならない
最適化
理想としては、検証中に逆アセンブリや CFG改修は行わない方がよい(遅い)
しかし、分析されたコードの一部は動的に作られる – それが変動するものではい限り、これは前処理にて行われるはず
変動した都度 "Adobe Reader"が起動してファイルを開いてしまう場合、前処理では不十分◦コードが逆アセンブリされて、 CFGが更新されてしまう
最適化
実行トレースの追跡は、スレッドベースごとに行われる
各トレースにてどのスレッドが実行されているか、どのように把握する?◦PTパケットがタイミング情報をくれるが、現時点でのプロセスを出力するのみ
スレッド情報
Event Tracing for Windows (ETW)
◦TSCとして ETWから提供される CSwitchイベントから、 スレッドコンテキストの切り替え時間を取得するのは可能
◦次に、これらのタイムスタンプは、様々なトレースの中でどのスレッドが実行されているかを決めるため、PTからの TSCパケットと一致している可能性がある
スレッド情報
トレース済みプロセス内のスレッドが切り替わる都度コールバックを取得する、というのはどうだろうか?
◦わたし達の知る限りでは、直接的な方法は無い
◦わたし達は、Windowsコンテキストの切り替え機能をフックした – これをやってはいけない
◦最終段階で、非同期プロシージャの呼び出しを通して、目的に到達する方法が見つかった( Blackhat 2016)
スレッド情報
トレース内の実行可能なメモリの範囲を徹底的に知る必要がある – 何のモジュールがロードされたか
PTトレースがいつ ntdll!LdrLoadDll や ntdll!LdrUnloadDll に到達したか、を知るだけでは不十分◦モジュール名は、現時点のメモリマップを更新する際に必要
ETWは、モジュールのロード/アンロード名称や時間( tsc)を取得するために使われ、その時間はトレース内の関数のロード/アンロードの時間と一致する
モジュールのロード/アンロード
例:◦例外捕捉コード◦ユーザーモジュールコールバック◦ …
トレースを調べている際に怪しいミスマッチが発生した場合、バイナリ署名を通して上記の特殊ケースがチェックされる
これは主にアプリケーションごとではなく、OSごとに行われなければならない
まだ終わりではない – 関数は常に呼び出し元に戻るというわけではない
(ほぼ全体的に)わたし達の実装は取り扱わない
PTトレーシングの場合、コードが実行中である必要がある
ひとつ明確な問題がページにあり、それはページへの書き込み/ページからの実行が同時に行われるというもの
(多分)コードの新バージョンを取得するために、人がページが書き込みや実行可能になる都度書き込み許可を取り払ったり、書き込まれた時にアクセス違反に対処することは可能ではないか
動的に生成されたコード
取り扱われた動的に生成されたコードのケース:
自らをフックするアプリケーション… 同じ位置、同じタイミングで、全く同じフック
トレース検証者にとって、コードは原則的に静的
動的に生成されたコード
無害な、悪意のないファイル◦10000個の pdf、 3000個の ppt/x、 3000個の doc/xで実行し、誤検知なし
ROPチェーンを含む、悪意のあるファイル◦その類のファイルを 5個で実行したところ、脆弱性を検知、 CFI侵害を表示
スキャン結果
それでもなお必要と思われるもの
◦モジュールのロード/アンロード情報◦スレッドコンテキストの切り替え時間
しかし、なくても多少はできる場合があるもの
◦CFG – 一部の CFGはトレースからビルド可能(前もってビルドしておく必要はない)
CFIと脆弱性対策を忘れよう…ただ、Processor Traceを使って素早くプロセスをトレースしたいだけだったらどうなる?
Intelが2016年6月に公表したControl-flow Enforcement Technology。発売日は?
プロセッサは直接サポートするようになる :◦シャドー(コール)スタックのトラッキング – 整合性の取れない戻り → コントロール保護例外
◦間接的分岐のトラッキング – ENDBRANCHとは異なる命令を含むターゲットへの間接的分岐 → コントロール保護違反
巷のマザーボードに近日中にやってくるもの
ARMには、 Processor Traceに似た機能のCoreSightがある
Linux上でのトレーシングは、 perfに統合されている
オープンソースの復号ライブラリがある – OpenCSD
http://www.linaro.org/blog/core-dump/coresight-perf-and-the-opencsd-library/
ARM上で素早くトレースするのはどうだろうか?
“Control Jujutsu” – Evans, Long, Otogonbaatar, Shrobe, Rinard, Okhravi, Stelios, CCS 2015
任意コードの実行に至るため、(脆弱性を通して)制御可能なターゲットと引数でサイトの間接的呼び出しを使う(例:実行ファイルやシステムを呼び出す)
ターゲットの関数が CFGにおいて適切であるが故に、CFIを回避する
CFIを回避する
“Write Once, Pwn Anywhere”, Yu, Black Hat USA 2014◦アプリケーションは時々、セキュリティ・クリティカル情報をひとつの変数に持っていることがある
◦インターネット・エクスプローラの JavaScriptエンジンからの擬似コード :
if (safemode & 0xB == 0) {turn_on_god_mode();}
"データ攻撃 "で CFIを回避する
“Control Flow Bending”, Carlini, Barresi, Payer, Wagner, Gross, USENIX 2015
◦printf指向プログラミング – 引数を制御すれば、printfは任意の計算をすることが可能
"データ攻撃 "で CFIを回避する
“Data oriented programming” – Hu, Shinde, Sendroiu, Zheng, Prateek , Zhenkai, S&P 2016
目標: CFGを着実に実行している最中に、任意の計算を実行する
心持ち ROPに似ている – オリジナルプログラムの一部を、攻撃者が制御している "VM"命令として使う
"データ・ガジェット "は、データの計算を行う際に使われる
"データ攻撃 "で CFIを回避する
脆弱なプログラム内に既存するループなどの構造を使って、ガジェットは次々と実行される
どのデータ・ガジェットが何のデータで実行されたかを見つけ出すために、脆弱性が悪用される
“ データ指向プログラミング”(続き)
質問ありますか?