JP4990998B2 - プログラム実行フローの修正を防止する方法及び装置 - Google Patents

プログラム実行フローの修正を防止する方法及び装置 Download PDF

Info

Publication number
JP4990998B2
JP4990998B2 JP2010121289A JP2010121289A JP4990998B2 JP 4990998 B2 JP4990998 B2 JP 4990998B2 JP 2010121289 A JP2010121289 A JP 2010121289A JP 2010121289 A JP2010121289 A JP 2010121289A JP 4990998 B2 JP4990998 B2 JP 4990998B2
Authority
JP
Japan
Prior art keywords
mask
memory
address
program
jump
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Expired - Fee Related
Application number
JP2010121289A
Other languages
English (en)
Other versions
JP2011008778A (ja
Inventor
ピーター・フィリッパーツ
イヴ・ユーナン
フランク・ピーセンス
スヴェン・ラッハムント
トーマス・ヴァルター
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
NTT Docomo Inc
Original Assignee
NTT Docomo Inc
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by NTT Docomo Inc filed Critical NTT Docomo Inc
Publication of JP2011008778A publication Critical patent/JP2011008778A/ja
Application granted granted Critical
Publication of JP4990998B2 publication Critical patent/JP4990998B2/ja
Expired - Fee Related legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/52Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems during program execution, e.g. stack integrity ; Preventing unwanted data erasure; Buffer overflow
    • G06F21/53Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems during program execution, e.g. stack integrity ; Preventing unwanted data erasure; Buffer overflow by executing in a restricted environment, e.g. sandbox or secure virtual machine
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/52Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems during program execution, e.g. stack integrity ; Preventing unwanted data erasure; Buffer overflow
    • G06F21/54Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems during program execution, e.g. stack integrity ; Preventing unwanted data erasure; Buffer overflow by adding security routines or objects to programs

Description

本発明は、攻撃者によるプログラム実行フローの修正、例えば、バッファオーバーフロー攻撃を防止する方法及び装置に関する。
バッファオーバーフロー攻撃者は、しばしば、リターンアドレス(return address)(例えば、関数コール(関数呼び出し)又はメソッドコール(メソッド呼び出し)からのリターンアドレス)を変更できることを利用して、注入された悪意のあるコードを実行することによって、制御フローが継続するようにする。これによって、攻撃者は任意のコードを実行することができるようになるため、バッファオーバーフロー脆弱性を重大な脅威へと変えることになる。
バッファオーバーフロー攻撃を防止し、あるいはこれらの攻撃を大きく減らすための効果的な対策が必要となる。従来、メインストリームのオペレーティングシステムにはこのような対策が加えられていたが、時間が経過するにつれて、攻撃者は、これらの対策を迂回するやり方を発見してきた。したがって、新しい効果的な対策が開発されるべきである。
今日まで、様々な対策が知られている。対策は、概して2つの種類に分類される。
対策の第1の種類としては、攻撃者がリターンアドレスを変更することを不可能にするやり方である。この種の対策の例は、非特許文献1に記載されている。
対策の別の種類としては、攻撃者がリターンアドレスを修正することを許容するが、損害が起こる前に、これらの変更を検出しようと試みるやり方である。そのような対策の例は、スタック・クッキー(例えば、非特許文献2を参照)、ポインタ暗号化(例えば、非特許文献3を参照)、及び制御フロー・インテグリティCFI(例えば、非特許文献4を参照)である。
Yves Younan,Davide Pozza,Frank Piessens and Wouter Joosen.Extended protection against stack smashing attacks without performance loss.Proceedings of the 22nd Annual Computer Security Applications Conference (ACSAC’06),Miami Beach,Florida,U.S.A,December 2006.IEEE Press Jason Combs:Windows(登録商標) Stack Buffer Overflow Protection(http://www.ddj.com/security/184405546) Crispin Cowan,Steve Beattie,John Johansen,and Perry Wagle.Point−Guard:protecting pointers from buffer overflow vulnerabilities.In Proceedings of the 12th USENIX Security Symposium,pages 91−104,Washington,D.C.,U.S.A.,August 2003.USENIX Association Martin Abadi,Mihai Budiu,Ulfar Erlingsson,and Jay Ligatti.Control−flow integrity.In Proceedings of the 12th ACM Conference on Computer and Communications Security,pages 340−353,Alexandria,Virginia,U.S.A.,November 2005 Andrew Sloss,Dominic Symes,and Chris Wright.ARM System Developer’s Guide - Designing and Optimizing System Software,Elsvier,2004
制御フロー・インテグリティCFIは、プログラム実行フローのグラフを実質的に作成し、フロー内のジャンプを識別して、どこへジャンプするかを識別する。次いで、これらの場所(location)には、ユニークなIDが割り当てられ、このIDは、コードの中へ挿入される。次いで、実行の間にジャンプが起こると、ジャンプする場所が正しいIDを有するかどうかがチェックされる。正しいIDは、プログラムフローを検査するときに前もって決定されている。正しいIDでない場合は、プログラムは途中停止(アボート)される。このようにして、CFIは、プログラムフローのリターンアドレスが修正されたかどうかを検出し(修正されると、誤った行き先のラベルが生じることになる)、これに基づいてプログラムが途中停止される。
このアプローチは、ある程度効果的であるが、オーバーヘッドがかなり大きくなる。なぜなら、各ジャンプについて、このジャンプの正しい場所へ行くかどうか、言い換えれば、ジャンプが正しいIDに割り当てられたかどうかを、最初に調査しなければならないからである。このような操作は、プログラムの実行をかなり遅らせることになる。したがって、本発明の目的は、安全であって、CFIよりも小さいオーバーヘッドとなる他のアプローチを提供することである。
1つの実施形態によれば、順次に実行される操作のシーケンスを含むコンピュータプログラムの実行フローを攻撃者が修正することを防止する方法をコンピュータに実行させるプログラムが提供される。
該方法は、
攻撃者によって修正されていない前記コンピュータプログラムの実行フローの操作が置かれていることが期待されるコンピュータのメモリの1つ以上の範囲を識別するステップと、
メモリアドレスが前記1つ以上の識別されたメモリ範囲の中にあることを確実にするために、前記メモリアドレスをマスクするためのマスクを決定するステップと、
前記コンピュータプログラムの実行フローを検査して、前記コンピュータプログラムの実行フローが、前記コンピュータプログラムの実行フローの次の操作が置かれている目標メモリアドレスへジャンプすることを引き起こす前記プログラムの1つ以上の操作を識別するステップと、
前記識別された1つ以上の操作の実行前に、前記コンピュータプログラムの実行フローの中へある操作を挿入するステップであって、前記挿入された操作は、前記決定されたマスクを前記目標メモリアドレスへ適用することによって前記目標メモリアドレスをマスクし、このマスク操作によって、前記ジャンプを引き起こす操作が、前記1つ以上の識別されたメモリ範囲の中にあるメモリ場所へ向けられることを確実にする、ステップと
を含み、
前記コンピュータの前記メモリの1つ以上の範囲を識別するステップは、
プログラムコードの前記コンピュータプログラムの実行フローを検査し、前記コンピュータプログラムの実行フローの間に呼び出される関数について、前記関数が呼び出されるメモリアドレス場所を決定することを含み、
前記方法は、
前記コンピュータプログラムの実行フローが、前記呼び出された関数から、前記関数が呼び出されたアドレス又は前記関数が呼び出されたアドレスの次のアドレスへ戻るようにするマスクを決定するステップと、
前記呼び出された関数からの戻り処理が実行される前は常に、前記挿入された操作へ前記マスクを適用するステップと
を更に含む。
修正されていないコードが期待されるメモリ範囲を決定し、対応するマスクを決定してジャンプ前にこれを適用することによって、プログラム実行フローの任意の修正を攻撃者が実際に使用する可能性を厳しく制限することができる。
1つの実施形態によれば、目標アドレスは、識別された操作の現在のメモリアドレスに隣接するメモリアドレスとは異なる。言い換えれば、「ジャンプ」は、プログラム実行フローが、プログラム・コード・メモリの次のメモリアドレスではなく、ある一層遠いメモリ場所のメモリアドレスへ実際に「ジャンプ」することを意味する。
1つの実施形態によれば、前記1つ以上の識別されたメモリ範囲は、前記コンピュータプログラムの前記プログラムコードが置かれているメモリ範囲と、前記コンピュータプログラムによって使用されるようにロードされた1つ以上のライブラリが置かれているメモリ範囲との1つ以上を含む。
プログラムコードが置かれているメモリは、任意のバッファオーバーフロー攻撃に対して安全であると考えられ得るメモリ範囲であり、したがって、この範囲は、意味のあるマスクを生成するために使用され得る。
同様に、ロードされたライブラリが置かれているメモリ範囲は、比較的安全な区域として見なされ、したがって、このメモリ範囲についてもマスクが生成及び適用され得る。
1つの実施形態によれば、前記コンピュータプログラムの実行フローが目標メモリアドレスへジャンプすることを引き起こす前記1つ以上の操作は、
関数又はメソッドのコール(call:呼び出し)、
関数又はメソッドのコールからの戻り処理(リターン処理)、
計算されたジャンプ、
ライブラリ関数へのジャンプ
の1つ以上を含む。
これらは、プログラム実行フローが、次のメモリアドレスに置かれた命令への進行から外れる例である。したがって、これらは、潜在的に脆弱である命令であるが、マスク操作による保護が有用である命令である。
1つの実施形態による方法は、
ライブラリがロードされた前記メモリ範囲を読み出し専用としてマークするステップと、
グローバル・オフセット・テーブル及びプロシージャ・リンケージ・テーブルの双方あるいはいずれか一方を読み出し専用としてマークするステップと
の両方又はいずれか一方のステップを更に含む。
ライブラリが置かれている領域を読み出し専用としてマークすることは、ライブラリが置かれているコードの変更を防御し、
グローバル・オフセット・テーブル又はプロシージャ・リンケージ・テーブルを読み出し専用としてマークすることは、これらのテーブルの内容の修正に依存する任意の攻撃を防御する。
1つの実施形態の方法は、
任意の計算されたジャンプの前に前記マスクを適用する操作を挿入するステップと、
任意のライブラリのコール(呼び出し)の前に前記マスクを適用する操作を挿入するステップと、
グローバル・オフセット・テーブルにアクセスする前に前記マスクを前記グローバル・オフセット・テーブルへ適用するステップと、
プロシージャ・リンケージ・テーブルにアクセスする前に前記マスクを前記プロシージャ・リンケージ・テーブルへ適用するステップと
の1つ以上を含む。
これらは、マスク操作の挿入が、任意の攻撃を防止するために有用であり得る例である。
1つの実施形態による方法は、
修正されていないプログラムコードが置かれていることが期待される前記メモリ範囲の最後のメモリアドレスが、一連の連続した論理「1」で構成されていない場合、前記メモリ範囲の前記最後のメモリアドレスが一連の論理「1」で構成されるまで、ダミー命令又はNOP命令又は存在しない命令で前記メモリ範囲を充填するステップを含む。
このようにして、プログラムコードの最後のメモリアドレスが論理「0」を含む場合でも、良好なマスクが生成され得る。
1つの実施形態によれば、方法は、
プログラムコードのプログラムの実行フローを検査して、該プログラムの実行フローの間に呼び出される関数について、該関数が呼び出されるメモリアドレス場所を決定するステップと、
該呼び出された関数から、該関数が呼び出されたアドレス、又はこれらのアドレスの次にあるアドレスへ、プログラムの実行フローが戻るようにするマスクを決定するステップと、
呼び出された関数からのリターン処理(戻り処理)が実行される前は常に、該挿入された命令へ前記マスクを適用するステップと
を含む。
呼び出すアドレスに基づくマスクの決定及び適用は、一層精密なマスクを可能にし、これにより、実際にコール(呼び出し)が起こった関数又はアドレスへのみにリターン処理がジャンプすることが確実になり、セキュリティが向上する。
リターンのジャンプは、実際の実装又はコンパイラに依存して、ジャンプを引き起こした操作の後の「次の操作」の場所へ行くことを可能にするか、ジャンプを引き起こした命令の場所へ直接行くことを可能にする。
1つの実施形態によれば、前記マスクは、関数が呼び出された操作のアドレスの次にある操作のメモリアドレスをOR操作することに基づいて決定されるものである。
論理OR結合は、多数のコールアドレス(call address)に基づくマスク決定の実際的アプローチである。
1つの実施形態によれば、前記コンピュータプログラムの実行フローの間に呼び出される各関数について、前記関数に対して特有のマスクが決定され、前記関数特有のマスクは、前記呼び出された関数からのリターン処理が実行されるべきときに常に適用される。
これは、セキュリティを更に向上する関数特有のマスクの適用を確実にする。
1つの実施形態によれば、方法は、
前記コンピュータプログラムの実行フローの操作を整列させるステップであって、メソッドコール又は計算されたジャンプが、ある一定の区間又はこの区間の倍数だけ分離されたメモリアドレスに置かれるように整列される、ステップと、
前記マスクを適用した後に、結果として得られるメモリアドレスが、メソッドコール又は計算されたジャンプではない命令が置かれているアドレスの1つになるように、前記マスクを決定するステップと
を更に含む。
これは、攻撃者がジャンプ命令へ直接ジャンプすることによってマスキング命令を迂回することができないことを確実にする。
1つの実施形態によれば、方法は、
メソッドコール又は計算されたジャンプが、奇数メモリアドレスに置かれるように、前記コンピュータプログラムの実行フローの操作を整列させるステップと、
前記マスクを適用した後に、結果として得られるメモリアドレスが、偶数アドレスであって、ジャンプ又はメソッドコールからのリターン処理が次のジャンプ又はメソッドコールの前にあるアドレスで生じるように、前記マスクを決定するか、又は、メソッドコール又は計算されたジャンプが偶数メモリアドレスに置かれるように、前記コンピュータプログラムの実行フローの操作を整列させるステップと、
前記マスクを適用した後に、結果として得られるメモリアドレスが、奇数アドレスであって、メソッドコールからのジャンプ又はリターン処理が、次のジャンプ又はメソッドコールの前にあるアドレスで生じるように、前記マスクを決定するステップと
を含む。
これは、ジャンプ命令の整列の具体的な実装の仕方である。
1つの実施形態によれば、方法は、
前記挿入された操作によって、操作が実行される前にチェックされるパラメータを設定するステップと、
前記パラメータが設定されている場合にのみ、前記マスクの操作に後続する前記ジャンプの操作について及び前記ジャンプの実行に後続する操作について設定を実行するステップとを更に含む。
このようにして、条件付き実行可能パラメータを利用することによりセキュリティが更に向上され得る。
1つの実施形態によれば、順次に実行される操作のシーケンスを含むコンピュータプログラムの実行フローを攻撃者が修正することを防止する装置が提供される。
該装置は、
攻撃者によって修正されていない前記プログラムの実行フローの操作が置かれていることが期待されるコンピュータのメモリの1つ以上の範囲を識別するモジュールと、
メモリアドレスが前記1つ以上の識別されたメモリ範囲の中にあることを確実にするように、前記メモリアドレスをマスクするためのマスクを決定するモジュールと、
前記プログラムの実行フローを検査して、前記プログラムの前記実行フローが、前記プログラムの実行フローの次の操作が置かれている目標メモリアドレスへジャンプすることを引き起こす前記プログラムの1つ以上の操作を識別するモジュールであって、前記目標メモリアドレスは、識別された操作の現在のメモリアドレスに隣接するメモリアドレスとは異なる、モジュールと、
前記識別された1つ以上の操作の実行前に、前記プログラムの実行フローの中へある操作を挿入するモジュールであって、前記挿入された操作は、前記決定されたマスクを前記目標メモリアドレスへ適用することによって前記目標アドレスをマスクし、このマスク操作によって、前記ジャンプを引き起こす操作が、前記1つ以上の識別されたメモリ範囲の中にあるメモリ場所へ向けられることを確実にする、モジュールと
を備える。
1つの実施形態によれば、装置は、本発明の実施形態の1つに従った方法の各ステップそれぞれ実行するモジュールを備える。
本発明の実施形態を概略的に示した図である。 本発明の実施形態が適用され得るメモリ・アーキテクチャを概略的に示した図である。
本発明は、幾つかの実施形態を用いて説明される。最初に、説明で使用される幾つかの用語について説明する。
AND:論理AND操作
BIC:論理ビットクリア(AND NOT)
攻撃者:ソフトウェア内の脆弱性を探している悪意のあるユーザ
制御フロー・インテグリティ:アプリケーションにおける意図された制御フロー又はプログラムコードから外れることを識別するための対策
グローバル・オフセット・テーブル:グローバル・オフセット・テーブルは、位置独立アドレス計算(position-independent address calculation)の結果を絶対場所(absolute location)へ変換する
ヒープ:動的メモリ割り当てに使用されるコンピュータメモリ
マスク:ビット単位の操作に使用される値であって、他の値と結合されて特定の値域の中にある値を戻す
OR:論理OR操作
プログラムコード:実行されるべきアプリケーションの命令
プロシージャ・リンケージ・テーブル:プロシージャ・リンケージ・テーブルは、位置独立関数コール(position-independent function call)を絶対場所へ変換する。
シェルコード:攻撃者によって、メモリ、例えば、ヒープ又はスタックの中へ注入されるプログラムコード
スタック:固定された基点をもち、サイズが可変のコンピュータメモリ。スタックは後入れ先出し法で動作する
スタック・クッキー:予測し得ない値のトークン
本発明の1つの実施形態によれば、マスクは、関数コール(関数呼び出し)からリターンした後、又はメモリ内のある一定の範囲のみに対応する命令のウィンドウ(window)への関数コールを実行するとき、プログラムの実行を制限するようにする(マスクの生成及び適用は、この後で更に詳細に解明される)。
以下、時にはCRAM(コール及びリターンアドレス(return address)のマスキング)と呼ばれる本発明の実施形態に従ったアプローチは、プログラム実行フローが攻撃者によって修正されていない正規のコードが置かれていることが期待されるメモリ範囲を指し示すように、リターンアドレスをマスクする。そのようなメモリ範囲は、1つの実施形態によれば、例えば、プログラムコードが置かれているメモリ範囲である。任意の関数コールの目標アドレス(target address)又は関数からリターンするときの目標アドレスをマスクすることによって、データメモリの任意のオーバーフローバッファ内に注入されたコードが、実行されないようにする。
提示されたアプローチは、ランタイムオーバーヘッドが小さく、且つ他の対策と両立できる対策である。このアプローチは、セキュリティに関して高い保証を提供することができる。
本発明の実施形態によれば、プログラム実行フローを修正するような攻撃をどのようにして防止するかの新しいカテゴリが導入される。従来のアプローチは、ジャンプアドレスの修正を防止するか、ジャンプアドレスの修正を検出するものである。本発明の実施形態の提案アプローチによれば、第3のカテゴリの対策が提示される。提示されたアプローチは、リターンアドレスの上書きを防止するか、リターンアドレスの変更を検出する代わりに、攻撃者がいくらか修正をして有用な何かを行う可能性を制限するものである。
1つの実施形態によれば、修正されていない正規のプログラムコードが置かれていることを期待される1つ以上のメモリ範囲が識別される。このメモリ範囲は、例えば、プログラムコードが置かれている範囲であり、または、プログラム実行の間に使用されるロードされたライブラリ(loaded library)が置かれている範囲としてもよい。その範囲に対応するメモリ場所は、例えば、コンパイラによって決定され得る。
そのような1つ以上のメモリ場所が識別されると、マスクが生成される。このマスクは、メモリアドレスへ適用されたときに、1つ以上の識別された範囲の中にあるメモリアドレスが得られる。次いで、ジャンプ操作の前にマスクをジャンプ操作の目標アドレスへ適用する操作が、プログラム実行フローの中へ挿入される。言い換えれば、現在の命令が置かれているアドレスの次のアドレスに置かれている命令へ実行フローが進行せず、異なるアドレスへプログラムフローがジャンプする任意のジャンプについて、プログラム実行フローが検査される。そのような検査の対象となる命令は、関数あるいはメソッドコール、又は関数あるいはメソッドコールからのリターンの命令であり得る。
現在の操作の場所の次のアドレスとは異なる目標アドレスへのジャンプを引き起こす操作が識別されたとき、識別されたジャンプ操作の前に、マスキング操作がプログラム実行フローの中へ挿入される。マスキング操作は、正規の命令又は操作が置かれていることを期待され得るアドレスに基づいて決定されたマスクをジャンプ操作の目標アドレスへ適用し、これにより、攻撃者によって修正されていない正規のコードのみが置かれていることを期待され得るアドレスへジャンプを導くことを確実にする。
したがって、プログラム実行フロー内でマスクをジャンプの目標アドレスへ適用する処理をプログラム実行フローの中へ挿入することによって、正規の及び修正されていないプログラムコードを、攻撃者による修正から保護することができる。ジャンプは、プログラム実行フロー内で識別され、次いで、識別されたジャンプの目標アドレスへマスクを適用する操作を挿入することによって、プログラム実行フローが修正される。
1つ以上の「安全なメモリ範囲」の識別、対応するマスクの決定、プログラムフロー内のジャンプの識別、及びジャンプの目標アドレスをマスクするマスキング操作の挿入は、コンパイラによって実行され得る。コンパイラによってコンパイルされたプログラムは、各ジャンプ操作の前にマスキング操作を実行し、したがって、プログラム実行フローのジャンプは、攻撃者によって修正されていない正規のプログラムコードのみが置かれていることを期待される「安全なメモリ範囲」へのみ行われる。
このアプローチは、効率性が高く、オーバーヘッドを非常に小さくすることができる。
ここで、実施形態の具体的な例が説明される。
例えば、関数コールからのリターン処理に対応するジャンプのマスキングを達成するため、あるコードが、各関数の終わりに追加される。典型的には、関数は次のように終了する(抜粋されたアセンブラコード)。
[get return address from stack(スタックからリターンアドレスを取得する)]
[jump to this address(このアドレスへジャンプする)]
攻撃者がコードメモリ(即ち、修正されていないプログラムコードが置かれているメモリ範囲)へのみジャンプすることが確実であれば、攻撃者は、攻撃者自身が挿入して且つ典型的にはヒープ又はスタック上に置かれている攻撃者自身のシェルコードへ、ジャンプすることはできない。
この動作を達成させるために、1つの実施形態によれば、例えば、特別なマスクを実行するビット単位操作(例えば、AND、OR、又はBIC(論理ビットクリア−AND NOT))をリターンアドレスに適用してもよい。このマスクは、結果として得られるアドレスが、コードメモリの境界を越えないことを確実にする。リターンアドレス(=ジャンプの目標アドレス)へジャンプする代わりに、リターン処理においては、特別なマスクをリターンアドレスへ適用することから得られるアドレスへジャンプする。
この目的のために、上記のコードシーケンスは次のように変更される。
[get return address from stack(スタックからリターンアドレスを取得する)]
[apply mask on address, thus making sure that the return address points to code memory(マスクをアドレスに適用し、これにより、リターンアドレスがコードメモリを指し示すことを確実にする)]
[jump to this address(このアドレスへジャンプする)]
以上から分かるように、オリジナル(原初)のコードは、特別なマスクを適用する操作をジャンプ操作の前に挿入するように、修正されることになる。
これによって、アプリケーションは、依然としてバッファオーバーフローの脆弱性を有しているが、攻撃者が自身に対して有用なやり方で脆弱性を利用することがより困難になる。
図1は、修正される前の(オリジナルの)コードのコンパイルと、セキュリティを目的として修正された後の修正コードのコンパイルとを示している。
このアプローチは、オーバーヘッドを小さくし、したがって他の対策よりも良好な性能を提供し、同時にセキュリティを著しく改善する。
実施形態によれば、バッファオーバーフローは防止されないが、攻撃者がオーバーフローを用いてできることが制限されることになる。攻撃者は、重要なデータ、例えば、リターンアドレスを上書きすることによって、アプリケーションの制御フローを操作しようと試みる。この場合、攻撃者はリターンアドレスを操作し、このリターンアドレスがメモリ内のどこかを指し示すように操作することが想定される。提案されたアプローチは、リターンアドレスへ戻る前にリターンアドレスへマスクを適用することによって、この攻撃者が行うことを妨げる。マスクは、リターンアドレスがコードメモリ内のある場所を指し示すことを確実にし、攻撃者が、注入されたコードへリターンさせることをできないようにする。
同じアプローチは、プログラムフローが、関数コール又はメソッドコールから、目標アドレスとしてのリターンアドレスへ戻るときのジャンプに対して適用されるだけでなく、プログラム実行フローが、任意の他のジャンプ、例えば、ライブラリコールへジャンプするときにも適用される。この場合、適用されるマスクは、ロードされたライブラリが置かれているメモリ範囲に基づくことができる。1つを超えるメモリ範囲、例えば、プログラムコードが置かれているメモリ範囲及びライブラリが置かれているメモリ範囲に基づく組み合わせマスクが生成されるという意味で、双方のアプローチが組み合わせられてもよい。双方の範囲は、ライブラリのメモリ範囲及びプログラムコードのメモリ範囲へのジャンプを可能にするマスクを生じ得る。
以下では、Linuxオペレーティングシステム用の実施形態の例が示される。なお、他のオペレーティングシステムに対策を行うときは、本明細書で使用されるマスキング操作とは異なるマスキング操作が必要となるが、どのようなシステムでも、コンセプトは同じであることに留意すべきである。
図2で示されるように、プログラムデータ、ヒープ、及びスタックは、メモリ内でプログラムコードの上方に置かれている。例として、プログラムコードは0x00000000から0x0000FFFFまでの範囲にあることが想定され、スタック及びヒープは0x0000FFFFよりも大きいメモリアドレスに置かれている。
攻撃者が(例えば、バッファをオーバーフローさせることによって)シェルコードをヒープ又はスタックの中へ注入できるならば、注入されたシェルコードのアドレスでは、2つの最上位バイトの少なくとも1つのビットが常に1に設定される。ここで、リターンアドレスがマスク0x0000FFFFでマスクされるならば、これらのビットはクリアされる。結果として、プログラムコード(範囲は0x00000000から0x0000FFFFまで)の中のどこかで実行が継続することになる。最もありそうなこととして、そのように修正されたプログラムフローの場合、目標アドレスが意味をなさないので、例外が生じる。この例外としては、プログラムの実行を終了させる場合がある。しかしながら、注入されたコードの実行は、このようにして防止することができる。
マスクの適用を強制する提案した修正を適用するために、最初のステップにおいて、メソッドの終末部は、以下のa)の処理からb)の処理へと変更される。
a)リターンアドレスをフェッチして、そこへジャンプする
b)リターンアドレスをフェッチして、マスク及びリターンアドレスを用いて、例えば、AND操作(又は任意のビット単位操作)を実行し、次いで、そのAND操作の結果へジャンプする
ヒープ及びスタックは、メモリ内のより高いアドレスに置かれているので、スタック又はヒープ内の場所を指し示すリターンアドレスは、コードセグメント内のアドレスには決して設定されることがない1つ以上のビットを常に有している。したがって、AND操作を用いて、コードセグメントの外側へコードが決してジャンプしないことを強制することができる。他のオペレーティングシステム又はプロセッサでは、他のビット単位操作が使用されてもよいことに留意すべきである。これらの他の操作の例は、OR、BIC(ビットクリア)、又はリターンアドレス内のある数のビットをセット又はリセットし得る他の任意の操作である。
上述した対策は、標準return−to−libc攻撃が不可能になるという利点がある。なぜなら、ライブラリは、アプリケーションのコード領域の外側にロードされているからである。本明細書での「コード領域」は、「安全なメモリ範囲」又は攻撃者によって修正されていない正規のプログラムコードのみが置かれていることを期待されるメモリ範囲である。この範囲は、コンパイラによって決定され、次いで、対応するマスクが決定され得る。このマスクは、メモリ範囲0x00000000から0x0000FFFFまでの範囲へのジャンプを強制するものである。
他方、攻撃者は、アプリケーション内のlibcを呼び出す命令へジャンプし得る。しかしながら、攻撃者は、アプリケーションによって使用されるlibcメソッドへのジャンプしかできないので、危険は限定的なものとなる。
上記の例において、プログラムコードは、0x00000000から0x0000FFFFまでのメモリ範囲に置かれている。この例においては、マスクを容易に決定することができる。というのは、プログラムコードの最後のメモリ場所は、連続する論理「1」のみを含み、これによって、結果として得られるマスクも同じようなものとなるからである。しかしながら、プログラムコードの最後のメモリ場所が論理「0」も含むならば、プログラムコード区域を正確にマスクし、同時にプログラムコード区域の幾つかのアドレスを排除しないマスクを決定することはそれほど容易ではない。そのような場合、1つの実施形態によれば、プログラム・コード・メモリは、プログラムコードの最後のメモリアドレスが論理「1」のみで構成されるまで、NOP命令、又はダミー命令あるいは存在しない命令で充填される。次いで、充填されたプログラムコードが置かれているメモリ範囲を正確にマスクすることによって、前述したのと同じやり方でマスクが生成され得る。
以下では、そのような状況において攻撃からの危険を更に制限することができる他の実施形態が説明される。
この実施形態において、提案されるメカニズムは、メソッドがアプリケーション内の任意のコードへジャンプすることを許容する代わりに、その任意のコードへのジャンプをコールする(呼び出す)メソッドへのみ戻ることを許容する。これを行うために、関数ごとに特有のマスクが計算される。このアプローチは、下記で更に説明されるように、コード又はバイナリ解析を必要とする。次の例を考える。
メソッド又は関数M1は、アドレス0x0B3E(0000101100111110)に置かれ、メソッドM2は、アドレス0x0A98(0000101010011000)に置かれている。更に、前述したアドレスからM1及びM2によってのみM3が呼び出されると仮定する。この場合、マスク0x0BBE(0000101110111110)は、デフォルトマスク0xFFFF(1111111111111111)よりもずっとうまく機能する。なぜなら、より特有なマスク0x0BBEは、メソッドM3をM1又はM2へ戻すが、コード領域全体へは戻さないからである。この例のマスクは、関数M3が呼び出される2つのアドレス0000101100111110及び0000101010011000を組み合わせることに基づいている。この例の組み合わせは、論理ORであるが、結果として得られるマスクが、関数M3が呼び出された2つの場所のいずれかへ戻ることができる限り、他のビット単位操作も適用することができる。
したがって、この実施形態では、特に呼び出されるメソッド又は関数について、その関数が呼び出されるメモリ場所が識別される。次いで、これらの識別されたメモリ場所に基づいて、マスクが決定される。このマスクは、この関数に対して特有のものであり、この関数が呼び出された識別メモリ場所へ戻るようにする。
より正確に言えば、呼び出されたメソッド又は関数からそれを呼び出す関数へ戻るときは、呼び出しを行ったアドレスの次のアドレスへ常にジャンプするので、マスクは実際にそのようなアドレスに基づいて決定すべきである。言い換えれば、呼び出す操作が、0000101100111110に置かれていれば、呼び出す操作に後続するプログラムフロー内の次の操作が置かれている次のアドレスが、マスクを決定するために使用されるべきである。もちろん、呼び出しを行う任意の場所についても、同じことが言える。呼び出す命令に後続する正規の命令であるプログラムフロー内の次の正規の命令へ戻るように、マスクが決定されるべきである。
しかしながら、使用される実際の実装又はコンパイラに依存して、ジャンプを引き起こした命令が置かれているメモリ場所へ直接ジャンプして戻ることも許容され得る。より一般的には、1つの実施形態によれば、呼び出しを行ったメソッド又は関数に所属する場所を、好ましくはビット単位操作、例えばORにより組み合わせて、それらの場所に基づくマスクを生成することによって、関数又はメソッドコールからジャンプして戻る処理が、それらの場所へ限定される。
これらの関数特有のマスクは、プログラムコード範囲の全体よりも小さいアドレス範囲へ戻るように決定される方が好ましいことが明らかである。したがって、それらのマスクは、個々のコールアドレス(又は、これらのアドレスに後続するアドレス、上記を参照)に基づいて決定され、次いで、これらのコールアドレスは、マスクを生成するために組み合わせられる。このマスクは、適用されたときに、プログラムコード範囲の全体より小さい範囲をもたらし、このマスクは、より具体的には、関数が呼び出されたアドレスへ戻るようにする。
結果として得られるマスクは、関数特有のものなので、ある特定の関数からのリターン操作が識別されるとき、そのリターン操作の前に挿入されるマスキング操作は、その関数に対して特有のマスクを適用するという意味で、マスクを適用する操作の挿入も、もちろん関数特有のものである。
これらの関数特有のマスクは、バイナリファイルを解析することによって計算されるか、コンパイルプロセスの間に計算される。後者の場合、より良好なマスクを生成するために、メソッドを動かす追加のロジックがコンパイラへ追加されてもよい。これは、ある特定の他の関数を呼び出す異なる関数を実行して、それらの異なる関数が、類似するメモリアドレスに置かれるようにすることによって達成され得る。というのは、これは、論理「1」がより少なく且つ論理「0」がより多いマスクをもたらし、ジャンプが可能となるメモリ範囲を一層制限するからである。
しかしながら、説明された実施形態を用いる場合でも、攻撃者は、間接ポインタ上書き(indirect pointer overwrite)を実行し得る。これにより、攻撃者は、例えば、システムコール(例えば、printf)を攻撃者自身のコードへリダイレクト(変更)することができる。こうして、システムコールが次に実行されるとき、代わりに攻撃者のコードが実行される。これ(及び変形)を防御するために、1つの実施形態によれば、全ての計算されたジャンプ及びライブラリコールもマスクされる。ライブラリコールの場合、グローバル・オフセット・テーブル(GOT)内のエントリが変更されないようにするために、プロシージャ・リンケージ・テーブル(PLT)の中でマスキングが行われ得る。
この場合(マスキングがライブラリコールへ適用される場合)、マスクは、ロードされたライブラリが置かれたメモリ範囲に基づくものにすることができ、ライブラリコールに対応する各ジャンプの前にマスクを適用することができる。
更に、計算されたジャンプの場合、ジャンプの実行前にマスクが適用され得る。計算されたジャンプの場合、マスクは、プログラムコード区域に基づくものにすることができ、更にロードされたライブラリが置かれているメモリ範囲に基づくものにすることができる。
ライブラリを指し示すテーブル(GOT及びPLT)内のアドレスは、通常、プログラムコードのアドレス範囲を指し示さない。ライブラリは、プログラムコードよりも高いアドレスへマップされているので、ジャンプが、プログラムコード区域へジャンプするようにマスクされるならば、libcには決して到達することができない。マスクは、ライブラリが置かれている範囲を排除しないようにしており、なぜなら、そうしないと、プログラムが正しく実行されないからである。
他方、そのような場合、libcライブラリによってカバーされる全メモリ範囲よりも狭いメモリ領域まで、目標アドレスを狭くするマスクを発見できることが好ましい。
しかしながら、全ライブラリ(libc)メモリ区域よりも狭いマスクを発見することは困難である。これは、依然として厳しい攻撃が残されている可能性があることを意味する。
この問題を解決するため、1つの実施形態によれば、GOT(又はPLT)を読み出し専用(read-only)にすることができる。これは、いわゆる「memprotect」操作を実行することによって行うことができる。1つの実施形態によれば、memprotect操作は、「デフォルトセッティング」の一種として、言い換えれば、プログラムの正常な実行の間のセッティングとして使用され、GOT(又はPLT)が読み出し専用に設定される。ライブラリがロードされると、GOT又はPLTは、短時間の間、書き込み可能に設定されて、その中のポインタの設定を可能にし、その後で再び読み出し専用に設定される。memprotectコールは、メモリ区域を、読み出し専用から読み書き可能へ、及びこの逆へ、設定することができる。
これは、ライブラリがロードされるたびに、負担のかかるmemprotectコールが実行されねばならない欠点を有するが、幸いなことに、アプリケーションのライフタイムの間に頻繁に起こらない。この場合、PLT/GOTコード内で余分のAND操作を省略できるという利点がある(全てのライブラリコールが少し早くなる)。
結果として、バッファをオーバーフローさせるとき、攻撃者はGOT(又はPLT)を修正することができない。というのは、それは書き込み保護され、注入されたコードを攻撃者は実行できないからである。攻撃者はmemprotectコールも実行できない。
ここで、攻撃者がある特定のレジスタを制御できる場合に対処することができる更なる実施形態を説明する。
そのような場合、攻撃者は課された制限をうまく避けることができる。対策として、ライブラリ関数へのコールを、次のように変更した場合について考える。
[copy address of library function to register(ライブラリ関数のアドレスをレジスタへコピーする)]
[mask register(レジスタをマスクする)]
[jump to address in register(レジスタ内のアドレスへジャンプする)]
攻撃者がこのレジスタの内容をある程度制御できるならば、攻撃者は、リターン値を上書きして、[jump to address in register(レジスタ内のアドレスへジャンプする)]をポイントすることができる。この問題を解決する1つの方法は、メソッドコール及び計算されたジャンプを奇数アドレスに整列させることである。メソッドは、通常、関数を呼び出すその親メソッドの命令の直後に戻るので、これは常に偶数アドレスになる。その結果、マスクの最下位ビットは、常に0になるように選択され得る。これは、攻撃者が偶数アドレスへのみリターンすることを確実にする。計算されたジャンプは、奇数アドレスに整列するから、攻撃者は、ジャンプの前の命令(これはマスキング命令である)又はジャンプの後の命令へのみジャンプし得る。言い換えれば、攻撃者は、ジャンプ命令が置かれているメモリ場所へ直接ジャンプすることによってマスキング操作を迂回できない。
この方法は、コール及び計算されたジャンプが100のビットマスクへ整列することを確実にすることによって、全ての命令が4バイト整列で記憶されるRISCアーキテクチャへも拡張され得る。対策マスクの3つの最下位ビットは、000へ設定され、100のビットマスクに整列した命令へのリターンを妨げる。これは、アーキテクチャのデフォルト整列に依存して、任意に拡張され得る。
より一般的には、メソッドコール及び計算されたジャンプは、ある一定の区間又はこの区間のある倍数だけ分離されるアドレスで整列され得る。このようにして、ジャンプ命令の場所は、メモリアドレス空間内においてある特定のパターンに従っている。その特定のパターンは、マスクを決定するために使用されて、マスクをジャンプの目標アドレスへ適用するとき、ジャンプ命令が置かれているメモリ場所を排除する目標アドレスが得られるようにする。
代替の解決法は、ライブラリコールについて特別にレジスタを予約することである。これは、攻撃者がこのレジスタの内容に影響を及ぼすことができないことを確実にする。この解決法のインパクトは、プロセッサごとに異なる。というのは、これは、レジスタ圧力(register pressure)を増加させるからである。
上記で説明されたアプローチは、上書きされたリターンアドレスを用いて攻撃者が有用な何かを実行しようとするのを、既に厳しく妨げている。しかしながら、(バッファオーバーフローを用いるメソッドで使用されるマスクの精密度に依存して)システムコール又はライブラリコールを呼び出すコードメモリ内の場所を、リターンアドレスにポイントすることが依然として可能である。この問題を更に緩和するための1つのプラットフォーム特有のやり方は、プロセッサ特有の特徴、例えば、ARMプロセッサの条件付き実行を利用することである。ARMプロセッサについては、非特許文献5に記載されている。
このアプローチは、ARMプロセッサのアーキテクチャの特有の特徴、即ち、条件付き実行を使用する。「キャリー(carry)」ビットがセットされていれば、ある特定の命令のみが実行可能であり、「キャリー」ビットがセットされていなければ、全ての他の命令が実行可能であるという処理を行うことによって、追加の保護が与えられる。
この実施形態において、キャリーがセットされていないか(キャリークリア−cc)、セットされていれば(キャリーセット−cs)、全ての命令は、条件付き実行可能としてマークされていることになる(命令名のサフィックスとしての「cc」又は「cs」)。リターンアドレスのマスキングを行う命令(下記のコード例では操作03)は、キャリービットをセットする(命令名のサフィックス「s」は、キャリー・ビット・セットを得る)。呼び出す関数へのリターン分岐と、関数をコールした後の命令(例示的コードの命令04及び08)は、キャリービットがセットされていれば(「cs」のサフィックス)実行される。
ここで、攻撃者がリターンアドレスを上書きできれば、目標アドレスをマスクする(正規の)マスキング命令は、前の実施形態と関連して説明されたように、プログラムコードが1で終了することについて対処する。追加の副次的効果として、キャリービットは操作03によってセットされる。このようにして、条件付き実行可能パラメータが「キャリー・ビット・セット」であるようにマークされた命令でのみプログラムフローが進行することを保証し得る。これは、関数コールからのリターン処理を実行する命令(下記のコードでは命令04)及びリターンに後続する命令(下記のコードでは命令08)の場合である。
このようにして、たとえ攻撃者がリターンアドレスを修正できたとしても、修正されたリターンアドレスに置かれた命令は、依然として実行されない。なぜなら、この命令は、パラメータ「キャリー・フラグ・セット」で条件付き実行可能としてマークされていないからである。
アプローチは、ここで幾分異なる語句によって説明される。
最初のステップにおいて、全ての命令は、例えば、キャリーがクリアされるとき、条件付きでのみ実行するようにマークされなければならない。次いで、リターンアドレスをマスクする命令が選択され、キャリーフラグをセットするように修正される(下記で与えられるコード例では命令03)。メソッドから戻るために使用される次のジャンプは、この命令の「cs」サフィックスから分かるように、キャリーフラグがセットされるならば、条件付きで実行される。更に、リターンが向けられる命令(下記のコードの命令08)は、キャリーフラグがセットされるならば、条件付きで実行される。したがって、たとえ攻撃者が、リターン命令(下記のコードの命令04)がジャンプする場所に影響を与えることができたとしても、攻撃者は、キャリーがセットされているときに実行する命令があるアドレスへ制限される。これは、ライブラリ関数を呼び出す命令を含めて、アプリケーション全体のほとんど全ての命令を排除する。したがって、このアプローチは攻撃者を更に妨げる。というのは、攻撃者は、メソッドコール(ライブラリメソッドコールを除いて)が戻る正常な命令へのみにしかジャンプできないからである。
次の例を考える。
sum:#パラメータa及びbを加算して,結果を戻す
#この命令は、
#キャリーフラグがクリアされている場合にのみ実行する
01: addcc r0,r0,r1
#リターン;結果はr0の中にある
#r10を0xFFFFFFへセットする
02: movcc r10,#−1
#リターンアドレス(「lr」の中にある)をマスクする
#0x0000FFFFを用いる。更に
#キャリーを再びセットする
03: bicccs lr,r10,LSL #16
#キャリーは現在セットされている。コール側へ戻る
04: bxcs lr
親:<他の命令>
05: movcc r0,#1
06: movcc r1,#1
07: blcc sum
#キャリーをクリアする
08: movcss r10,pc,LSR #1
#キャリーフラグは現在クリアされている
09: ldrcc r0,L0
10: blcc printf
<他の命令>
この例において、攻撃者が関数「sum」の中でリターンアドレスを変更できるならば、攻撃者は命令04及び命令08へのみジャンプできる。というのは、これらの命令はキャリーフラグがセットされている場合のみ実行可能な命令だからである。全ての他の命令はアクセス不可能である。なぜなら、それらの命令はキャリーフラグがクリアされることを必要とするからである。
言い換えれば、マスキングは、プログラムフローの「条件付き実行可能」パラメータ、ここではキャリーフラグを変更することによって、更に向上される。プログラム全体の命令について、「条件付き実行可能」パラメータがセットされていない場合にのみ命令が実行されるように、これらの命令の設定が行われる。しかしながら、マスキングの後でジャンプを実際に実行する操作については、及びジャンプの後で実行されるべき操作については、条件付き実行可能パラメータがセットされている場合にのみ操作が実行されるように設定が行われる。このようにして、ジャンプに続く正しい操作を除く全ての他の操作が阻止される。
これまで説明された実施形態は、ハードウェア、ソフトウェア、又はソフトウェアとハードウェアとの組み合わせによって実装され得ることが、当業者によって理解される。本発明の実施形態と関連して説明されたモジュール及び機能は、全体的又は部分的に、マイクロプロセッサ又はコンピュータによって実装され得る。これらのマイクロプロセッサ又はコンピュータは、本発明の実施形態と関連して説明された方法に従って動作するように適切にプログラムされる。本発明の実施形態を実装する装置は、例えば、コンピューティングデバイス又は移動電話又は任意のモバイルデバイス又は移動局、又は本発明の実施形態で説明された方法を実行し得るように適切にプログラムされるノードで構成される。
本発明の実施形態によれば、コンピュータプログラムが提供される。このコンピュータプログラムは、データキャリアに記憶されるか、ある物理手段、例えば、記録メディア又は伝送リンクによって具現化された他のやり方で記憶される。また、このコンピュータプログラムは、コンピュータ上で実行するときに、これまでに説明された本発明の実施形態に従ってコンピュータを動作させるものである。

