JP6338796B1 - 変換装置、変換プログラム、プログラム変換方法 - Google Patents

変換装置、変換プログラム、プログラム変換方法 Download PDF

Info

Publication number
JP6338796B1
JP6338796B1 JP2018000920A JP2018000920A JP6338796B1 JP 6338796 B1 JP6338796 B1 JP 6338796B1 JP 2018000920 A JP2018000920 A JP 2018000920A JP 2018000920 A JP2018000920 A JP 2018000920A JP 6338796 B1 JP6338796 B1 JP 6338796B1
Authority
JP
Japan
Prior art keywords
address
instruction
function
conversion target
target program
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.)
Active
Application number
JP2018000920A
Other languages
English (en)
Other versions
JP2019121203A (ja
Inventor
平 昌展
昌展 平
Original Assignee
株式会社Attc
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 株式会社Attc filed Critical 株式会社Attc
Priority to JP2018000920A priority Critical patent/JP6338796B1/ja
Application granted granted Critical
Publication of JP6338796B1 publication Critical patent/JP6338796B1/ja
Publication of JP2019121203A publication Critical patent/JP2019121203A/ja
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Landscapes

  • Stored Programmes (AREA)
  • Storage Device Security (AREA)

Abstract

【課題】ソフトウェアの脆弱性を利用した攻撃による不正なプログラムの実行を防止すること。【解決手段】本発明は、遅延リンクを採用した実行ファイルからリンクされるプログラム内の関数が呼び出されるコンピュータでの処理において、関数が呼び出された際に指示されたアドレスが間接参照するグローバルオフセットテーブル中の前記関数のスロットが呼び出された関数を正しく指し示しているかを判定し、指し示していなければ実行を停止するようにプログラムを変換することで、不正なプログラムの実行を未然に防止する。【選択図】図1

Description

本発明は、ソフトウェアの脆弱性を利用した攻撃による不正なプログラムの実行を防止する技術に関するものである。
不正なプログラムをコンピュータにおいて実行することによる情報流出が問題となっている。これらの不正なプログラムは、ソフトウェアの脆弱性を利用するものが多い。
代表的な例としてバッファオーバーフロー攻撃がある。コンピュータでのプログラムの動作において関数が呼び出される際には、当該関数の呼び出し元へ戻ることを可能とするために、戻り先のアドレスがレジスタまたはメモリ上のスタック領域に格納されるが、関数の脆弱性を利用してスタック領域上の戻り先のアドレスを不正なアドレスに上書きする攻撃がよく知られている。
特許文献1には、バッファオーバーフローの発生を防ぐようにプログラムを変換する変換装置が記載されている。
特許文献2には、バッファオーバーフローによる不正なプログラムの実行を防止する手段を備えるプロセッサが記載されている。
特許第5820754号公報 特許第5777843号公報
しかしながら、バッファオーバーフロー攻撃以外にもソフトウェアの脆弱性を利用して、本来意図しないアドレスに書き換える攻撃が存在する。例えば、位置独立コード化された共有ライブラリ内の関数を実行可能ファイルから呼び出す場合、Linux(登録商標)でよく利用される実行ファイル形式であるExecutable and Linkable Format(以下、ELF)では、関数のアドレスを再配置可能とするために、プロシージャリンケージテーブル(以下、PLT)を経由してグローバルオフセットテーブル(以下、GOT)というアドレス管理テーブルを利用する。共有ライブラリがロードされれば、共有ライブラリの絶対アドレスが決定されるため、当該関数の絶対アドレスも必然的に解決できることになるが、解決のためにはアドレスの再計算が必要となる。よって、実行可能ファイルの起動を優先するために、アドレス解決のタイミングを個々の関数が実際に呼び出される時に行う方式があり、遅延リンクと呼ばれている。この場合は、アドレス解決のタイミングが関数の呼び出し時となるため、GOTは読み書き可能とせざるを得ない。ところが、この特徴を利用したGOT上書き攻撃というものが存在する。攻撃時に、本来のアドレスの代わりに、不正なアドレスに書き換えておき、実際の関数呼び出しの際に、不正な処理を実行させる攻撃である。このように、共有ライブラリが位置独立コード化されていると、実行可能ファイルの実行時に動的リンクによってその絶対アドレスが解決されるために、特許文献1及び特許文献2に記載された発明では、いずれも主処理で呼び出されるプログラムを指し示す絶対アドレスが主処理の実行前にすべて判明していることを前提としているために対応ができない。
また、遅延リンクを採用せずGOTを書き込み禁止とする対策も考えられるが、前述のように起動に時間がかかるという課題がある。
本発明は、このような事情を鑑みてなされたものであり、前述の課題を解決しつつ、ソフトウェアの脆弱性を利用した攻撃による不正なプログラムの実行を防止する変換装置、変換プログラム、プログラム変換方法を提供することを目的とする。
本発明である変換装置、変換プログラム及びコンピュータを用いたプログラム変換方法は、共有ライブラリ内の関数を呼び出す際に、変換対象プログラムに存在する前記関数のPLTから、GOT中の前記関数のスロット(以下、GOTスロット)を特定し、さらに、このGOTスロットが参照する値が適正か否かを判定し、不正なアドレスに書き換えられていると判定した場合には実行を中断するように、変換対象プログラムを変換することで、前述の課題を解決する。
前述の課題を解決するために、本発明は、GOTスロットが参照する値と変換対象プログラムに存在するPLTに記述されている遅延リンクの際に関数のアドレスを解決するための命令群の先頭アドレス(以下、PLT解決アドレス)と対比し、次に、変換対象プログラムから呼び出される関数本体の先頭アドレス(以下、関数アドレス)と対比することで、値がいずれも一致しない場合に不正なアドレスに書き換えられていると判定する命令を、いずれかに値が一致する場合は直接的または間接的に関数を呼び出す命令を生成して、変換対象プログラムに挿入することを特徴とする。また、前記命令は、変換対象プログラム及び共有ライブラリの各々が位置独立コード化されているか否かの場合分けによって、対比すべきアドレスを算出することを特徴とする。
前述の課題を解決するために、本発明は、判定に必要なGOTスロットとPLT解決アドレスを変換対象プログラムに問い合わせることで、さらに、関数アドレスを共有ライブラリに問い合わせることで、それぞれ取得し、保持することを特徴とする。
前述の課題を解決するために、本発明は、対比すべきアドレスの算出に必要な変換対象プログラムの開始アドレス及び共有ライブラリの開始アドレスを、変換対象プログラムの実行開始直後に算出して静的変数に格納するプログラムを生成して、変換対象プログラムに挿入することを特徴とする。
前述の課題を解決するために、本発明は、変換対象プログラムから共有ライブラリ内の関数を呼び出す命令を検出して、命令を追加することを考慮してリターンアドレスを再計算して保持した後に、前述のGOTスロットが参照する値が適正か否かを判定する命令にジャンプし、さらに保持したリターンアドレスに復帰させる命令に書き換えることを特徴とする。
前述の課題を解決するために、本発明は、変換対象プログラムから変換対象プログラム内の関数を呼び出す命令を検出して、検出した命令の前に、さらに命令を追加することを考慮してリターンアドレスを再計算して保持する命令を挿入し、検出した命令の後に、保持したリターンアドレスに復帰させる命令を挿入する。さらに、変換対象プログラム内の関数のリターン命令を検出して、検出した命令を保持したリターンアドレスにジャンプする命令に書き換えることを特徴とする。
以上のように本発明によれば、前述の課題を解決して、ソフトウェアの脆弱性を利用した攻撃による不正なプログラムの実行を防止することができる。
変換装置の構成例を示すブロック図である。 変換装置のハードウェア構成である。 変換装置の動作を示すフローチャートである。 メモリマップの例である。 第1実施形態において、変換済みプログラム実行時のロードアドレス算出命令の動作を示すフローチャートである。 PLT経由のGOTの間接参照のしくみを説明する概念図である。 GOT書き込み可の場合に、GOTスロットが参照する値が適正か否かを判定するアルゴリズムを示した図である。 変換装置の動作のうちチェック命令生成挿入処理を示すフローチャートである。 変換済みプログラム実行時のPLTチェック命令Aの動作を示すフローチャートである。 変換済みプログラム実行時のPLTチェック命令Bの動作を示すフローチャートである。 チェック命令生成挿入処理のうち関数アドレスチェック命令生成挿入処理を示すフローチャートである。 変換済みプログラム実行時の関数アドレスチェック命令Aの動作を示すフローチャートである。 変換済みプログラム実行時の関数アドレスチェック命令Bの動作を示すフローチャートである。 変換済みプログラム実行時の関数アドレスチェック命令Cの動作を示すフローチャートである。 変換済みプログラム実行時の関数アドレスチェック命令Dの動作を示すフローチャートである。 第2実施形態において、変換済みプログラム実行時のロードアドレス算出命令の動作を示すフローチャートである。 各オブジェクトの開始アドレスを結合した文字列をひとつの静的変数に、格納した状態を模式的に例示した図である。
本発明の実施の形態について図面を参照して説明する。なお、各図において同一又は相当部分には同一の符号を付し、重複する説明を省略する。
(第1実施形態)
本実施形態に係る変換装置は、攻撃を検知して停止するようにプログラムを変換する変換装置である。この変換装置は、GOTを書き換えることで不正なプログラムを実行するGOT上書き攻撃からの防御のためにプログラムを変換する装置として好適に採用されるものである。
図1は、本実施形態による変換装置10の構成を示すブロック図である。変換装置10は、アセンブリプログラムをセキュアなアセンブリプログラムに変換するものである。本明細書において、セキュアとは、プログラムへの攻撃から防御するための処理を施された状態を指し、プログラムをセキュアなプログラムに変換することがセキュア化である。図1で示すように、ソースプログラムをコンパイラによってアセンブリプログラムに変換した後に、変換装置10でセキュア化する。変換装置10によってセキュア化されたアセンブリプログラムは、アセンブラによってオブジェクトプログラムに変換する。コンパイラに代えて逆アセンブルすることでオブジェクトプログラムをアセンブリプログラムに変換した後に、変換装置10でセキュアなアセンブリプログラムに変換してもよい。
図1に示すように、変換装置10は、ロードアドレス算出命令生成挿入部100、GOTスロット取得部110、GOT書き込み可否判定部120、PLT解決アドレス取得部130、関数アドレス取得部140、PLTチェック命令生成挿入部150、関数アドレスチェック命令生成挿入部160、関数別ジャンプ命令生成挿入部170、コール命令書き換え部180、及び、リターン命令書き換え部190を備えている。
また、GOTスロット取得部110、GOT書き込み可否判定部120、PLT解決アドレス取得部130、及び、関数アドレス取得部140を情報取得ブロックB10と、PLTチェック命令生成挿入部150、関数アドレスチェック命令生成挿入部160、及び、関数別ジャンプ命令生成挿入部170を命令生成挿入ブロックB20と、コール命令書き換え部180、及び、リターン命令書き換え部190を命令書き換えブロックB30として説明する。
ロードアドレス算出命令生成挿入部100は、変換対象プログラムの実行開始直後に変換対象プログラムの開始アドレス及び共有ライブラリの開始アドレスを算出して静的変数に格納するプログラムを生成し、変換対象プログラムから呼び出すことができるように前記変換対象プログラムに挿入する機能を有している。
GOTスロット取得部110は、変換対象プログラムにリンクされる共有ライブラリ内の関数についてのGOTスロットを、変換対象プログラムに問い合わせ、取得して、保持する機能を有している。
GOT書き込み可否判定部120は、変換対象プログラムに存在するGOTが書き込み可能かどうかを判定する機能を有している。
PLT解決アドレス取得部130は、GOTが書き込み可能な場合に、変換対象プログラムにリンクされる共有ライブラリ内の関数についてのPLT解決アドレスを、変換対象プログラムに問い合わせ、取得して、保持する機能を有している。
関数アドレス取得部140は、GOTが書き込み可能な場合に、変換対象プログラムから呼び出される関数についての関数アドレスを、共有ライブラリに問い合わせ、取得して、保持する機能を有している。
PLTチェック命令生成挿入部150は、PLTチェック命令を、生成して、変換対象プログラムに挿入する機能を有している。本実施形態では、判定処理中にGOTスロットが他のスレッドによって改ざんされることを回避するためにGOTスロットが参照する値をレジスタに転送する例で説明する。なお、レジスタに限定するものではなく、他のスレッドからアクセスできないような他の記憶媒体であってもよい。ここで、PLTチェック命令とは、GOTが書き込み可能な場合に、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、PLT解決アドレスと、GOTスロットが参照する値を対比して、変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合には、変換対象プログラムの開始位置を示す絶対アドレスとPLT解決アドレスとを加算して得られる絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとGOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば、関数別ジャンプ命令生成挿入部170が生成した命令に引き渡す命令をいう。以下において同様である。ここで引き渡す命令とは、目的の命令にジャンプする命令であっても、後続の命令として続けて実行させる命令でもよい。以下において同様の意味で使用する。
関数アドレスチェック命令生成挿入部160は、関数アドレスチェック命令を、生成して、変換対象プログラムに挿入する機能を有している。本実施形態では、判定処理中にGOTスロットが参照先するアドレスが他のスレッドによって改ざんされることを回避するために、GOTスロットが参照する値をレジスタに転送する例で説明する。なお、レジスタに限定するものではなく他のスレッドからアクセスできないような他の記憶媒体であってもよい。ここで、関数アドレスチェック命令とは、GOTが書き込み可能な場合に、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合であって、共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、関数アドレスと、GOTスロットが参照する値とを対比して、共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる絶対アドレスと、GOTスロットが参照する値とを対比して、変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合であって、共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、関数アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとGOTスロットとを加算した結果であるアドレスが参照する値とを対比して、共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる関数の開始位置を示す絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとGOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば、関数別ジャンプ命令生成挿入部170が生成した命令に引き渡す命令を、値が一致しなければ変換対象プログラムを終了させる命令をいう。以下において同様である。
関数別ジャンプ命令生成挿入部170は、関数別ジャンプ命令を、生成して、変換対象プログラムに挿入する機能を有している。ここで、関数別ジャンプ命令とは、GOTが書き込み可能であり、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスであり、共用ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、関数アドレスチェック命令生成挿入部160で、GOTスロットが参照する値を格納したレジスタの値に分岐する命令を、それ以外の場合には、本来のPLT経由で関数をコールする命令をいう。なお、ここでGOTスロットが参照する値を格納したレジスタの値に分岐する命令は、ジャンプ命令であってもよいし、GOTスロットが参照する値を格納したレジスタの値を関数アドレスとしてコールする命令であってもよい。以下において同様である。
コール命令書き換え部180は、変換対象プログラムから共有ライブラリ内の関数を呼び出す命令を検出し、命令が追加される分を考慮し、リターンアドレスを再計算してレジスタに格納し、検出した関数を呼び出す命令を、GOTが書き込み可能な場合にはPLTチェック命令に、GOTが書き込み禁止の場合には関数別ジャンプ命令に、ジャンプする命令に書き換える機能を有している。なお、本実施形態では、再計算したリターンアドレスをレジスタに転送する例で説明するが、レジスタに限定するものではなく他のスレッドからアクセスできないような他の記憶媒体であってもよい。
リターン命令書き換え部190は、変換対象プログラムからリターン命令を検出し、検出したリターン命令を、コール命令書き換え部180でレジスタに格納されたアドレスにジャンプする命令に書き換える機能を有している。
図1に示す変換装置10は、図2に示すハードウェア構成20を有する。図2に示すように、変換装置10は、物理的には、中央演算装置(CPU)210、入力装置220、出力装置230、主記憶装置(RAM/ROM)240、補助記憶装置250等を含むコンピュータシステムとして構成される。また、一時的な記憶回路としてCPU内に複数のレジスタ260を有する。
変換装置10の各機能は、図2に示す中央演算装置(CPU)210、主記憶装置(RAM/ROM)240等に所定のコンピュータソフトウェアを読み込ませることにより、中央演算装置(CPU)210の制御により入力装置220、出力装置230を動作させるとともに、主記憶装置(RAM/ROM)240、補助記憶装置250とデータの読み書きを行うことで実現される。
次に、本実施形態に係る変換装置10の動作について説明する。図3は、本実施形態に係る変換装置10の動作を示すフローチャートである。なお、説明理解の容易性を考慮して、以下では、オペレーションシステムとしてLinux(登録商標)、プログラミング言語としてC言語、コンパイラとしてGNUコンパイラコレクション(以下、GCC)、及び、コンパイラが生成するファイル形式としてELFを使用するものとして説明するが、コンピュータが同様の挙動をとる環境であれば同じである。
変換装置10は、例えば、変換対象プログラム及び変換対象プログラムにリンクされるプログラムをプロセス空間にロードした後に明示的に動作の開始を指示するなどによって、図3に示す動作を開始する。
変換装置10の動作の開始にあたっては、変換装置10に対して変換対象プログラムを指定する。例えば、変換装置10で起動する変換プログラムに引数として、変換対象プログラムの実行可能ファイルのプロセスID、変換対象プログラムのオブジェクトファイルのディレクトリパス、変換対象プログラムのオブジェクトファイルのソースファイルのディレクトリパスを与えるなどによって指定する。
図3に示すフローチャートに従って、本実施形態に係る変換装置10の動作について説明する。
ロードアドレス算出命令生成挿入部100が、ロードアドレス算出命令生成挿入処理(S301)を行う。ロードアドレス算出命令生成挿入処理(S301)では、まず、変換対象プログラム及び変換対象プログラムにリンクされるプログラムの開始アドレスを格納する静的変数を定義する処理を行う。次に、変換対象プログラムの実行開始直後に、変換対象プログラムの開始アドレス及び変換対象プログラムにリンクされるプログラムの開始アドレスを算出し、定義した静的変数に格納することで保持するプログラムを生成する処理を行う。最後に、生成したプログラムを変換対象プログラムから呼び出すことができるように変換対象プログラムに挿入する処理を行う。以下、ロードアドレス算出命令生成挿入処理(S301)の内容を説明する。
まず、ロードアドレス算出命令生成挿入部100は、変換対象プログラム及び変換対象プログラムにリンクされるプログラムの開始アドレスを格納する静的変数を定義する処理を行う。
ロードアドレス算出命令生成挿入部100は、メモリマップを取得する。メモリマップとは、オペレーティングシステムのカーネルにおいてプロセスの状態を示すデータ構造の情報をマッピングしたファイルである。メモリマップによってプロセス空間の各領域の正確な開始アドレスを得ることができる。例えば、Linux(登録商標)では、/procディレクトリ配下にプロセスIDごとに存在する。自プロセスIDは、C言語ではgetpid関数によって取得できる。
図4に、メモリマップの例を示す。符号aに開始アドレスが、符号bに終了アドレスが、符号cにアクセス権限が、符号dにフルパスが示される。実行可能ファイル(符号e)と共有ライブラリ(符号f)は、いずれもアクセス権限(符号c)がr−xp(読み込み可、書き込み不可、実行可)であることから識別ができる。
ロードアドレス算出命令生成挿入部100は、取得したメモリマップからアクセス権限(符号c)がr−xpであるオブジェクトファイルについて、フルパス(符号d)と開始アドレス(符号a)を抽出する。なお、アクセス権限(符号c)がr−xpであってもローダなどチェックの必要がないオブジェクトファイルについて、処理の効率化を図るために抽出対象から除外してもよい。
ロードアドレス算出命令生成挿入部100は、抽出した実行可能ファイル及び共有ライブラリについて、開始アドレスを格納するための静的変数として開始アドレス格納変数を定義する。ここでは、開始アドレス格納変数名に連番を付与して定義して、開始アドレスの降順に格納するとして説明する。
表1は、例として、ロードアドレス算出命令生成挿入部100が、図4に示すメモリマップから実行可能ファイル及び共有ライブラリについて、フルパス及び対応する定義した開始アドレス格納変数を示したものである。
次に、ロードアドレス算出命令生成挿入部100は、変換対象プログラムの実行開始直後に、変換対象プログラムの開始アドレス及び変換対象プログラムにリンクされる共用ライブラリの開始アドレスを算出し、定義した静的変数に格納することで保持するプログラムを生成する処理を行う。
ロードアドレス算出命令生成挿入部100が生成するプログラムの詳細と変換済みの変換対象プログラム実行時の動作については後述する。
最後に、ロードアドレス算出命令生成挿入部100は、生成したプログラムを変換対象プログラムから呼び出すことができるように変換対象プログラムに挿入する処理を行う。定義した静的変数(開始アドレス格納変数)をヘッダファイルとして、変換対象プログラムのソースコードにインクルードし、さらに生成したプログラムの呼び出しを変換対象プログラムのソースコード中のmain関数の冒頭に記述することで、変換対象プログラムの起動直後に生成したプログラムを呼び出すことができるようにする。したがって、ロードアドレス算出命令生成挿入処理(S301)は、変換対象プログラム及び生成したプログラムのコンパイルとリンクを行う。ロードアドレス算出命令生成挿入処理(S301)が終了すると、GOTスロット取得処理(S303)に移行する。
ここで、実行時におけるロードアドレス算出命令生成挿入部100が生成し、挿入したプログラムの動作を説明する。
プログラムが実行されると実行可能ファイルのヘッダファイルに記述された開始アドレス格納変数の領域がプロセス空間に確保される。アドレス格納変数は静的変数であるからアドレス(変数のアドレス)は絶対アドレスとなる。表2は、実行可能ファイル及び共有ライブラリについてのフルパス、開始アドレス格納変数及び定義した開始アドレス格納変数のアドレスを示した例である。
図5は、変換済みのプログラム実行時におけるロードアドレス算出命令生成挿入部100が生成し、挿入したプログラムの動作を示すフローチャートである。
変換済みのプログラムの実行ファイルからロードアドレス算出命令生成挿入部100が生成し、挿入したプログラムが呼び出されると自プロセスIDを取得する処理(S501)が実行される。getpid関数でプロセスIDを取得する。S501の処理が終了するとS503の処理に移行する。
S503の処理では、取得したプロセスIDのメモリマップを取得する。メモリマップは/procディレクトリ配下にプロセスIDごとに存在する。S503の処理が終了するとS505の処理に移行する。
S505の処理では、取得したプロセスIDのメモリマップを1行ずつ取得する。アクセス権限がr−xpである場合(S507)に、開始アドレスを対応する開始アドレス格納変数に入力(S509)する。メモリマップの最終行までS505の処理が終了するとロードアドレス算出命令生成挿入部100が生成するプログラムによる処理が終了する。
表3は、図4に示すメモリマップについて、図5に示す処理終了後の状態を例として示した表である。例えば、表3の1行目は、mainの先頭を示す絶対アドレスは0x00400000であって、この値は定義された静的変数start_load_addr0に格納されており、この静的変数のアドレスが0x00000000006018d0であることを示している。
図3に戻り、ロードアドレス算出命令生成挿入処理(S301)が終了すると、GOTスロット取得処理(S303)から始まる情報取得ブロックB10で行う処理に移行する。
情報取得ブロックB10で行う処理の説明の前に、以降の説明理解のために、共有ライブラリ内の関数呼出におけるGOTとPLTの役割について概説する。
共有ライブラリ内の関数を呼び出す手段としてGOTを利用する。GOTは、外部関数及び外部変数のアドレスを格納しているテーブルである。これにより、共有ライブラリが位置独立コードであっても目的の関数や変数にアクセス可能となる。
一般に外部関数や外部変数の数が多くなるとアドレス解決に要する時間が無視できなくなり、実行可能ファイルの起動が遅延することがある。このため、関数が初めて呼び出された時にアドレス解決を行う方法があり、遅延リンクという。PLTは遅延リンクの際に利用される。
遅延リンクは、PLTを経由してGOTを間接参照することで実現する。共有ライブラリ内の関数を指し示すアドレスは、共有ライブラリがロードされた際に、共有ライブラリの開始アドレスと関数のオフセットを用いて決定される。演算を必要とするため直接的にアドレスを指定することができないので、PLTを経由してGOTを間接参照する。PLTにはアドレス解決のための小さなコードが含まれている。
図6は、共有ライブラリ内のputs関数を例としてPLT経由のGOTの間接参照のしくみを説明する概念図である。
図6に示すように、共有ライブラリ内の関数の呼び出しは、アセンブリプログラムにおいて、「call PLTの当該関数のアドレス解決のための命令群の先頭アドレス <(当該関数名)@plt>」(図6では、call 80482a8 <puts@plt>)と記述される。この命令の参照先には、jmp命令があり、ジャンプ先として当該関数のGOTスロットが参照する値にさらにジャンプする。図6の例では、「アドレス0x804955c(GOTスロット:GOTの0x804955cを指示)で参照するアドレス(PLT解決アドレス:PLTの80482ae)にジャンプせよ」との命令となっている。
当該関数のGOTスロットの初期値は、PLTの当該関数について記述された領域の2行目の命令(PLT解決アドレス:図6では、PLTの80482ae)となっている。このPLT解決アドレスはアドレス解決のための小さなコードの先頭である。当該関数が初めて呼び出されると、当該関数のアドレスを解決する処理に移る。この処理は、当該関数のアドレスを取得した後、GOTスロットの値(図6では、PLTの80482ae)を取得した当該関数の絶対アドレス(関数アドレス:図6では、putsのアドレス)に書き換える。これにより、当該関数の2回目の呼び出し以降は、PLT経由でGOTスロットに設定された当該関数の絶対アドレスを直接参照することで当該関数(図6では、puts)を呼び出すことができる。以上が遅延リンクの仕組みである。
上述の通り、遅延リンクの正常な動作において、GOTスロットが参照する値は、PLT解決アドレスもしくは関数アドレスのいずれかを取る。
図3に戻り、情報取得ブロックB10で行う処理を説明する。GOTスロット取得処理(S303)から関数アドレス取得処理(S309)までは、情報取得ブロックB10で行う処理である。これらの処理によって攻撃によってGOTが書き換えられたかどうかチェックするために必要な情報を取得する。
表4及び表5は、以降の説明理解を容易とするために、情報取得ブロックB10で行う処理によって取得される情報の例を模式的に表に示したものである。

表4は、変換対象プログラムのELFヘッダのエントリポイントに記述された値が絶対アドレスの場合の例である。エントリポイントアドレス≧0x0400000の場合が相当する。表4は、変換対象プログラムが実行可能ファイルの場合で、標準関数printf、自作関数myadd、及び、自作関数mycalcを呼び出す例である。表4の関数名の欄には呼び出される関数の名前が、共有ライブラリフルパスの欄には関数が格納されている共有ライブラリのフルパスが、関数アドレスの欄には関数の開始位置を示すアドレス(関数アドレス)が、GOTスロットの欄には当該関数のGOTスロットが、PLT解決用絶対アドレスの欄にはPLTに記述されている遅延リンクの際に関数の開始位置を示すアドレスを解決するための命令群の先頭アドレス(PLT解決アドレス)が、それぞれ記述されている。また、網掛けの部分は相対アドレスであり、その他の部分は絶対アドレスが記述されている。変換対象プログラムが絶対アドレスでロードされるので、当該PLTとGOTも絶対アドレスとなる。
表5は、変換対象プログラムのELFヘッダのエントリポイントに記述された値が相対アドレスの場合の例である。エントリポイントアドレス<0x0400000の場合が相当する。表5は、変換対象プログラム自体が自作の共有ライブラリmylib1.so.1.0の場合であり、標準関数printf、及び、自作関数mycalcを呼び出す例である。表5の関数名の欄には呼び出される関数の名前が、共有ライブラリフルパスの欄には関数が格納されている共有ライブラリのフルパスが、関数アドレスの欄には関数アドレスが、GOTスロットが、PLTアドレス解決用オフセットの欄にはPLT解決アドレスが、それぞれ記述されている。また、網掛けの部分は相対アドレスであり、その他の部分は絶対アドレスが記述されている。
図3に示すフローチャートで、GOTスロット取得処理(S303)から説明する。
GOTスロット取得部110が、GOTスロット取得処理(S303)を行う。GOTスロット取得処理(S303)では、GOTスロットを変換対象プログラムに問い合わせ、取得して、保持する。GOT上書き攻撃を受けた場合にはGOTスロットが参照する値が変わることから、GOT上書き攻撃有無の判定対象とするためにGOTスロットを取得する。
GOTスロット取得部110が、objdump命令により変換対象プログラムに問い合わせて、GOTスロットを取得して、保持する。表4及び表5のGOTスロットの欄に記述された値である。変換対象プログラムのELFヘッダのエントリポイントに記述された値が絶対アドレスの場合(表4)には絶対アドレスと、変換対象プログラムのELFヘッダのエントリポイントに記述された値が相対アドレスの場合(表5)には相対アドレスとなる。すべての変換対象プログラムについてS303の処理が終了すると、GOT書き込み可否判定処理(S305)に移行する。
GOT書き込み可否判定部120が、GOT書き込み可否判定処理(S305)を行う。GOT書き込み可否判定処理(S305)では、変換対象プログラムに存在するGOTが書き込み可能かどうかを判定する。GOTが書き込み可能な場合に、GOT上書き攻撃を受ける可能性があるためである。
GOT書き込み可否の判定は、例えば、コンパイラでGCCを利用する場合であれば、調査対象プログラムのELFヘッダにGNU_RELRO及びBIND_NOWの文字列が含まれている場合にはGOTは書き込み不可であると判定する。
S305の処理が終了すると、GOT書き込み可と判定された場合にはPLT解決アドレス取得処理(S307)に、GOT書き込み不可と判定された場合には情報取得ブロック(B10)での処理を終えてS317の処理に移行する。
GOT書き込み可否判定処理(S305)でGOT書き込み可と判定された場合に、PLT解決アドレス取得処理(S307)では、PLT解決アドレスを変換対象プログラムに問い合わせ、取得して、保持する。
PLT解決アドレス取得部130が、objdump命令により変換対象プログラムに問い合わせて、PLT解決アドレスを取得して、保持する。表4のPLTアドレス解決用絶対アドレス、並びに、表5のPLTアドレス解決用オフセットの欄に記述された値である。変換対象プログラムのELFヘッダのエントリポイントに記述された値が絶対アドレスの場合(表4)には絶対アドレスと、変換対象プログラムのELFヘッダのエントリポイントに記述された値が相対アドレスの場合(表5)には相対アドレスとなる。すべての変換対象プログラムについてS307の処理が終了すると、関数アドレス取得処理(S309)に移行する。
GOT書き込み可否判定処理(S305)でGOT書き込み可と判定された場合に、関数アドレス取得処理(S309)では、関数アドレスを共有ライブラリに問い合わせ、取得して、保持する。
関数アドレス取得部140が、nm命令により共有ライブラリに問い合わせて、関数アドレスを取得して、保持する。表4及び表5の関数アドレスの欄に記述された値である。共有ライブラリのELFヘッダのエントリポイントに記述された値が相対アドレスの場合は位置独立コード化された共有ライブラリであって、この共有ライブラリ内の関数(例えば、myaddやmycalc)では関数アドレスは相対アドレスをとる。共有ライブラリのELFヘッダのエントリポイントに記述された値が絶対アドレスの場合は、標準関数(例えば、printf)などであって関数アドレスは絶対アドレスをとる。すべての共有ライブラリについてS309の処理が終了すると命令生成処理ブロック(B20)に移行する。
情報取得処理ブロック(B10)が終了すると、変換対象プログラムで呼び出される関数について、表4または表5に記述された情報が保持された状態となる。情報は、記憶装置に記憶するなどして保持する。
命令生成挿入ブロック(B20)は、GOT書き込み可否判定処理(S305)でGOT書き込み可と判定された場合に機能するPLTチェック命令生成挿入部150と関数アドレス命令生成挿入部160、関数別ジャンプ命令生成挿入部170及び、GOT書き込み不可と判定された場合に機能する関数別ジャンプ命令生成挿入部170からなる。まず、GOT書き込み可と判定された場合について説明をすすめ、次にGOT書き込み不可と判定された場合についての説明を行う。
図7は、GOT書き込み可の場合に、GOTスロットが参照する値が適正か否かを判定するアルゴリズムを示した図である。F71で示す部分をPLTチェック命令生成挿入部150が生成した命令が実施する。F73で示す部分を関数アドレス命令生成挿入部160が生成した命令が実施する。図7で、判定結果がOKの場合は処理を継続し、NGの場合はGOTが不正に書き換えられたと判定してプログラムの実行を停止する。図7で示すアルゴリズムの各判定ステップは次の通りである。
S701 変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスか相対アドレスか判定する。
S703 S701の処理で絶対アドレスと判定された場合に、PLT解決アドレスと、GOTスロットが参照する値とを対比して、値が一致するか判定する。
S705 S701の処理で相対アドレスと判定された場合に、変換対象プログラムの開始位置を示す絶対アドレスとPLT解決アドレスとを加算して得られる絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとGOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致するか判定する。
S707 S703の処理で値が一致しないと判定された場合に、共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスか相対アドレスか判定する。
S709 S707の処理で絶対アドレスと判定された場合に、関数アドレスと、GOTスロットが参照する値とを対比して、値が一致するか判定する。
S711 S707の処理で相対アドレスと判定された場合に、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる絶対アドレスと、GOTスロットが参照する値とを対比して、値が一致するか判定する。
S713 S705の処理で値が一致しないと判定された場合に、共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスか相対アドレスか判定する。
S715 S713の処理で絶対アドレスと判定された場合に、関数アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとGOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致するか判定する。
S717 S713の処理で相対アドレスと判定された場合に、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとGOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致するか判定する。
次に、PLTチェック命令生成挿入部150と関数アドレス命令生成挿入部160の動作を説明する。PLTチェック命令生成挿入部150と関数アドレス命令生成挿入部160は、前述の図7に示すアルゴリズムを実行するプログラムを生成し、変換対象プログラムに挿入する。
GOT書き込み可否判定処理(S305)でGOT書き込み可と判定された場合、図3のS311の処理で示すように変換対象プログラムのすべてのソースファイルについてチェック命令生成挿入処理(S315)を行う。チェック命令生成挿入処理(S315)はアセンブリで行うため、ソースコードは事前にアセンブリに変換(S313)する。
チェック命令生成挿入処理(S315)は、PLTチェック命令生成挿入部150が行うPLTチェック命令生成挿入処理(S805A及びS805B)と関数チェック命令生成挿入部160が行う関数チェック命令生成挿入処理(S1107A、S1107B、S1107C及びS1107D)で構成される。
図8は、チェック命令生成挿入処理(S315)について示すフローチャートである。S801の処理は、変換対象プログラムで呼び出されるすべての関数について順次処理を行う。
S803の処理は、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスの場合と相対アドレスの場合で場合分けする。それぞれの場合によって次に行うPLTチェック命令生成挿入処理が異なるためである。変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定された場合にはPLTチェック命令生成挿入処理A(S805A)に、相対アドレスと判定された場合にはチェック命令生成挿入処理B(S805B)に移行する。
S803の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定された場合、PLTチェック命令生成挿入部150がPLTチェック命令生成挿入処理A(S805A)を行う。PLTチェック命令生成挿入処理A(S805A)では、PLT解決アドレスと、GOTスロットが参照する値とを対比して、値が一致しなければ関数アドレスチェック命令生成挿入部160が生成した命令(関数アドレスチェック命令)に引き渡してチェック処理を継続し、値が一致したならば関数別ジャンプ命令生成挿入部170が生成した命令(関数別ジャンプ命令)に引き渡して処理を継続する命令を、生成して、変換対象プログラムに挿入する。変換対象プログラムへの挿入は、生成した命令を、アセンブラに変換された変換対象プログラムのソースコードの冒頭に記述し、ラベルを付与することで分岐元から分岐できるようにする。
S803の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定された場合とは、表4に示される場合である。関数が含まれる共有ライブラリが位置独立コード化されているかどうかによらず、PLT解決アドレス及びGOTスロットのいずれも絶対アドレスである。このことから、PLT解決アドレスと、GOTスロットが参照する値とを対比して、値が一致しなければGOTが攻撃によって書き換えられた可能性があると判定する。
図9は、変換対象プログラムの実行時に、PLTチェック命令生成挿入処理A(S805A)で生成された命令(PLTチェック命令A)が実行された際の動作を示すフローチャートである。
S901の処理では、レジスタAにGOTスロットが参照する値を転送する。S901の処理が終了するとS903の処理に移行する。
S903の処理では、レジスタBにPLT解決アドレスを転送する。S903の処理が終了するとS905の処理に移行する。
S905の処理では、レジスタAとレジスタBの値を対比する。値が一致しなければS907の処理に、値が一致すればS909の処理に移行する。
S907の処理では、関数アドレスチェック命令に引き渡してチェック処理を継続する。また、S909の処理では、関数別ジャンプ命令に引き渡して処理を継続する。
図8に戻り、S803の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスと判定された場合、PLTチェック命令生成挿入部150がPLTチェック命令生成挿入処理B(S805B)を行う。PLTチェック命令生成挿入処理B(S805B)では、変換対象プログラムの開始位置を示す絶対アドレスとPLT解決アドレスとを加算して得られる絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとGOTスロットとを加算した結果であるアドレスが参照する値とを対比して値が一致しなければ関数アドレスチェック命令生成挿入部160が生成した命令(関数アドレスチェック命令)に引き渡してチェック処理を継続し、値が一致したならば関数別ジャンプ命令生成挿入部170が生成した命令(関数別ジャンプ命令)に引き渡して処理を継続する命令を、生成して、変換対象プログラムに挿入する。変換対象プログラムへの挿入は、生成した命令を、アセンブラに変換された変換対象プログラムのソースコードの冒頭に記述し、ラベルを付与することで分岐元から分岐できるようにする。共有ライブラリの開始位置を示す絶対アドレスは、変換対象プログラムの実行開始直後に、ロードアドレス算出命令生成挿入処理(S301)が生成した命令が実行されることで取得する。(表3を参照)
S803の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスと判定された場合とは、表5に示される場合である。この場合は、PLT解決アドレス及びGOTスロットのいずれも相対アドレスであってオフセットとなる。このことから、変換対象プログラムの開始位置を示す絶対アドレスとPLT解決アドレスとを加算して得られる絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとGOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致しなければGOTが攻撃によって書き換えられた可能性があると判定する。
図10は、変換対象プログラムの実行時に、PLTチェック命令生成処理B(S805B)で生成された命令(PLTチェック命令B)が実行された際の動作を示すフローチャートである。
S1001の処理では、ロードアドレス格納変数に格納されているロードアドレス算出命令生成挿入部(S301)で生成した命令が実行されることで算出された変換対象プログラムの開始アドレスを格納した静的変数アドレスを取得する。S1001の処理が終了するとS1003の処理に移行する。
S1003の処理では、レジスタAにS1001の処理で取得したアドレスで間接参照されるアドレスを転送する。S1003の処理が終了するとS1005の処理に移行する。
S1005の処理では、レジスタBにGOTスロットを転送する。S1005の処理が終了するとS1007の処理に移行する。
S1007の処理では、レジスタAの値とレジスタBの値を加算してレジスタBに転送する。S1007の処理が終了するとS1009の処理に移行する。
S1009の処理では、レジスタCにPLT解決アドレスを転送する。S1009の処理が終了するとS1011の処理に移行する。
S1011の処理では、レジスタAの値とレジスタCの値を加算してレジスタCに転送する。S1011の処理が終了するとS1013の処理に移行する。
S1013の処理では、レジスタBの参照する値とレジスタCの値を対比する。値が一致しなければS1015の処理に、値が一致すればS1017の処理に移行する。
S1015の処理では、関数アドレスチェック命令に引き渡してチェック処理を継続する。また、S1017の処理では、関数別ジャンプ命令に引き渡して処理を継続する。
図8に戻り、関数アドレスチェック命令生成挿入処理(S807)について説明する。図11は、関数アドレスチェック命令生成挿入処理(S807)について示したフローチャートである。
S1101、S1103及びS1105の処理は、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスの場合と相対アドレスの場合、変換対象プログラムに呼び出される関数が含まれる共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスの場合と相対アドレスの場合、それぞれの組合せでその後の処理を4つに場合分けする。それぞれの場合によって次に行う関数アドレスチェック命令生成挿入処理が異なるためである。
S1101の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定され、S1103の処理で共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスと判定された場合、関数アドレスチェック命令生成挿入部160は関数アドレスチェック命令生成挿入処理A(S1107A)を行う。関数アドレスチェック命令生成挿入処理A(S1107A)では、関数アドレスと、GOTスロットが参照する値とを対比して、値が一致しなければ変換対象プログラムを終了させ、値が一致したならば関数別ジャンプ命令生成挿入部170が生成した命令(関数別ジャンプ命令)に分岐する命令を、生成して、変換対象プログラムに挿入する。変換対象プログラムへの挿入は、生成した命令を、アセンブラに変換された変換対象プログラムのソースコードの冒頭に記述し、ラベルを付与することで分岐元から分岐できるようにする。
S1101の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定され、S1103の処理で共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスと判定された場合とは、例えば表4に示されるprintf関数の場合である。GOTスロットも絶対アドレスである。また、関数が含まれる共有ライブラリが位置独立コード化されておらず関数アドレスも絶対アドレスである。このことから、関数アドレスと、GOTスロットが参照する値とを直接に対比して、値が一致しなければGOTが攻撃によって書き換えられた可能性があると判定する。
図12は、変換対象プログラムの実行時に、関数アドレスチェック命令生成挿入処理A(S1107A)で生成された命令(関数アドレスチェック命令A)が実行された際の動作を示すフローチャートである。
S1201の処理では、レジスタAにGOTスロットが参照する値を転送する。S1201の処理が終了するとS1203の処理に移行する。
S1203の処理では、レジスタBに関数アドレスを転送する。S1203の処理が終了するとS1205の処理に移行する。
S1205の処理では、レジスタAの値とレジスタBの値を対比する。値が一致しなければS1207の処理に、値が一致すればS1209の処理に移行する。
S1207の処理では、当該関数の呼出命令を中止する命令を出力する。また、S1209の処理では、関数別ジャンプ命令に分岐して処理を継続する。
図11に戻り、S1101の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定され、S1103の処理で共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスと判定された場合、関数アドレスチェック命令生成挿入部160は関数アドレスチェック命令生成挿入処理B(S1107B)を行う。関数アドレスチェック命令生成挿入処理B(S1107B)では、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる絶対アドレスと、GOTスロットが参照する値とを対比して、値が一致しなければ変換対象プログラムを終了させ、値が一致したならば関数別ジャンプ命令生成挿入部170が生成した命令(関数別ジャンプ命令)に分岐する命令を、生成して、変換対象プログラムに挿入する。変換対象プログラムへの挿入は、生成した命令を、アセンブラに変換された変換対象プログラムのソースコードの冒頭に記述し、ラベルを付与することで分岐元から分岐できるようにする。共有ライブラリの開始位置を示す絶対アドレスは、変換対象プログラムの実行開始直後に、ロードアドレス算出命令生成挿入処理(S301)が生成した命令が実行されることで取得する。(表3を参照)
S1101の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定され、S1103の処理で共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスと判定された場合とは、例えば表4に示されるmyadd関数やmycalc関数の場合である。GOTスロットは絶対アドレスである。また、関数が含まれる共有ライブラリが位置独立コード化されており関数アドレスは相対アドレスであってオフセットである。このことから、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる絶対アドレスと、GOTスロットが参照する値とを対比して、値が一致しなければGOTが攻撃によって書き換えられた可能性があると判定する。
図13は、変換対象プログラムの実行時に、関数アドレスチェック命令生成処理B(S1107B)で生成された命令(関数アドレスチェック命令B)が実行された際の動作を示すフローチャートである。
S1301の処理では、ロードアドレス格納変数に格納されているロードアドレス算出命令生成挿入部(S301)で生成した命令が実行されることで算出された共有ライブラリの開始アドレスを格納した静的変数アドレスを取得する。S1301の処理が終了するとS1303の処理に移行する。
S1303の処理では、レジスタAにS1301の処理で取得したアドレスで間接参照されるアドレスを転送する。S1303の処理が終了するとS1305の処理に移行する。
S1305の処理では、レジスタBにGOTスロットが参照する値を転送する。S1305の処理が終了するとS1307の処理に移行する。
S1307の処理では、レジスタCに関数アドレスを転送する。S1307の処理が終了するとS1309の処理に移行する。
S1309の処理では、レジスタAの値とレジスタCの値を加算してレジスタCに転送する。S1309の処理が終了するとS1311の処理に移行する。
S1311の処理では、レジスタBの値とレジスタCの値を対比する。値が一致しなければS1313の処理に、値が一致すればS1315の処理に移行する。
S1313の処理では、当該関数の呼出命令を中止する命令を出力する。また、S1315の処理では、関数別ジャンプ命令に分岐して処理を継続する。
図11に戻り、S1101の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスと判定され、S1105の処理で共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスと判定された場合、関数アドレスチェック命令生成挿入部160は関数アドレスチェック命令生成挿入処理C(S1107C)を行う。関数アドレスチェック命令生成挿入処理C(S1107C)では、関数アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとGOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致しなければ変換対象プログラムを終了させ、値が一致したならば関数別ジャンプ命令生成挿入部170が生成した命令(関数別ジャンプ命令)に分岐する命令を、生成して、変換対象プログラムに挿入する。変換対象プログラムへの挿入は、生成した命令を、アセンブラに変換された変換対象プログラムのソースコードの冒頭に記述し、ラベルを付与することで分岐元から分岐できるようにする。変換対象プログラムの開始位置を示す絶対アドレスは、変換対象プログラムの実行開始直後に、ロードアドレス算出命令生成挿入処理(S301)が生成した命令が実行されることで取得する。(表3を参照)
S1101の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスと判定され、S1105の処理で共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスと判定された場合とは、例えば表5に示されるprintf関数の場合である。GOTスロットは相対アドレスであってオフセットである。一方、関数が含まれる共有ライブラリが位置独立コード化されておらず関数アドレスは絶対アドレスである。このことから、関数アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとGOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致しなければGOTが攻撃によって書き換えられた可能性があると判定する。
図14は、変換対象プログラムの実行時に、関数アドレスチェック命令生成処理C(S1107C)で生成された命令(関数アドレスチェック命令C)が実行された際の動作を示すフローチャートである。
S1401の処理では、ロードアドレス格納変数に格納されているロードアドレス算出命令生成挿入部(S301)で生成した命令が実行されることで算出された変換対象プログラムの開始アドレスを格納した静的変数アドレスを取得する。S1401の処理が終了するとS1403の処理に移行する。
S1403の処理では、レジスタAにS1401の処理で取得したアドレスで間接参照されるアドレスを転送する。S1403の処理が終了するとS1405の処理に移行する。
S1405の処理では、レジスタBにGOTスロットを転送する。S1405の処理が終了するとS1407の処理に移行する。
S1407の処理では、レジスタAの値とレジスタBの値を加算してレジスタBに転送する。S1407の処理が終了するとS1409の処理に移行する。
S1409の処理では、レジスタCに関数アドレスを転送する。S1409の処理が終了するとS1411の処理に移行する。
S1411の処理では、レジスタBの参照する値とレジスタCの値を対比する。値が一致しなければS1413の処理に、値が一致すればS1415の処理に移行する。
S1415の処理では、当該関数の呼出命令を中止する命令を出力する。また、S1417の処理では、関数別ジャンプ命令に分岐して処理を継続する。
図11に戻り、S1101の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスと判定され、S1105の処理で共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスと判定された場合、関数アドレスチェック命令生成挿入部160は関数アドレスチェック命令生成挿入処理D(S1107D)を行う。関数アドレスチェック命令生成挿入処理D(S1107D)では、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとGOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致しなければ変換対象プログラムを終了させ、値が一致したならば関数別ジャンプ命令生成挿入部170が生成した命令(関数別ジャンプ命令)に分岐する命令を、生成して、変換対象プログラムに挿入する。変換対象プログラムへの挿入は、生成した命令を、アセンブラに変換された変換対象プログラムのソースコードの冒頭に記述し、ラベルを付与することで分岐元から分岐できるようにする。変換対象プログラムと共有ライブラリの開始位置を示す絶対アドレスは、変換対象プログラムの実行開始直後に、ロードアドレス算出命令生成挿入処理(S301)が生成した命令が実行されることで取得する。(表3を参照)
S1101の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスと判定され、S1105の処理で共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスと判定された場合とは、例えば表5に示されるmycalc関数の場合である。GOTスロットは相対アドレスであってオフセットである。また、関数が含まれる共有ライブラリが位置独立コード化されており関数アドレスも相対アドレスであってオフセットである。このことから、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとGOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致しなければGOTが攻撃によって書き換えられた可能性があると判定する。
図15は、変換対象プログラムの実行時に、関数アドレスチェック命令生成処理D(S1107D)で生成された命令(関数アドレスチェック命令D)が実行された際の動作を示すフローチャートである。
S1501の処理では、ロードアドレス格納変数に格納されているロードアドレス算出命令生成挿入部(S301)で生成した命令が実行されることで算出された変換対象プログラムと共有ライブラリの開始アドレスを格納した静的変数アドレスを取得する。S1501の処理が終了するとS1503の処理に移行する。
S1503の処理では、レジスタAにS1501の処理で取得したアドレスで間接参照される変換対象プログラムの開始アドレスを、レジスタBにS1501の処理で取得したアドレスで間接参照される共有ライブラリの開始アドレスを転送する。S1503の処理が終了するとS1505の処理に移行する。
S1505の処理では、レジスタCにGOTスロットを転送する。S1505の処理が終了するとS1507の処理に移行する。
S1507の処理では、レジスタAの値とレジスタCの値を加算してレジスタCに転送する。S1507の処理が終了するとS1509の処理に移行する。
S1509の処理では、レジスタDに関数アドレスを転送する。S1509の処理が終了するとS1511の処理に移行する。
S1511の処理では、レジスタBの値とレジスタDの値を加算してレジスタDに転送する。S1511の処理が終了するとS1513の処理に移行する。
S1513の処理では、レジスタCの参照する値とレジスタDの値を対比する。値が一致しなければS1515の処理に、値が一致すればS1517の処理に移行する。
S1515の処理では、当該関数の呼出命令を中止する命令を出力する。また、S1517の処理では、関数別ジャンプ命令に分岐して処理を継続する。
図3に戻り、GOT書き込み可否判定処理(S305)でGOT書き込み不可と判定された場合、GOTに不正な書き込みが行われたかどうかのチェックを行う必要はない。S317の処理で示すように変換対象プログラムのすべてのソースファイルについて関数別ジャンプ命令生成挿入処理(S319)を行う。関数別ジャンプ命令生成挿入処理(S319)はアセンブリで行うため、ソースコードは事前にアセンブリに変換(S321)する。
関数別ジャンプ命令生成挿入部170が、関数別ジャンプ命令生成挿入処理(S319)を行う。関数別ジャンプ命令生成挿入処理(S319)では、関数別ジャンプ命令を、生成して、変換対象プログラムに挿入する。
関数別ジャンプ命令は、GOT書き込み可否判定処理(S305)でGOTが書き込み可能と判定され、関数アドレスチェック命令生成挿入処理で変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定(S1101)され、共用ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスと判定(S1103)された場合には、関数アドレスチェック命令生成挿入部160で、GOTスロットが参照する値を格納したレジスタの値に分岐する命令、それ以外の場合には、本来のPLT経由で当該関数をコールする命令である。なお、ここでGOTスロットが参照する値を格納したレジスタの値に分岐する命令は、ジャンプ命令であってもよいし、GOTスロットが参照する値を格納したレジスタの値を関数アドレスとしてコールする命令であってもよい。
命令生成挿入ブロック(B20)での処理を終えた関数について、アセンブラに変換されたソースコードの冒頭に、PLTチェック命令と関数アドレスチェック命令、及び、関数別ジャンプ命令が挿入された状態となる。
命令書き換えブロック(B30)は、コール命令書き換え処理(S323)を行うコール命令書き換え部180とリターン命令書き換え処理(S325)を行うリターン命令書き換え部190からなる。
本実施形態の環境においてはコール命令によって関数が呼び出される。コール命令は関数を呼び出す際に、この関数呼び出しの次の命令をリターンアドレスとしてスタックに格納する。その後、関数の処理完了時にリターン命令によって、スタックに格納したリターンアドレスに戻る処理を行う。しかしながら、関数の処理中にスタックに格納したリターンアドレスがバッファオーバーフロー攻撃などによって書き換えられる恐れがある。そこで、本実施形態では、命令書き換えブロック(B30)で、リターンアドレスを計算してレジスタに格納し、GOTが書き込み可能な場合には当該関数に対応するPLTチェック命令に、GOTが書き込み禁止の場合には当該関数に対応する関数別ジャンプ命令に、ジャンプする命令に関数のコール命令を書き換え、ジャンプ先の関数の処理完了後にレジスタに格納してある値にジャンプし、適正なリターンアドレスに戻るようにすることでバッファオーバーフロー攻撃などから回避する。
コール命令書き換え部180が、コール命令書き換え処理(S323)を行う。コール命令書き換え処理(S323)では、変換対象であるアセンブリプログラムを一行ずつ読み込んで「call」の文字列を発見することで関数を呼び出すためのコール命令を検出して、検出したコール命令を次に示す一連の処理を行う命令に書き換える。書き換えられた命令は、まず、レジスタをスタックに退避した後にリターンアドレスを再計算してレジスタに格納し、次に、GOTが書き込み可能な場合には当該関数に対応するPLTチェック命令へ、GOTが書き込み禁止の場合には当該関数に対応する関数別ジャンプ命令へ分岐し、関数の処理完了後に前記レジスタにスタックから復帰させる処理を行う。これにより、変換対象プログラムが共有ライブラリの関数を呼び出した際に命令生成ブロック(B20)で生成したチェック命令が動作する。また、チェック命令によりアドレスが適性であると判定された場合は前記レジスタに格納されたリターンアドレスに復帰する。
リターン命令書き換え部190が、リターン命令書き換え処理(S325)を行う。リターン命令書き換え処理(S325)では、まず、変換対象であるアセンブリプログラムを一行ずつ読み込んで「ret」の文字列を発見することでリターン命令を検出する。検出したリターン命令をコール命令書き換え部180でレジスタに格納しているアドレスに分岐する命令に書き換える。リターン命令書き換え処理(S325)により、リターンアドレスを書き換える攻撃を回避する。
命令生成ブロック(B20)及び命令書き換えブロック(B30)の処理が変換対象プログラムにロジックを追加することによる取得するアドレスの変更に対応するため、変換装置10は変換対象プログラムのリコンパイルを行い、アドレス更新のために再度、命令生成ブロック(B20)及び命令書き換えブロック(B30)の処理を行う。
次に、コンピュータシステムを変換装置10として機能させるための変換プログラムについて説明する。コンピュータシステムの構成は、図2に示す通りである。
変換プログラムは、メインモジュール、入力モジュール、出力モジュール及び演算処理モジュールを備える。メインモジュールは変換処理を統括的に制御する部分である。入力モジュールは変換対象のプログラムの入力を、出力モジュールは変換後のプログラムの出力をするようにコンピュータシステムを動作させる。演算処理モジュールは、ロードアドレス算出命令生成挿入モジュール、GOTスロット取得モジュール、GOT書き込み可否判定モジュール、PLT解決アドレス取得モジュール、関数アドレス取得モジュール、PLTチェック命令生成挿入モジュール、関数アドレスチェック命令生成挿入モジュール、関数別ジャンプ命令生成挿入モジュール、コール命令書き換えモジュール及びリターン命令書き換えモジュールを備える。メインモジュール、入力モジュール、出力モジュール及び演算処理モジュールを実行させることにより実現される機能は、変換装置10のロードアドレス算出命令生成挿入部100、GOTスロット取得部110、GOT書き込み可否判定部120、PLT解決アドレス取得部130、関数アドレス取得部140、PLTチェック命令生成挿入部150、関数アドレスチェック命令生成挿入部160、関数別ジャンプ命令生成挿入部170、コール命令書き換え部180及びリターン命令書き換え部190の機能とそれぞれ同様である。
(第2実施形態)
本実施形態に係る変換装置は、攻撃を検知して停止するようにプログラムを変換する変換装置である。第1実施形態が、ロードアドレス算出命令生成挿入部100は変換対象プログラム及び共有ライブラリの開始アドレスを静的変数に格納することで保持するプログラムを生成するのに対して、本実施形態は、ロードアドレス算出命令生成挿入部100は、変換対象プログラム及び共有ライブラリの開始アドレスを低い順に1つの文字列に連結してファイルに出力し、このファイルに記載された文字列を読み込み可能、書き込み不可としてプロセス空間に新たなメモリ領域として保存し、このメモリ領域の開始アドレスを静的変数に格納するプログラムを生成して、変換対象プログラムから呼び出すことができるように変換対象プログラムに挿入する点が相違する。読み取り専用でメモリに書き込むため、第1実施形態よりもセキュアなプログラムへの変換が実現できる。
本実施形態に係る変換装置の構成を示すブロック図及びハードウェア構成は、図1に示すブロック図及び図2に示すハードウェア構成と同様である。第1実施形態と大きく相違するのはロードアドレス算出命令生成挿入部100の動作であるので、この点を中心に説明する。
本実施形態に係る変換装置のロードアドレス算出命令生成挿入部100は、変換対象プログラム及び変換対象プログラムにリンクされるプログラムが実施された直後に、変換対象プログラムの開始アドレス及び変換対象プログラムにリンクされるプログラムの開始アドレスを算出し、アドレスの低い順に1つの文字列に連結してファイルに出力し、このファイルに記載された文字列を読み込み可能、書き込み不可としてプロセス空間に新たなメモリ領域として保存し、このメモリ領域の開始アドレスを静的変数に格納するプログラムを生成する機能を有している。また、生成したプログラムを変換対象プログラムから呼び出すことができるように変換対象プログラムに挿入する機能を有している。
本実施形態に係る変換装置10が、図3に示す動作を開始すると、ロードアドレス算出命令生成挿入部100が、ロードアドレス算出命令生成挿入処理(S301)を行う。ロードアドレス算出命令生成挿入処理(S301)では、変換対象プログラム及び変換対象プログラムにリンクされるプログラムが実施された直後に、変換対象プログラムの開始アドレス及び変換対象プログラムにリンクされるプログラムの開始アドレスを算出し、アドレスの低い順に1つの文字列に連結してファイルに出力し、このファイルに記載された文字列を読み込み可能、書き込み不可としてプロセス空間に新たなメモリ領域として保存し、このメモリ領域の開始アドレスを静的変数に格納するプログラムを生成する処理を行う。次に、生成したプログラムを変換対象プログラムから呼び出すことができるように変換対象プログラムに挿入する処理を行う。
ロードアドレス算出命令生成挿入部100が生成するプログラムの詳細と変換済みのプログラム実行時の動作について説明する。図16は、ロードアドレス算出命令生成挿入部100が生成するプログラムの詳細と変換済みのプログラム実行時の動作を示すフローチャートである。
変換済みのプログラムの実行ファイルからロードアドレス算出命令生成挿入部100が生成するプログラムが呼び出されると現在のプロセスIDを取得する処理(S1601)が実行される。getpid命令でプロセスIDを取得する。S1601の処理が終了するとS1603の処理に移行する。
S1603の処理では、取得したプロセスIDのメモリマップを取得する。メモリマップは/procディレクトリ配下にプロセスIDごとに存在する。S1603の処理が終了するとS1605の処理に移行する。
S1605の処理では、取得したメモリマップからロードされているオブジェクトファイルの開始アドレスの数を取得する。例えば、図4に示すメモリマップの場合4つとなる。S1605の処理が終了すると1507の処理に移行する。
S1607の処理では、ロードされているオブジェクトファイルの開始アドレスを書き込むのに必要なページサイズを計算する。まず、必要メモリ量を求める。OSが64ビットの場合は、(ロードされているオブジェクトファイルの開始アドレスの数)に16を乗じることで求められる。OSが32ビットの場合は、(ロードされているオブジェクトファイルの開始アドレスの数)に8を乗じることで求められる。次に、ページサイズを取得する。システムでのメモリ管理におけるページサイズは、getpagesize命令で取得できる。通常、4096(4kB)である。必要ページサイズは、(必要メモリ量)/(ページサイズ)で余りを繰り上げることで求められる。S1607の処理が終了するとS1609の処理に移行する。
S1609は、r−xp行の開始アドレスを連結した文字列を生成する。後の処理で開始アドレスが復元できるように各開始アドレスのバイト数を統一する。例えば、バイト数については、0を埋めることで16バイトにアドレスを修正する。また、バイト順(エンディアン)はプロセッサやプラットフォームによって異なるため環境にあわせて文字列を生成するようにする。エンディアンの種別についてはELFヘッダに情報が記載されている。S1617の処理が終了するとS1611の処理に移行する。
S1611の処理では、メモリの書き込み開始アドレスから開始アドレスを結合した文字列をmmap関数を使用して読み取り専用で書き込む。
S1613の処理では、静的変数をひとつ定義して、その静的変数にS1611の処理で読み取り専用で文字列を書き込んだメモリ領域の先頭のアドレスを格納する。
図17は、図4に示すメモリマップの場合で例示した図である。各オブジェクトの開始アドレスを16バイトに編集した後にリトルエンディアンで結合した文字列を示している。この文字列を読み取り専用で書き込んだメモリ領域の先頭アドレスが7f07852e1000であり、このアドレスが、ひとつの静的変数(開始アドレス格納変数)start_load_addrに格納されている。
第1実施形態では、図10に示すS1001の処理、図13に示すS1301の処理、図14に示すS1401の処理及び図15に示すS1501の処理で各オブジェクトの開始アドレスを取得するためには各々のオブジェクトごとに定義された開始アドレス格納変数を参照したが、本実施形態では、ひとつの静的変数(開始アドレス格納変数)を参照する点が相違する。開始アドレス格納変数で指示されるメモリ領域に読み込み専用で書き込まれた文字列の先頭から16バイトごとに各々のオブジェクトの開始アドレスが記述されているので、目的の位置から文字列を読み込むことで目的とするオブジェクトの開始アドレスを取得することができる。
第1実施形態では、開始アドレス格納変数がオブジェクトの数だけ定義されるのに対して、本実施形態で定義する静的変数はひとつであることから、よりセキュアなプログラムへの変換を実現できる。また、静的変数によって指示されるメモリ領域に書き込まれた開始アドレスを連結した文字列は読み取り専用であるために書き換えられることがないことから、第1実施形態と比べて本実施形態は、よりセキュアなプログラムへの変換を実現できる。
変換対象のプログラムが起動時に、静的変数に格納された開始アドレスを連結した文字列を書き込んだメモリ領域の開始アドレスをレジスタに格納するように、更にプログラムを変換するようにしてもよい。これにより変換対象のプログラムが起動後に当該静的変数の値が攻撃によって書き換えられた場合などにもリスクを回避することができ、よりセキュアなプログラムへの変換を実現できる。
10 変換装置
100 ロードアドレス算出命令生成挿入部
110 GOTスロット取得部
120 GOT書き込み可否判定部
130 PLT解決アドレス取得部生成部
140 関数アドレス取得部
150 PLTチェック命令生成挿入部
160 関数アドレスチェック命令生成挿入部
170 関数別ジャンプ命令生成挿入部
180 コール命令書き換え部
190 リターン命令書き換え部
B10 情報取得ブロック
B20 命令生成挿入ブロック
B30 命令書き換えブロック
20 ハードウェア構成
210 中央演算装置(CPU)
220 入力装置
230 出力装置
240 主記憶装置(RAM/ROM)
250 補助記憶装置
260 複数のレジスタ

Claims (4)

  1. 攻撃を検知して停止するようにプログラムを変換する変換装置であって、
    変換対象プログラムの実行開始直後に、前記変換対象プログラムの開始アドレス及び前記変換対象プログラムにリンクされる共有ライブラリの開始アドレスを算出し、静的変数に格納するプログラムを生成して、前記変換対象プログラムから、このプログラムを呼び出すことができるように前記変換対象プログラムに挿入する、ロードアドレス算出命令生成挿入部と、
    前記共有ライブラリ内の関数を呼び出す際に前記変換対象プログラムに存在する前記関数のプロシージャリンケージテーブルから特定されるグローバルオフセットテーブル中の前記関数のスロット(以下、GOTスロット)を、前記変換対象プログラムに問い合わせ、取得して、保持するGOTスロット取得部と、
    前記変換対象プログラムに存在するグローバルオフセットテーブルが書き込み可能かどうかを判定するGOT書き込み可否判定部と、
    グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムに存在するプロシージャリンケージテーブルに記述されている遅延リンクの際に前記関数のアドレスを解決するための命令群の先頭アドレス(以下、PLT解決アドレス)を、前記変換対象プログラムに問い合わせ、取得して、保持するPLT解決アドレス取得部と、
    グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムから呼び出される前記関数本体の先頭アドレス(以下、関数アドレス)を、前記共有ライブラリに問い合わせ、取得して、保持する関数アドレス取得部と、
    グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記PLT解決アドレスと、前記GOTスロットが参照する値とを対比して、前記変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記変換対象プログラムの開始位置を示す絶対アドレスと前記PLT解決アドレスとを加算して得られる絶対アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記GOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば関数別ジャンプ命令生成挿入部が生成した命令に引き渡す命令を、値が一致していなければ関数アドレスチェック命令生成挿入部に引き渡す命令を、生成して、前記変換対象プログラムに挿入する、PLTチェック命令生成挿入部と、
    グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合であって、前記共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記関数アドレスと、前記GOTスロットが参照する値とを対比して、前記共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記共有ライブラリの開始位置を示す絶対アドレスと前記関数アドレスとを加算して得られる前記関数の開始位置を示す絶対アドレスと、前記GOTスロットが参照する値とを対比して、前記変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合であって、前記共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記関数アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記GOTスロットとを加算した結果であるアドレスが参照する値とを対比して、前記共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記共有ライブラリの開始位置を示す絶対アドレスと前記関数アドレスとを加算して得られる前記関数の開始位置を示す絶対アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記GOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば関数別ジャンプ命令生成挿入部が生成した命令に引き渡す命令を、値が一致しなければ前記変換対象プログラムを終了させる命令を、生成して、前記変換対象プログラムに挿入する、関数アドレスチェック命令生成挿入部と、
    グローバルオフセットテーブルが書き込み可能であり、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスであり、共用ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、GOTスロットが参照する値に分岐する分岐命令を、それ以外の場合には、プロシージャリンケージテーブル経由で関数をコールする命令を、生成して、前記変換対象プログラムに挿入する、関数別ジャンプ命令生成挿入部と、
    前記変換対象プログラムから前記共有ライブラリ内の関数を呼び出す命令を検出し、検出した前記関数を呼び出す命令を、リターンアドレスを計算して保持した後に、グローバルオフセットテーブルが書き込み可能な場合にはPLTチェック命令生成挿入部が挿入した命令に、グローバルオフセットテーブルが書き込み禁止の場合には関数別ジャンプ命令生成挿入部が挿入した命令に分岐する命令に書き換えるコール命令書き換え部と、
    前記変換対象プログラムからリターン命令を検出し、検出した前記リターン命令を前記計算して保持しているアドレスに分岐する命令に書き換えるリターン命令書き換え部と、
    を備えることを特徴とする変換装置
  2. 前記ロードアドレス算出命令生成挿入部は、変換対象プログラムが実行開始直後に、前記変換対象プログラムの開始アドレス及び前記変換対象プログラムにリンクされる共有ライブラリの開始アドレスを算出し、その算出結果を1つの文字列に連結してファイルに出力し、このファイルに記載された文字列を読み込み可能、書き込み不可としてプロセス空間に新たなメモリ領域として保存し、このメモリ領域の開始アドレスを静的変数に格納するプログラムを生成して、前記変換対象プログラムから、このプログラムを呼び出すことができるように前記変換対象プログラムに挿入する、
    請求項1に記載の変換装置
  3. コンピュータに、
    攻撃を検知して停止するようにプログラムの変換を実行させる変換プログラムであって、
    変換対象プログラムの実行開始直後に、前記変換対象プログラムの開始アドレス及び前記変換対象プログラムにリンクされる共有ライブラリの開始アドレスを算出し、静的変数に格納するプログラムを生成して、前記変換対象プログラムから、このプログラムを呼び出すことができるように前記変換対象プログラムに挿入する、ロードアドレス算出命令生成挿入処理ステップと、
    前記GOTスロットを、前記変換対象プログラムに問い合わせ、取得して、保持するGOTスロット取得処理ステップと、
    前記変換対象プログラムに存在するグローバルオフセットテーブルが書き込み可能かどうかを判定するGOT書き込み可否判定処理ステップと、
    グローバルオフセットテーブルが書き込み可能な場合に、前記PLT解決アドレスを、前記変換対象プログラムに問い合わせ、取得して、保持するPLT解決アドレス取得処理ステップと、
    グローバルオフセットテーブルが書き込み可能な場合に、前記関数アドレスを、前記共有ライブラリに問い合わせ、取得して、保持する関数アドレス取得処理ステップと、
    グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記PLT解決アドレスと、前記GOTスロットが参照する値とを対比して、前記変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記変換対象プログラムの開始位置を示す絶対アドレスと前記PLT解決アドレスとを加算して得られる絶対アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記GOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば、関数別ジャンプ命令生成挿入処理ステップが生成した命令に引き渡す命令を、値が一致していなければ関数アドレスチェック命令生成挿入部に引き渡す命令を、生成して、前記変換対象プログラムに挿入する、PLTチェック命令生成挿入処理ステップと、
    グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合であって、前記共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記関数アドレスと、前記GOTスロットが参照する値とを対比して、前記共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記共有ライブラリの開始位置を示す絶対アドレスと前記関数アドレスとを加算して得られる前記関数の開始位置を示す絶対アドレスと、前記GOTスロットが参照する値とを対比して、前記変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合であって、前記共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記関数アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記GOTスロットとを加算した結果であるアドレスが参照する値とを対比して、前記共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記共有ライブラリの開始位置を示す絶対アドレスと前記関数アドレスとを加算して得られる前記関数の開始位置を示す絶対アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記GOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば関数別ジャンプ命令生成挿入処理ステップが生成した命令に引き渡す命令を、値が一致しなければ前記変換対象プログラムを終了させる命令を、生成して、前記変換対象プログラムに挿入する、関数アドレスチェック命令生成挿入処理ステップと、
    グローバルオフセットテーブルが書き込み可能であり、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスであり、共用ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、GOTスロットが参照する値に分岐する分岐命令を、それ以外の場合には、プロシージャリンケージテーブル経由で関数をコールする命令を、生成して、前記変換対象プログラムに挿入する、関数別ジャンプ命令生成挿入ステップと、
    前記変換対象プログラムから前記共有ライブラリ内の関数を呼び出す命令を検出し、検出した前記関数を呼び出す命令を、リターンアドレスを計算して保持したした後に、グローバルオフセットテーブルが書き込み可能な場合にはPLTチェック命令生成挿入処理ステップが挿入した命令に、グローバルオフセットテーブルが書き込み禁止の場合には関数別ジャンプ命令生成挿入処理ステップが挿入した命令に分岐させる命令に書き換えるコール命令書き換え処理ステップと、
    前記変換対象プログラムからリターン命令を検出し、検出した前記リターン命令を前記計算して保持しているアドレスに分岐する命令に書き換えるリターン命令書き換え処理ステップと、
    を実行させる変換プログラム
  4. 撃を検知して停止するようにプログラムを変換するプログラム変換方法であって、コンピュータが、
    変換対象プログラムの実行開始直後に、前記変換対象プログラムの開始アドレス及び前記変換対象プログラムにリンクされる共有ライブラリの開始アドレスを算出し、静的変数に格納するプログラムを生成して、前記変換対象プログラムから、このプログラムを呼び出すことができるように前記変換対象プログラムに挿入する、ロードアドレス算出命令生成挿入処理ステップと、
    前記GOTスロットを、前記変換対象プログラムに問い合わせ、取得して、保持するGOTスロット取得処理ステップと、
    前記変換対象プログラムに存在するグローバルオフセットテーブルが書き込み可能かどうかを判定するGOT書き込み可否判定処理ステップと、
    グローバルオフセットテーブルが書き込み可能な場合に、前記PLT解決アドレスを、前記変換対象プログラムに問い合わせ、取得して、保持するPLT解決アドレス取得処理ステップと、
    グローバルオフセットテーブルが書き込み可能な場合に、前記関数アドレスを、前記共有ライブラリに問い合わせ、取得して、保持する関数アドレス取得処理ステップと、
    グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記PLT解決アドレスと、前記GOTスロットが参照する値とを対比して、前記変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記変換対象プログラムの開始位置を示す絶対アドレスと前記PLT解決アドレスとを加算して得られる絶対アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記GOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば関数別ジャンプ命令生成挿入手段で生成した命令に引き渡す命令を、値が一致していなければ関数アドレスチェック命令生成挿入部に引き渡す命令を、生成して、前記変換対象プログラムに挿入する、PLTチェック命令生成挿入処理ステップと、
    グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合であって、前記共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記関数アドレスと、前記GOTスロットが参照する値とを対比して、前記共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記共有ライブラリの開始位置を示す絶対アドレスと前記関数アドレスとを加算して得られる前記関数の開始位置を示す絶対アドレスと、前記GOTスロットが参照する値とを対比して、前記変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合であって、前記共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記関数アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記GOTスロットとを加算した結果であるアドレスが参照する値とを対比して、前記共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記共有ライブラリの開始位置を示す絶対アドレスと前記関数アドレスとを加算して得られる前記関数の開始位置を示す絶対アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記GOTスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば関数別ジャンプ命令生成挿入手段で生成した命令に引き渡す命令を、値が一致しなければ前記変換対象プログラムを終了させる命令を、生成して、前記変換対象プログラムに挿入する、関数アドレスチェック命令生成挿入処理ステップと、
    グローバルオフセットテーブルが書き込み可能であり、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスであり、共用ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、GOTスロットが参照する値に分岐する分岐命令を、それ以外の場合には、プロシージャリンケージテーブル経由で関数をコールする命令を、生成して、前記変換対象プログラムに挿入する、関数別ジャンプ命令生成挿入処理ステップと、
    前記変換対象プログラムから前記共有ライブラリ内の関数を呼び出す命令を検出し、検出した前記関数を呼び出す命令を、リターンアドレスを計算して保持した後に、グローバルオフセットテーブルが書き込み可能な場合にはPLTチェック命令生成挿入手段が挿入した命令に、グローバルオフセットテーブルが書き込み禁止の場合には関数別ジャンプ命令生成挿入処理ステップが挿入した命令に分岐させる命令に書き換えるコール命令書き換え処理ステップと、
    前記変換対象プログラムからリターン命令を検出し、検出した前記リターン命令を前記計算して保持しているアドレスに分岐する命令に書き換えるリターン命令書き換え処理ステップと、
    実行するプログラム変換方法
JP2018000920A 2018-01-09 2018-01-09 変換装置、変換プログラム、プログラム変換方法 Active JP6338796B1 (ja)

Priority Applications (1)

Application Number Priority Date Filing Date Title
JP2018000920A JP6338796B1 (ja) 2018-01-09 2018-01-09 変換装置、変換プログラム、プログラム変換方法

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
JP2018000920A JP6338796B1 (ja) 2018-01-09 2018-01-09 変換装置、変換プログラム、プログラム変換方法

Publications (2)

Publication Number Publication Date
JP6338796B1 true JP6338796B1 (ja) 2018-06-06
JP2019121203A JP2019121203A (ja) 2019-07-22

Family

ID=62487363

Family Applications (1)

Application Number Title Priority Date Filing Date
JP2018000920A Active JP6338796B1 (ja) 2018-01-09 2018-01-09 変換装置、変換プログラム、プログラム変換方法

Country Status (1)

Country Link
JP (1) JP6338796B1 (ja)

Cited By (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP6460433B1 (ja) * 2018-08-15 2019-01-30 株式会社Attc 変換装置、変換プログラム、プログラム変換方法
KR20210062438A (ko) * 2019-11-21 2021-05-31 국방과학연구소 컴퓨터 장치 및 컴퓨터 장치의 바이너리 프로그램 실행 속도 측정방법
US11709940B2 (en) 2019-03-18 2023-07-25 Nec Corporation Firmware rewriting apparatus, firmware rewriting method, and non-transitory computer readable medium storing program

Families Citing this family (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
KR102351663B1 (ko) * 2020-02-26 2022-01-17 세종대학교산학협력단 Cfi 기반 got 변조 공격 방지 장치 및 그 방법
JP6827244B1 (ja) * 2020-09-15 2021-02-10 株式会社Attc 監査装置、監査方法、監査プログラムおよび監査システム
KR102713727B1 (ko) * 2021-12-21 2024-10-08 한국전자통신연구원 간접 함수 호출 보호 방법 및 장치

Citations (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP2011008778A (ja) * 2009-05-27 2011-01-13 Ntt Docomo Inc プログラム実行フローの修正を防止する方法及び装置
US20150356294A1 (en) * 2014-06-09 2015-12-10 Lehigh University Methods for enforcing control flow of a computer program

Patent Citations (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP2011008778A (ja) * 2009-05-27 2011-01-13 Ntt Docomo Inc プログラム実行フローの修正を防止する方法及び装置
US20150356294A1 (en) * 2014-06-09 2015-12-10 Lehigh University Methods for enforcing control flow of a computer program

Non-Patent Citations (1)

* Cited by examiner, † Cited by third party
Title
"Security Trend [寄稿]マイクロソフトが脆弱性攻撃の対抗技術", 日経コミュニケーション 2015年3月号, vol. 第614号, JPN6018010276, 1 March 2015 (2015-03-01), JP, pages p.40-p.41 *

Cited By (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP6460433B1 (ja) * 2018-08-15 2019-01-30 株式会社Attc 変換装置、変換プログラム、プログラム変換方法
JP2020027512A (ja) * 2018-08-15 2020-02-20 株式会社Attc 変換装置、変換プログラム、プログラム変換方法
US11709940B2 (en) 2019-03-18 2023-07-25 Nec Corporation Firmware rewriting apparatus, firmware rewriting method, and non-transitory computer readable medium storing program
KR20210062438A (ko) * 2019-11-21 2021-05-31 국방과학연구소 컴퓨터 장치 및 컴퓨터 장치의 바이너리 프로그램 실행 속도 측정방법

Also Published As

Publication number Publication date
JP2019121203A (ja) 2019-07-22

Similar Documents

Publication Publication Date Title
JP6338796B1 (ja) 変換装置、変換プログラム、プログラム変換方法
JP6189039B2 (ja) セキュアドメインおよび低セキュアドメインを使用するデータ処理装置および方法
KR102192880B1 (ko) 소프트웨어 재패키징 방지 방법 및 장치
KR102160916B1 (ko) 안전한 도메인과 덜 안전한 도메인을 이용한 데이터 처리 장치 및 방법
US9336125B2 (en) Systems and methods for hardware-assisted type checking
JP2019516181A (ja) ケイパビリティ・メタデータに対する操作を実施するための装置及び方法
US9489315B2 (en) Method of executing, by a microprocessor, a polymorphic binary code of a predetermined function
US11176060B2 (en) Dynamic memory protection
US7269828B2 (en) Method for safely instrumenting large binary code
CN111222103B (zh) 基于向量化异常处理的软件保护方法
JP4681868B2 (ja) 情報処理装置及びその制御方法、コンピュータプログラム及び記憶媒体
JP5777843B1 (ja) プロセッサ、処理装置、プログラム作成方法
US11113392B2 (en) Executable binary code insertion
JP6460433B1 (ja) 変換装置、変換プログラム、プログラム変換方法
CN107239415B (zh) 一种执行临界区操作的方法及装置
US20060168567A1 (en) Preserving platform independence with native accelerators for performance critical program objects
JP2005165919A (ja) プログラム実行方法、プログラム作成方法、情報処理装置及びプログラム
US9229698B2 (en) Method and apparatus for compiler processing for a function marked with multiple execution spaces
JP2009020695A (ja) 情報処理装置及びシステム
US11055202B1 (en) Compilation scheme for tagged global variables
KR102658588B1 (ko) 처리회로 상에서 실행할 프로그램을 디버깅할 때 메타데이터를 액세스하는 방법
US20230325476A1 (en) Obfuscation device, obfuscation method, and obfuscation program
JP2011164972A (ja) プログラムローダ、データ処理装置、プログラムロード方法及びロードプログラム
JP2021103354A (ja) プログラムの試験方法
US20230418950A1 (en) Methods, Devices, and Systems for Control Flow Integrity

Legal Events

Date Code Title Description
A621 Written request for application examination

Free format text: JAPANESE INTERMEDIATE CODE: A621

Effective date: 20180111

A871 Explanation of circumstances concerning accelerated examination

Free format text: JAPANESE INTERMEDIATE CODE: A871

Effective date: 20180111

A975 Report on accelerated examination

Free format text: JAPANESE INTERMEDIATE CODE: A971005

Effective date: 20180314

A131 Notification of reasons for refusal

Free format text: JAPANESE INTERMEDIATE CODE: A131

Effective date: 20180323

A521 Request for written amendment filed

Free format text: JAPANESE INTERMEDIATE CODE: A523

Effective date: 20180327

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: 20180507

A61 First payment of annual fees (during grant procedure)

Free format text: JAPANESE INTERMEDIATE CODE: A61

Effective date: 20180508

R150 Certificate of patent or registration of utility model

Ref document number: 6338796

Country of ref document: JP

Free format text: JAPANESE INTERMEDIATE CODE: R150

R250 Receipt of annual fees

Free format text: JAPANESE INTERMEDIATE CODE: R250

R250 Receipt of annual fees

Free format text: JAPANESE INTERMEDIATE CODE: R250