ROPの対策技術を解説する、EMET3.5βのROP対策機能において参照された論文。
対策技術は以下の2種類に分類できる。
対策技術は以下の2種類に分類できる。
- コンパイラレベル
- バイナリレベル
コンパイラレベル
CALLの検証
- 概要
- RETの戻り先がCALLであるかを検証する。ROPはCALLを使用せずにgadgetを実行しRETするので、ROP実行時には戻り先はCALLにならない事が多いのを利用する。
- 欠点
- 逆アセンブルが必要になりパフォーマンスが低下する。また逆アセンブルが難しいために検証機能の信頼性に問題がある。
定数埋め込み
- 概要
- CALL命令の直後に固定値を埋め込む。さらに関数エピローグに、戻り先(*esp)の内容が前述の固定値であるかを検証するコードを埋め込む。上記の「CALLの検証」と同様に機能することに加え、逆アセンブルに関連する問題が解決される。
- 欠点
- 全てのバイナリが同じ固定値を持たなければならない。このためには、すべてのバイナリが同一のルールに従って再コンパイルされる必要があり、現実的に不可能。
命令の改ざん
- 概要
- RETが存在しなくなるように命令(バイト列)を変更する。なお、純粋なRET命令以外にも、命令の途中が「RET命令として解釈できる」バイト列が存在することに配慮しつつ変更を行う。
バイナリレベル
スタックのカプセル化
- 概要&欠点
- (理解できず)
スタックポインターの監視
- 概要
- ROPの実行中は、しばしばスタックポインターがTEBに定義されたスタックの範囲を超えることを利用し、ROPにしばしば利用されるAPIをあらかじめフックしておき、それらのAPIが呼び出されたときにスタックポインターの範囲がTEBに収まっているかを検証する。
- 欠点
- それらのAPIが呼び出される前にスタックポインターがTEBの範囲内に戻される可能性がある。
コードのカプセル化
- 概要
- 各モジュールを別のコードセグメントに分割する。これによりモジュール間の遷移時に例外が発生するようになるので、この例外をハンドルして、ROPが行われてるか否かを検証する。
- 欠点
- 性能の低下、switch文に対する追加の処置が必要、など。一部は理解できず。
おとりコード
- 概要
- 各モジュールのコピーをメモリー内に作成し、オリジナルは実行不可属性を付加する。オリジナルを実行しようとすると例外が発生するので、この例外をハンドルして、ROPが行われているか否かを検証する。問題がない場合は、コピー(実行可能)を実行する。
- 欠点
- 性能の低下。
- (コメント)メモリー領域の消耗が半端ないだろ、これ。
No comments:
Post a Comment