Claims (22)

  1. 順次に実行される操作のシーケンスを含むコンピュータプログラムの実行フローを攻撃者が修正することを防止する方法をコンピュータに実行させるプログラムであって、
    前記方法は、
    攻撃者によって修正されていない前記コンピュータプログラムの実行フローの操作が置かれていることが期待されるコンピュータのメモリの1つ以上の範囲を識別するステップと、
    メモリアドレスが前記1つ以上の識別されたメモリ範囲の中にあることを確実にするために、前記メモリアドレスをマスクするためのマスクを決定するステップと、
    前記コンピュータプログラムの実行フローを検査して、前記コンピュータプログラムの実行フローが、前記コンピュータプログラムの実行フローの次の操作が置かれている目標メモリアドレスへジャンプすることを引き起こす前記コンピュータプログラムの1つ以上の操作を識別するステップと、
    前記識別された1つ以上の操作の実行前に、前記コンピュータプログラムの実行フローの中へある操作を挿入するステップであって、前記挿入された操作は、前記決定されたマスクを前記目標メモリアドレスへ適用することによって前記目標メモリアドレスをマスクし、このマスク操作によって、前記ジャンプを引き起こす操作が、前記1つ以上の識別されたメモリ範囲の中にあるメモリ場所へ向けられることを確実にする、ステップと
    を含み、
    前記コンピュータの前記メモリの1つ以上の範囲を識別するステップは、
    プログラムコードの前記コンピュータプログラムの実行フローを検査し、前記コンピュータプログラムの実行フローの間に呼び出される関数について、前記関数が呼び出されるメモリアドレス場所を決定することを含み、
    前記方法は、
    前記コンピュータプログラムの実行フローが、前記呼び出された関数から、前記関数が呼び出されたアドレス又は前記関数が呼び出されたアドレスの次のアドレスへ戻るようにするマスクを決定するステップと、
    前記呼び出された関数からのリターン処理が実行される前は常に、前記挿入された操作へ前記マスクを適用するステップと
    を更に含む、プログラム
  2. 前記1つ以上の識別されたメモリ範囲は、
    前記コンピュータプログラムの前記プログラムコードが置かれているメモリ範囲と、
    前記コンピュータプログラムによって使用されるようにロードされた1つ以上のライブラリが置かれているメモリ範囲との1つ以上を含む、請求項1に記載のプログラム
  3. 前記コンピュータプログラムの実行フローが目標メモリアドレスへジャンプすることを引き起こす前記1つ以上の操作は、
    関数又はメソッドのコール処理、
    関数又はメソッドのコール処理からのリターン処理、
    計算されたジャンプ、
    ライブラリ関数へのジャンプ
    の1つ以上を含む、請求項1又は2に記載のプログラム
  4. 前記方法は、
    ライブラリがロードされた前記メモリ範囲を読み出し専用としてマークするステップと、
    グローバル・オフセット・テーブル及びプロシージャ・リンケージ・テーブルの双方あるいはいずれか一方を読み出し専用としてマークするステップと
    の両方又はいずれか一方のステップを更に含む、請求項1ないし3のいずれか一項に記載のプログラム
  5. 前記方法は、
    任意の計算されたジャンプの前に前記マスクを適用する操作を挿入するステップと、
    任意のライブラリコールの前に前記マスクを適用する操作を挿入するステップと、
    グローバル・オフセット・テーブルにアクセスする前に前記マスクを前記グローバル・オフセット・テーブルへ適用するステップと、
    プロシージャ・リンケージ・テーブルにアクセスする前に前記マスクを前記プロシージャ・リンケージ・テーブルへ適用するステップと
    の1つ以上を含む、請求項1ないし4のいずれか一項に記載のプログラム
  6. 前記方法は、
    修正されていないプログラムコードが置かれていることが期待される前記メモリ範囲の最後のメモリアドレスが、一連の連続した論理「1」で構成されていない場合、前記メモリ範囲の前記最後のメモリアドレスが一連の論理「1」で構成されるまで、ダミー命令又はNOP命令又は存在しない命令で前記メモリ範囲を充填するステップを含む、請求項1ないし5のいずれか一項に記載のプログラム
  7. 前記マスクは、前記関数が呼び出された操作のメモリアドレスの次にある操作のメモリアドレスをOR操作することに基づいて決定されるものである、請求項1に記載のプログラム
  8. 前記コンピュータプログラムの実行フローの間に呼び出される各関数について、前記関数に対して特有のマスクが決定され、前記関数特有のマスクは、前記呼び出された関数からの戻り処理が実行されるべきときに常に適用される、請求項1又は7に記載のプログラム
  9. 前記方法は、
    前記コンピュータプログラムの実行フローの操作を整列させるステップであって、メソッドコール又は計算されたジャンプが、ある一定の区間又はこの区間の倍数だけ分離されたメモリアドレスに置かれるように整列される、ステップと、
    前記マスクを適用した後に、結果として得られるメモリアドレスが、メソッドコール又は計算されたジャンプではない命令が置かれているアドレスの1つになるように、前記マスクを決定するステップと
    を更に含む、請求項1ないし8のいずれか一項に記載のプログラム
  10. 前記方法は、
    メソッドコール又は計算されたジャンプが、奇数メモリアドレスに置かれるように、前記コンピュータプログラムの実行フローの操作を整列させるステップと、
    前記マスクを適用した後に、結果として得られるメモリアドレスが、偶数アドレスであって、ジャンプ又はメソッドコールからのリターン処理が次のジャンプ又はメソッドコールの前にあるアドレスで生じるように、前記マスクを決定するか、又は、メソッドコール又は計算されたジャンプが偶数メモリアドレスに置かれるように、前記コンピュータプログラムの実行フローの操作を整列させるステップと、
    前記マスクを適用した後に、結果として得られるメモリアドレスが、奇数アドレスであって、メソッドコールからのジャンプ又はリターン処理が、次のジャンプ又はメソッドコールの前にあるアドレスで生じるように、前記マスクを決定するステップと
    を含む、請求項9に記載のプログラム
  11. 前記方法は、
    前記挿入された操作によって、操作が実行される前にチェックされるパラメータを設定するステップと、
    前記パラメータが設定されている場合にのみ、前記マスクの操作に後続する前記ジャンプの操作について及び前記ジャンプの実行に後続する操作について設定を実行するステップと
    を更に含む、請求項1ないし10のいずれか一項に記載のプログラム
  12. 順次に実行される操作のシーケンスを含むコンピュータプログラムの実行フローを攻撃者が修正することを防止する装置であって、
    攻撃者によって修正されていない前記プログラムの実行フローの操作が置かれていることが期待されるコンピュータのメモリの1つ以上の範囲を識別するモジュールと、
    メモリアドレスが前記1つ以上の識別されたメモリ範囲の中にあることを確実にするように、前記メモリアドレスをマスクするためのマスクを決定するモジュールと、
    前記プログラムの実行フローを検査して、前記プログラムの前記実行フローが、前記プログラムの実行フローの次の操作が置かれている目標メモリアドレスへジャンプすることを引き起こす前記プログラムの1つ以上の操作を識別するモジュールと、
    前記識別された1つ以上の操作の実行前に、前記プログラムの実行フローの中へある操作を挿入するモジュールであって、前記挿入された操作は、前記決定されたマスクを前記目標メモリアドレスへ適用することによって前記目標アドレスをマスクし、このマスク操作によって、前記ジャンプを引き起こす操作が、前記1つ以上の識別されたメモリ範囲の中にあるメモリ場所へ向けられることを確実にする、モジュールと
    を備え、
    前記コンピュータのメモリの1つ以上の範囲を識別する前記モジュールは、
    プログラムコードの前記プログラムの実行フローを検査して、前記プログラムの実行フローの間に呼び出される関数について、前記関数が呼び出されるメモリアドレス場所を決定するモジュールを備え、
    前記装置は、
    前記プログラムの実行フローが、前記呼び出された関数から、前記関数が呼び出されたアドレス又は前記関数が呼び出されたアドレスの次のアドレスへ戻るようにするマスクを決定するモジュールと、
    前記呼び出された関数からのリターン処理が実行される前は常に、前記挿入された操作へ前記マスクを適用するモジュールと
    を更に備える、装置。
  13. 前記1つ以上の識別されたメモリ範囲は、
    前記プログラムの前記プログラムコードが置かれているメモリ範囲と、
    前記プログラムによって使用されるようにロードされた1つ以上のライブラリが置かれているメモリ範囲との1つ以上を含む、請求項12に記載の装置。
  14. 前記プログラムの実行フローが目標メモリアドレスへジャンプすることを引き起こす前記1つ以上の操作は、
    関数又はメソッドのコール処理、
    関数又はメソッドのコール処理からのリターン処理、
    計算されたジャンプ、
    ライブラリ関数へのジャンプ
    の1つ以上を含む、請求項12又は13に記載の装置。
  15. ライブラリがロードされた前記メモリ範囲を読み出し専用としてマークするモジュールと、
    グローバル・オフセット・テーブル及びプロシージャ・リンケージ・テーブルの双方あるいはいずれか一方を読み出し専用としてマークするモジュールと
    の両方又はいずれか一方のモジュールを更に含む、請求項12ないし14のいずれか一項に記載の装置。
  16. 任意の計算されたジャンプの前に前記マスクを適用する操作を挿入するモジュールと、
    任意のライブラリコールの前に前記マスクを適用する操作を挿入するモジュールと、
    グローバル・オフセット・テーブルにアクセスする前に前記マスクを前記グローバル・オフセット・テーブルへ適用するモジュールと、
    プロシージャ・リンケージ・テーブルにアクセスする前に前記マスクを前記プロシージャ・リンケージ・テーブルへ適用するモジュールと
    の1つ以上を含む、請求項12ないし15のいずれか一項に記載の装置。
  17. 修正されていないプログラムコードが置かれていることが期待される前記メモリ範囲の最後のメモリアドレスが、一連の連続した論理「1」で構成されていない場合、前記メモリ範囲の前記最後のメモリアドレスが一連の論理「1」で構成されるまで、ダミー命令又はNOP命令又は存在しない命令で前記メモリ範囲を充填するモジュールを含む、請求項12ないし16のいずれか一項に記載の装置。
  18. 前記マスクは、前記関数が呼び出された操作のメモリアドレスの次にある操作のメモリアドレスをOR操作することに基づいて決定されるものである、請求項12に記載の装置。
  19. 前記プログラムの実行フローの間に呼び出される各関数について、前記関数に対して特有のマスクが決定され、前記関数特有のマスクは、前記呼び出された関数からの戻り処理が実行されるべきときに常に適用される、請求項12又は18に記載の装置。
  20. 前記プログラムの実行フローの操作を整列させるモジュールであって、メソッドコール又は計算されたジャンプが、ある一定の区間又はこの区間の倍数だけ分離されたメモリアドレスに置かれるように整列される、モジュールと、
    前記マスクを適用した後に、結果として得られるメモリアドレスが、メソッドコール又は計算されたジャンプではない命令が置かれているアドレスの1つになるように、前記マスクを決定するモジュールと
    を更に含む、請求項12ないし19のいずれか一項に記載の装置。
  21. メソッドコール又は計算されたジャンプが、奇数メモリアドレスに置かれるように、前記プログラムの実行フローの操作を整列させるモジュールと、
    前記マスクを適用した後に、結果として得られるメモリアドレスが、偶数アドレスであって、ジャンプ又はメソッドコールからのリターン処理が次のジャンプ又はメソッドコールの前にあるアドレスで生じるように、前記マスクを決定するか、又は、メソッドコール又は計算されたジャンプが偶数メモリアドレスに置かれるように、前記プログラムの実行フローの操作を整列させるモジュールと、
    前記マスクを適用した後に、結果として得られるメモリアドレスが、奇数アドレスであって、メソッドコールからのジャンプ又はリターン処理が、次のジャンプ又はメソッドコールの前にあるアドレスで生じるように、前記マスクを決定するモジュールと
    を含む、請求項20に記載の装置。
  22. 前記挿入された操作によって、操作が実行される前にチェックされるパラメータを設定するモジュールと、
    前記パラメータが設定されている場合にのみ、前記マスクの操作に後続する前記ジャンプの操作について及び前記ジャンプの実行に後続する操作について設定を実行するモジュールと
    を更に含む、請求項12ないし21のいずれか一項に記載の装置。
