静的解析に基づく侵入 検知システムの最適化 大山 恵弘 (科学技術振興事業団) 王維 (筑波大学) 加藤 和彦 (筑波大学・科学技術振興事業団) 背景 C言語 = 大大大迷惑で危険な言語 世界に大きな脅威と経済的損失 ex1. バッファオーバフローで乗っ取り ex2. スタックやヒープが壊れて誤動作 しかし、今すぐC言語を駆逐するのは無理 支援システムでC言語の欠陥を補いましょう バッファオーバフロー サイズを越えてデータをバッファに注入 スタック、ヒープの破壊 制御フローのねじ曲げ 突然libcのexecに突入 注入したバイナリコード先頭にジャンプ Cプログラムを安全に 実行するための方策 型安全性の導入 [Oiwa et al. 02] Stack-smashing攻撃防止システムの導入 [Cowan et al. 96], [Etoh] 侵入検知システムの導入 本研究 他多数… 侵入検知システム 基本的な動き プログラムの実行を監視 侵入を検知 → 対策を取る 検知方式 シグネチャ検知: 「異常」の規則を保持 ex. 原始的なAntivirus 異常検知: 「正常」の規則を保持 本研究 異常検知システム 方法 プログラムのモデル(正しい動作を表す規則)を 作成 モデルに従わない動作 = 異常と判定 長所 未知の攻撃を検出可能 本研究の目的 実用的な異常検知システムの構築 小さいオーバヘッド 高い検知精度 使用が容易 以降の流れ 異常検知システムの設計軸 既存の方法 既存の方法の問題 本研究の方法 実験 議論・関連研究 異常検知システム作ろう! 異常検知システム作ろう! といっても色々考えることがある 何を監視するか? モデル(正しい動作を表す規則)を どうやって作るか? 何を監視するか? キータイプ パケット システムコール 制御スタック ヒープ 本研究 モデルをどうやって作るか? 人間が頭をひねって書く 過去の正常な実行を一般化・学習 [Ko et al. 94], [Sekar et al. 99] 問題: 計算機の専門知識が必要 [Forrest et al. 96], [Sekar et al. 01] 問題: 学習のためにプログラムを実行するのが面倒 プログラムの静的解析による自動生成 [Wagner et al. 01], [Giffin et al. 02] 本研究 本研究のアプローチ main() { f(); if (…) { g(); } … } 制御フローを監視しながら実行 モデルに無い制御フローを辿った → 異常 モデル = 制御フローの規則 システムコール呼び出し時に制御の状態を検査 Wagnerらの方法 [Wagner et al. 01] の改良 Wagnerらのシステム main() { f(); if (…) { g(); } … } コンパイラ プロセス 実行可能コード システムコール モデル 侵入検知システム OS モデル main() { stat(); if (…) { open(); } else { connect(); } close(); } main → stat; X; close X → open | connect 文脈自由文法 終端記号 = システムコール 実行の監視 プロセス open, stat, … 侵入検知システム = CFGパーザ main → stat; X; close X → open | connect OS パーズ可能 → 正常 パーズ不可能 → 異常 問題点 プログラムの内部状態を正確に把握 しない 制御の場所を非決定的に把握 open, stat, mmap, read, close, … sendmail 問題点1: オーバヘッドの増加 プロセス open, stat, … CFGパーザ main → f | g | h | i | … f → open | … | … g → open | … | … h → open | … | … i→f|g|… OS open呼ぶ候補の数100! →全部考慮してパーズ 次にstat呼ぶ候補の数1000! →全部考慮してパーズ 実用的とは言い難い性能 42分 1時間以上 1トランザクションあたりの 監視オーバヘッド (秒) 100 80 60 40 20 0 finger qpopper procmail sendmail 問題点2: 攻撃の見逃しの増加 プロセス open, stat, (buffer overflow), exec, … CFGパーザ main → f | g | h | i | … f → open | … | … g → open | … | … h → open | … | … i→f|g|… OS open, stat, execを 生成可能な規則あり → プロセス内部がどうなって いようが正常と判断 我々の考え 静的解析でモデルを作る着眼は良い しかし、システムコール列のみを検査対象に するのはいかがなものか プログラムの内部状態をもっと取得・活用して もいいのでは? イメージ open, stat, mmap, read, close, … sendmail 提案方式 main() { f(); if (…) { g(); } … } コンパイラ プロセス 実行可能コード システムコール モデル 侵入検知システム OS モデル 制御の移動を表すオートマトン main() { open(); if (…) { f(); } else { g(); } close(); } main 入口 open f g close 出口 検査方法 システムコールでプログラムを停止 スタックを検査 前回停止時のスタックから現在のスタックへの 制御フローがモデル中にあるかどうか調べる open printf f main 遷移可能? read fgets h g f main 遷移可能? connect p main 遷移可能性の検査 現在はナイーブなやり方 スタックの各フレームごとに遷移の存在を検査 popするパスの探索 pushするパスの探索 open printf f main read fgets h g f main 実装 モデル生成機能つきコンパイラ部 GCCを改造して作成 工数: 0.018人年 実行監視部 別プロセスによる監視 カーネルモジュールによってプロセスを操作 システムコールをフック レジスタ・スタック情報の取得 特徴 Wagnerらの方法 偽警報が出ない (正常を異常と誤判定しない) モデルを作る手間がかからない 加えて、本研究のシステム Wagnerらの方法より オーバヘッドが小さい(?) 見逃す攻撃が少ない 実験 環境 Pentium 4 (2.8GHz) 上のVMware Red Hat Linux 7.1 アプリケーション wc: 22MBのファイルのカウント cp: 22MBのファイルのコピー tar: ソースツリーのtarファイルを作成 結果 wc A: 異常検知なし cp 335 ms tar 805 ms 62 sec B: 異常検知あり 1267 ms 4921 ms 581 sec B/A 3.8 6.1 9.3 関連研究: 異常検知システム システムコールの情報 システムコール以外の だけから判断 情報も用いて判断 学習による モデル生成 [Forrest et al. 96] [Lee et al. 98] [Liao et al. 02] 静的解析による [Wagner et al. 01] モデル生成 [Sekar et al. 01] [Oyama et al. 01] 本研究 関連研究: バッファオーバフロー対策 Non-executable stack, StackGuard [Cowan et al. 96], propolice [Etoh] 関数ポインタを書き換える攻撃を防げない Program shepherding [Kiriansky et al. 02] 全ブランチ命令で安全性検査 ex. ブランチが関数先頭に飛んでいるか ex. retがcallの次の命令に飛んでいるか 「ソースコード通りの制御フローを辿る」というポリシーは 扱っていない まとめ ソースコード情報と実行時スタックの情報を 両方活用する異常検知システムを提案 今後の課題 大規模なアプリケーションを用いて性能測定 Wagnerらの方法との性能比較 システムコールの引数情報の活用 質問・議論スライド 議論: サンドボックスとの関係 サンドボックスと侵入検知システムは似ている 実行を監視、邪悪な操作を拒否 サンドボックスがあれば十分? → No! サンドボックスの適切なポリシーを定めることは 簡単ではない 厳しすぎるとプログラムが動かない 緩すぎると危険 議論: mimicry attack [Wagner et al. 02] 侵入検知システムによる検知を回避する攻撃 ex. ダミーシステムコールを発行して正常を偽装 システムコールだけを検査するシステム → mimicry attackがやりやすい 本研究のシステム → mimicry attackがやりにくい スタック内の制御情報も偽装する必要がある 議論: なぜシステムコールの タイミングで検査するのか? オーバヘッドを(比較的)小さく抑えられる 実装が楽 システムコール呼び出しに検査が挟まると ハッカーは攻撃を成功させにくい 異常検知の投機的実行 プログラムの未来の状態を予測 次に出るシステムコール 次のスタック状態 次にどの状態が来たら正常/異常かを事前に 計算しておく アプリケーションの停止時間が短縮される コンパイル処理に加わるオーバヘッド wget-1.8.2のmakeにかかる時間 元のGCC: 12.3秒 改造GCC: 12.4秒
© Copyright 2024 ExpyDoc