JP2010121289A 2009-05-27 2010-05-27 プログラム実行フローの修正を防止する方法及び装置 Expired - Fee Related JP4990998B2 (ja)

Applications Claiming Priority (2)

Application Number Priority Date Filing Date Title
EP09161239.0 2009-05-27
EP09161239A EP2256659A1 (en) 2009-05-27 2009-05-27 Method and apparatus for preventing modification of a program execution flow

Publications (2)

Publication Number Publication Date
JP2011008778A JP2011008778A (ja) 2011-01-13
JP4990998B2 true JP4990998B2 (ja) 2012-08-01

Family

ID=41165694

Family Applications (1)

Application Number Title Priority Date Filing Date
JP2010121289A Expired - Fee Related JP4990998B2 (ja) 2009-05-27 2010-05-27 プログラム実行フローの修正を防止する方法及び装置

Country Status (2)

Country Link
EP (1) EP2256659A1 (ja)
JP (1) JP4990998B2 (ja)

Families Citing this family (20)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN104050411A (zh) * 2011-04-21 2014-09-17 北京奇虎科技有限公司 主动防御方法
US8776223B2 (en) * 2012-01-16 2014-07-08 Qualcomm Incorporated Dynamic execution prevention to inhibit return-oriented programming
JP5820754B2 (ja) * 2012-03-21 2015-11-24 株式会社エヌ・ティ・ティ・データ 変換装置、変換方法、変換プログラム
JP5766648B2 (ja) * 2012-04-26 2015-08-19 日本電信電話株式会社 制御監視装置、制御監視方法及び制御監視プログラム
KR101265173B1 (ko) * 2012-05-11 2013-05-15 주식회사 안랩 비실행 파일 검사 장치 및 방법
KR101212553B1 (ko) * 2012-05-11 2012-12-14 주식회사 안랩 악성 파일 검사 장치 및 방법
WO2013174503A1 (en) * 2012-05-21 2013-11-28 Eth Zurich Secure loader
US9245110B2 (en) 2013-12-17 2016-01-26 International Business Machines Corporation Stack entry overwrite protection
CN105205390A (zh) * 2015-09-21 2015-12-30 上海斐讯数据通信技术有限公司 一种移动终端的安全检测系统及安全检测方法
WO2017201453A1 (en) * 2016-05-19 2017-11-23 Narf Industries, LLC System and method for probabilistic defense against remote exploitation of memory
CN106682508B (zh) * 2016-06-17 2019-01-11 腾讯科技(深圳)有限公司 病毒的查杀方法和装置
WO2018058414A1 (en) * 2016-09-29 2018-04-05 Intel Corporation Overflow detection
JP6996215B2 (ja) * 2017-07-03 2022-01-17 株式会社デンソー プログラム生成方法および電子制御装置
US11496506B2 (en) * 2017-07-03 2022-11-08 Denso Corporation Program generation method and electronic control unit for changing importance of functions based on detected operation state in a vehicle
JP6885226B2 (ja) 2017-07-03 2021-06-09 株式会社デンソー 電子制御装置
JP6338796B1 (ja) * 2018-01-09 2018-06-06 株式会社Attc 変換装置、変換プログラム、プログラム変換方法
JP6460433B1 (ja) * 2018-08-15 2019-01-30 株式会社Attc 変換装置、変換プログラム、プログラム変換方法
KR102351663B1 (ko) * 2020-02-26 2022-01-17 세종대학교산학협력단 Cfi 기반 got 변조 공격 방지 장치 및 그 방법
CN113885438B (zh) * 2021-10-26 2023-10-27 中国航发沈阳黎明航空发动机有限责任公司 一种整体叶盘混合铣加工自动截取程序的方法
WO2024057507A1 (ja) * 2022-09-15 2024-03-21 三菱電機株式会社 プログラム処理装置、プログラム処理方法、およびプログラム処理プログラム

Family Cites Families (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5745676A (en) * 1995-12-04 1998-04-28 International Business Machines Corporation Authority reduction and restoration method providing system integrity for subspace groups and single address spaces during program linkage
JP2007004647A (ja) * 2005-06-27 2007-01-11 Hitachi Ltd 不正コードの実行を防ぐプログラムの生成方法、及び、そのプログラム
JP2007304954A (ja) * 2006-05-12 2007-11-22 Sharp Corp メモリ保護機能を有するコンピュータシステム

Also Published As

Publication number Publication date
JP2011008778A (ja) 2011-01-13
EP2256659A1 (en) 2010-12-01

Similar Documents

Publication Publication Date Title
JP4990998B2 (ja) プログラム実行フローの修正を防止する方法及び装置
De Clercq et al. A survey of hardware-based control flow integrity (CFI)
US7086088B2 (en) Preventing stack buffer overflow attacks
EP2756366B1 (en) Systems, methods, and media for detecting return-oriented programming payloads
EP3069254B1 (en) Improved control flow integrity system and method
KR101480821B1 (ko) 리턴-지향형 프로그래밍을 억제하기 위한 동적 실행 방지
US20080133858A1 (en) Secure Bit
US20080140884A1 (en) Canary bit
US7287283B1 (en) Return-to-LIBC attack blocking system and method
EP2942727B1 (en) Return-oriented programming as an obfuscation technique
JP6435834B2 (ja) 命令実行制御装置、命令実行制御方法
CN109409086B (zh) 基于新增指令的检测堆栈中返回地址被篡改的装置
US11947663B2 (en) Control flow protection based on phantom addressing
US10572666B2 (en) Return-oriented programming mitigation
KR20220108176A (ko) 도메인 전이 디스에이블 구성 파라미터
US10579457B1 (en) Processor for achieving flow integrity and a method of providing notice of a fault in control flow
Lehniger et al. Window Canaries: Re-thinking Stack Canaries for Architectures with Register Windows
CN113032737B (zh) 软件的保护方法、装置、电子设备及存储介质
US11113392B2 (en) Executable binary code insertion
Lehniger et al. Combination of ROP Defense Mechanisms for Better Safety and Security in Embedded Systems
Roth et al. Implicit buffer overflow protection using memory segregation
CN111898119A (zh) 控制流完整性保护方法、装置、设备及存储介质
Gao et al. Metamorphic software for buffer overflow mitigation
US20230418950A1 (en) Methods, Devices, and Systems for Control Flow Integrity
Vallentin On the evolution of buffer overflows

Legal Events

Date Code Title Description
A131 Notification of reasons for refusal

Free format text: JAPANESE INTERMEDIATE CODE: A131

Effective date: 20120120

A521 Written amendment

Free format text: JAPANESE INTERMEDIATE CODE: A523

Effective date: 20120313

TRDD Decision of grant or rejection written
A01 Written decision to grant a patent or to grant a registration (utility model)

Free format text: JAPANESE INTERMEDIATE CODE: A01

Effective date: 20120410

A01 Written decision to grant a patent or to grant a registration (utility model)

Free format text: JAPANESE INTERMEDIATE CODE: A01

A61 First payment of annual fees (during grant procedure)

Free format text: JAPANESE INTERMEDIATE CODE: A61

Effective date: 20120502

R150 Certificate of patent or registration of utility model

Free format text: JAPANESE INTERMEDIATE CODE: R150

FPAY Renewal fee payment (event date is renewal date of database)

Free format text: PAYMENT UNTIL: 20150511

Year of fee payment: 3

LAPS Cancellation because of no payment of annual fees