(57)【要約】【課題】スタックスマッシング攻撃によりコンピュータにおいて実行され得る有害な攻撃コードを自動的に抽出できるプログラムと、攻撃コードの抽出装置および方法を提供する。【解決手段】不正データ入力検知部１０１において、攻撃コードを含む不正データの入力が検知されると、開始アドレス特定部１０２において、呼び出し元の関数への戻りアドレスが格納されるスタック上のアドレスに関連付けられた所定のポインタ（例えばフレーム・ポインタ）に基づいて、スタックオーバーフローにより書き換えられた戻りアドレスが取得され、このアドレスから、攻撃コードの開始アドレスが特定される。したがって、スタックスマッシング攻撃によりコンピュータに送り込まれた攻撃コードを、人手に依らず自動的に抽出することが可能になる。【選択図】図２
2005032182.tif 000002
【特許請求の範囲】
【請求項１】
攻撃コードを含む不正データの入力によってスタックにオーバーフローを引き起こし、上記オーバーフローによって、スタックに格納される呼び出し元関数のコードの戻りアドレスを上記攻撃コードの開始アドレスに書き換えることにより、上記攻撃コードを実行させることが可能なコンピュータに、
上記不正データの入力を検知する第１のステップと、
上記第１のステップにおいて上記不正データの入力が検知された場合、上記不正データの入力による上記オーバーフローで書き換えられた上記戻りアドレスに基づいて、上記攻撃コードの開始アドレスを特定する第２のステップと、
を有する処理を実行させるプログラム。
【請求項２】
上記第２のステップにおいて、上記コンピュータの所定のレジスタに格納されるポインタであって、上記戻りアドレスが格納されるスタック上のアドレスに関連付けられたポインタに基づいて、上記書き換えられた戻りアドレスを取得する、
請求項１に記載のプログラム。
【請求項３】
上記第１のステップにおいて上記不正データの入力が検知された後に新たな関数が呼び出された場合、
上記第２のステップにおいて、上記コンピュータの所定のレジスタに格納されるポインタであって、呼び出し元関数のスタック・フレームにおいて基準となるアドレスを指示するポインタが格納されたスタック上のアドレスに関連付けられたポインタに基づいて、呼び出し元関数の上記基準アドレスを取得し、取得した上記基準アドレスに基づいて、上記書き換えられた戻りアドレスを取得する、
請求項１に記載のプログラム。
【請求項４】
上記第１のステップにおいて上記攻撃が検知された後、新たに複数の関数が呼び出された場合、
上記第２のステップにおいて、取得した上記基準アドレスに基づいて、更に上位の呼び出し元関数のスタック・フレームにおける上記基準アドレスを取得する処理を反復し、上記反復処理の結果として取得される上記基準アドレスに基づいて、上記書き換えられた戻りアドレスを取得する、
請求項３に記載のプログラム。
【請求項５】
上記第１のステップにおいて、新たな関数が呼び出された場合に所定値のデータをスタック上の所定のアドレスに格納し、呼び出し元関数へ戻る場合に当該アドレスに格納されるデータの値と上記所定値とを比較し、当該比較結果に基づいて、上記オーバーフローの発生の有無を検知する、
請求項１に記載のプログラム。
【請求項６】
上記第１のステップにおいて、新たに呼び出すべき関数に引数として渡されるデータのサイズと、上記関数において上記引数に割り当てられているデータサイズとを比較し、当該比較結果に基づいて、上記関数が呼び出された場合における上記オーバーフローの発生の有無を事前に検知し、
上記第１のステップにおいて上記オーバーフローの発生が事前に検知された場合、上記新たな関数を呼び出して、上記オーバーフローを発生させる第３のステップを有する、
請求項１に記載のプログラム。
【請求項７】
上記第１のステップにおいて上記不正データの入力が検知された場合、上記不正データの入力によって上記オーバーフローが引き起こされたメモリ領域のデータを取得する第４のステップと、
上記第２のステップにおいて特定された上記攻撃コードの開始アドレスと、上記第４のステップにおいて取得されたデータとに応じて、上記攻撃コードが格納されるアドレス範囲を特定する第５のステップと、を有する、
請求項１に記載のプログラム。
【請求項８】
上記第５のステップにおいて、上記第４のステップで取得されたデータと所定のデータとを、上記第２のステップで特定された攻撃コードの開始アドレスから順に比較し、上記所定のデータと一致するデータが格納されるアドレスを検索する、
請求項７に記載のプログラム。
【請求項９】
プロセスの実行に伴って入力されるデータを記録する第６のステップを有し、
上記第５のステップにおいて、上記第４のステップで取得されたデータと上記第６のステップで記録された入力データとを、上記第２のステップで特定された攻撃コードの開始アドレスから順に比較し、上記入力データと一致するデータが格納されるアドレスを検索する、
請求項７に記載のプログラム。
【請求項１０】
上記第２のステップにおいて上記攻撃コードの開始アドレスが特定された場合、少なくとも、当該特定された開始アドレスに関する情報、または当該開始アドレスより格納される攻撃コードに関する情報を含んだ所定の通知情報を生成する第７のステップを有する、
請求項１に記載のプログラム。
【請求項１１】
攻撃コードを含む不正データの入力によってスタックにオーバーフローを引き起こし、上記オーバーフローによってスタックに格納される呼び出し元関数のコードの戻りアドレスを上記攻撃コードの開始アドレスに書き換えることにより、上記攻撃コードを実行させることが可能なコンピュータに、
予め設定されたメモリ領域のデータが実行すべき命令コードとして上記コンピュータに取得されたか否かを検知する第１のステップと、
上記第１のステップにおいて上記命令コードの取得が検知された場合、上記コンピュータの所定のレジスタに格納される、実行すべき命令コードのアドレスを指示するポインタに基づいて、上記攻撃コードの開始アドレスを特定する第２のステップと、
を有する処理を実行させるプログラム。
【請求項１２】
攻撃コードを含む不正データがコンピュータに入力されてスタックにオーバーフローが引き起こされ、上記オーバーフローによってスタックに格納される呼び出し元関数のコードの戻りアドレスが上記攻撃コードの開始アドレスに書き換えられることにより、上記コンピュータにおいて実行され得る上記攻撃コードを抽出する攻撃コード抽出装置であって、
上記不正データの入力を検知する不正データ入力検知手段と、
上記不正データ入力検知手段において上記不正データの入力が検知された場合、上記不正データの入力による上記オーバーフローで書き換えられたスタックに格納される上記戻りアドレスに基づいて、上記攻撃コードの開始アドレスを特定する開始アドレス特定手段と、
を有する攻撃コード抽出装置。
【請求項１３】
上記不正データ入力検知手段において上記不正データの入力が検知された場合、上記不正データの入力によって上記オーバーフローが引き起こされたメモリ領域のデータを取得するデータ取得手段と、
上記アドレス特定手段において特定された上記攻撃コードの開始アドレスと、上記データ取得手段において取得されたデータとに応じて、上記攻撃コードが格納されるアドレス範囲を特定するアドレス範囲特定手段と、を有する、
請求項１２に記載の攻撃コード抽出装置。
【請求項１４】
攻撃コードを含む不正データがコンピュータに入力されてスタックにオーバーフローが引き起こされ、上記オーバーフローによってスタックに格納される呼び出し元関数のコードの戻りアドレスが上記攻撃コードの開始アドレスに書き換えられることにより、上記コンピュータにおいて実行され得る上記攻撃コードを抽出する攻撃コード抽出装置であって、
予め設定されたメモリ領域のデータが実行すべき命令コードとして上記コンピュータに取得されたか否かを検知する命令コード取得検知手段と、
上記命令コード取得検知手段において上記命令コードの取得が検知された場合、上記コンピュータの所定のレジスタに格納される、実行すべき命令コードのアドレスを指示するポインタに基づいて、上記攻撃コードの開始アドレスを特定する開始アドレス特定手段と、
を有する攻撃コード抽出装置。
【請求項１５】
攻撃コードを含む不正データがコンピュータに入力されてスタックにオーバーフローが引き起こされ、上記オーバーフローによってスタックに格納される呼び出し元関数のコードの戻りアドレスが上記攻撃コードの開始アドレスに書き換えられることにより、上記コンピュータにおいて実行され得る上記攻撃コードを抽出する攻撃コード抽出方法であって、
上記不正データの入力を検知する第１の工程と、
上記第１の工程において上記不正データの入力が検知された場合、上記不正データの入力による上記オーバーフローで書き換えられたスタックに格納される上記戻りアドレスに基づいて、上記攻撃コードの開始アドレスを特定する第２の工程と、
を有する攻撃コード抽出方法。
【請求項１６】
攻撃コードを含む不正データがコンピュータに入力されてスタックにオーバーフローが引き起こされ、上記オーバーフローによってスタックに格納される呼び出し元関数のコードの戻りアドレスが上記攻撃コードの開始アドレスに書き換えられることにより、上記コンピュータにおいて実行され得る上記攻撃コードを抽出する攻撃コード抽出方法であって、
予め設定されたメモリ領域のデータが実行すべき命令コードとして上記コンピュータに取得されたか否かを検知する第１の工程と、
上記命令コード取得検知手段において上記命令コードの取得が検知された場合、上記コンピュータの所定のレジスタに格納される、実行すべき命令コードのアドレスを指示するポインタに基づいて、上記攻撃コードの開始アドレスを特定する第２の工程と、
を有する攻撃コード抽出方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、コンピュータに入力される不正な攻撃コードを抽出するプログラムとその抽出装置および抽出方法に係り、特に、スタックオーバーフローを利用した攻撃によって実行され得る攻撃コードを抽出するプログラムとその抽出装置および抽出方法に関するものである。
【背景技術】
【０００２】
現在、コンピュータのセキュリティに関する多くの問題が報告されている。最も多く報告されているものの一つに、バッファオーバーフローを利用した攻撃があり、その中でも特に、スタックのオーバーフローを利用するスタックスマッシング（stack smashing）と呼ばれる攻撃が数多く報告されている。
【０００３】
スタックオーバーフローは、次に述べるような、スタックの構造とＣ言語における配列の境界チェックの欠如とに起因して発生する。
【０００４】
スタックは、最後に置かれたオブジェクトが最初に取り除かれるＬＩＬＯ（last-in first-out）と呼ばれる性質を持つ抽象データ型である。Ｃ言語において関数の呼び出しに用いられるスタックは、一般に、スタック・ポインタ、スタック・フレーム、フレーム・ポインタから構成される。
【０００５】
スタック・ポインタは、スタックの先頭を指す。
スタック・フレームは、関数の引数や、ローカル変数、以前に積まれたスタック・フレームを復元するために必要なデータ（呼び出し元関数の命令ポインタ、呼び出し元関数のフレーム・ポインタなど）が所定の順序で格納されるメモリ領域である。
【０００６】
フレーム・ポインタは、スタック・フレーム内において基準となるアドレス位置を指示する。主として、ローカル変数を参照するための相対値として利用される。
すなわち、ローカル変数のサイズや引数の数が変化しても、ローカル変数が格納される先頭のアドレスは、このフレーム・ポインタによって指示される基準アドレスに対して相対的に一定の位置にある。したがって、フレーム・ポインタを取得することにより、ローカル変数へ容易にアクセスすることができる。
また、呼び出し元関数の命令ポインタやそのフレーム・ポインタなど、以前に積まれたスタック・フレームを復元するために必要なデータについても、この基準アドレスから相対的に一定の位置に格納される。したがって、フレーム・ポインタを取得することにより、これらのデータへのアクセスも容易になる。
【０００７】
関数の呼び出し時および戻り時におけるスタックの動作について、図１６および図１７を参照して説明する。
【０００８】
図１６は、Ｃ言語のソース・コードの一例を示す図である。
図１６のソース・コードにおける行番号Ｌ１の関数‘ｆｕｎｃｔｉｏｎ（）’には、３つの整数の変数‘ａ’，‘ｂ’，‘ｃ’が引数として渡されている。また、関数‘ｆｕｎｃｔｉｏｎ（）’の内部では、文字型の配列‘ｂｕｆ’がローカル変数として定義されている（行番号Ｌ２）。この関数‘ｆｕｎｃｔｉｏｎ（）’がｍａｉｎ関数において呼び出されている（行番号Ｌ４、Ｌ５）。
【０００９】
図１７は、このようなソース・コードが実行された場合におけるスタックの状態の一例を図解した図である。
【００１０】
関数の呼び出しは、以下の手順で実行される。
【００１１】
（１）関数‘ｆｕｎｃｔｉｏｎ（）’の引数（‘ａ’〜‘ｃ’）がスタックに積まれる。図１７に示すように、‘ｃ’、‘ｂ’、‘ａ’の順でスタックに引数が積まれる。
【００１２】
（２）次いで、現在の命令ポインタ（実行すべき命令コードが格納されるメモリのアドレス）が戻りアドレス‘ｒｅｔ’としてスタックに積まれる。
【００１３】
（３）更に、現在のフレーム・ポインタ‘ＦＰ’がスタックに積まれ、フレーム・ポインタ‘ｓｆｐ’（saved frame pointer）として保存される。
【００１４】
（４）現在のスタック・ポインタ‘ＳＰ’が、現在のフレーム・ポインタ‘ＦＰ’にコピーされる。これにより、新しいフレーム・ポインタ‘ＦＰ’は、上述した戻りアドレス‘ｒｅｔ’を指す。
【００１５】
（５）最後に、ローカル変数‘ｂｕｆ’のメモリ領域を確保するため、スタック・ポインタ‘ＳＰ’が更に上位へ進められる。図１７は、この時点におけるスタックの状態の一例を示している。
【００１６】
関数の戻り時には、以下の動作が実行される。
【００１７】
（１）現在のフレーム・ポインタ‘ＦＰ’がスタック・ポインタ‘ＳＰ’にコピーされる。これにより、新しいスタック・ポイン‘ＳＰ’は、戻りアドレス‘ｒｅｔ’を指す。
【００１８】
（２）また、スタックに積まれていた以前のフレーム・ポインタ‘ＳＦＰ’がフレーム・ポインタ‘ＦＰ’にコピーされる。これにより、フレーム・ポインタ‘ＦＰ’が呼び出し元の関数のスタック・フレームに戻る。
【００１９】
（３）そして、スタック・ポインタＳＰによって指示されている戻りアドレス‘ｒｅｔ’がスタックから読み出され、命令ポインタにセットされる。これにより、呼び出し元の関数へ処理がジャンプする。以降、スタックに積まれていた引数（‘ａ’〜‘ｃ’）が順に読み出されることによって、スタック・ポインタ‘ＳＰ’は元の状態に戻る。
【００２０】
図１８は、このような構造のスタックにオーバーフローが発生した場合におけるスタックの状態の一例を図解した図である。
【００２１】
ローカル変数としての配列‘ｂｕｆ’に、割り当てを超えたデータ（図１８の例では、終端文字を含めて１０個を超える文字型のデータ）が入力されると、図１８の矢印に示すように、配列ｂｕｆより上位のアドレスに格納されているデータが、入力データによって上書きされる。このように、割り当てを超えたデータが入力されることによって、スタック上の保持すべきデータが上書きされてしまうことを、スタックオーバーフローと呼んでいる。
【００２２】
図１９は、スタックオーバーフローを利用したスタックスマッシング攻撃によって、攻撃コードが実行される様子を図解した図である。
【００２３】
スタックスマッシング攻撃では、スタックオーバーフローを引き起こす入力データの中に、有害な攻撃コードが挿入される。すなわち、図１９に示すように、スタックオーバーフローによって上書きされたメモリ領域に、攻撃コードが書き込まれる。更に、この入力データの中には、攻撃コードを指示するアドレスが含まれており、このアドレスによって、スタックに格納されている戻りアドレス‘ｒｅｔ’が書き換えられる。そのため、関数の戻り時において、本来実行されるべき命令コードの代わりに、攻撃コードが実行されてしまう。
【００２４】
例えばＵＮＩＸ（登録商標）の場合、多くのデーモンプロセスはｒｏｏｔ権限で実行されている。そこで、例えば攻撃コードとして‘ｅｘｅｃ（／ｂｉｎ／ｓｈ）’を利用し、デーモンプロセスに対してスタックスマッシング攻撃を行なうことにより、攻撃者はそのホストでのｒｏｏｔ権限を獲得できる。
【００２５】
このようなスタックスマッシング攻撃に対抗するため、現在幾つかの技術が提案されており、これらは、大きく以下の３つに分類される。
【００２６】
（１）スタック上の情報が上書きされることを事前に検出する方法
（２）スタック上の情報が上書きされたことを検出する方法
（３）メモリ上のコードの実行可否を判定する方法
【００２７】
以下では、これらの従来技術について説明する。
【００２８】
（１）スタック上の情報が上書きされることを事前に検出する方法
【００２９】
［非特許文献１］には、ソース・コードのライブラリを置き換える方法として、ｌｉｂｓａｆｅと呼ばれる方法が提案されている。
【００３０】
ｌｉｂｓａｆｅでは、スタックオーバーフローを引き起こす可能性のあるライブラリ関数の呼び出しを横取り（intercept）し、関数の引数がスタックのメモリ範囲内に収まるか否かを検査する。そして、正常な場合には適当なライブラリ関数を呼び出し、異常な場合にはその旨を通知するメッセージを残してプログラムを終了することにより、スタックオーバーフローを防止する。
【００３１】
Ｃ言語における標準ライブラリ（ｌｉｂｃ）の関数‘ｓｔｒｃｐｙ（）’を例にして、ｌｉｂｓａｆｅの動作を説明する。
図２０は、ｌｉｂｓａｆｅのライブラリをリンクしたあるプロセスでのメモリの状態を示す図である。
【００３２】
プログラムが‘ｓｔｒｃｐｙ（）’を呼び出すと、標準ライブラリ（ｌｉｂｃ）ではなく、ｌｉｂｓａｆｅのライブラリに実装されている‘ｓｔｒｃｐｙ（）’が実行される（Ｆ１）。これはライブラリのロードの順番を工夫することにより実現される。
【００３３】
ｌｉｂｓａｆｅの‘ｓｔｒｃｐｙ（）’は、まず、コピー元の文字列（‘ｓｒｃ’）の長さとコピー先のバッファ長の上限（すなわちスタック・フレーム長）を計算し、コピー元の文字列がコピー先のバッファ長の上限を越えないかを検査する。
上限を越えない場合、ｌｉｂｓａｆｅの‘ｓｔｒｃｐｙ（）’は、標準ライブラリ（ｌｉｂｃ）の関数‘ｍｅｍｃｐｙ（）’を呼び出してこれを実行し（Ｆ２，Ｆ３）、メイン関数に戻る（Ｆ４）。
一方、上限を越えると判定された場合、ｌｉｂｓａｆｅの‘ｓｔｒｃｐｙ（）’はシステムのログ・ファイル（ｓｙｓｌｏｇ）にメッセージを残し、プログラムを終了させる。
このように、ｌｉｂｓａｆｅでは、スタックオーバーフローの発生を事前に検出することにより、スタックスマッシング攻撃を防いでいる。
【００３４】
（２）スタック上の情報が上書きされたことを検出する方法
【００３５】
［非特許文献２］には、コンパイラを拡張する方法として、ＳｔａｃｋＧｕａｒｄと呼ばれる方法が提案されている。
ＳｔａｃｋＧｕａｒｄでは、図２１に示されるように、戻りアドレス‘ｒｅｔ’とローカル変数‘ｂｕｆ’との間に‘Ｃａｎａｒｙ  Ｗｏｒｄ’と呼ばれる値を挿入する。そして、関数戻り時にこの値をチェックし、スタックオーバーフローの上書きによって値が変更されている場合、スタックスマッシング攻撃が行なわれたものとしてプロセスを終了させる（図２２）。
【００３６】
また、［特許文献１］においても、Ｓｔａｃｋ  Ｓｍａｓｈｉｎｇ  Ｐｒｏｔｅｃｔｏｒと呼ばれる、上述のＳｔａｃｋＧｕａｒｄと同様な技術が開示されている。［特許文献１］によれば、関数戻り時に、スタックのプレヴィアス・フレーム・ポインタ（図１７におけるフレーム・ポインタ‘ｓｆｐ’に相当する）と配列（図１７における配列‘ｂｕｆ’に相当する）との間にガード変数を格納し、その有効性を確認することにより、スタックスマッシング攻撃を防止する。
【００３７】
（３）メモリ上のコードの実行可否を判定する方法
【００３８】
オペレーティング・システムを拡張する方法として、インターネット＜ＵＲＬ：  http://www.openwall.com/linux/＞において開示されている、ｎｏｎ−ｅｘｅｃｕｔａｂｌｅ  ｓｔａｃｋと呼ばれる方法や、インターネット＜ＵＲＬ：  http://pageexec.virtualave.net/＞において開示されている、ＰａＸと呼ばれる方法が存在する。
【００３９】
ｎｏｎ−ｅｘｅｃｕｔａｂｌｅ  ｓｔａｃｋの方法では、スタックスマッシング攻撃において攻撃コードがスタック上に置かれることに着目し、メモリ上のスタックのページにおいて、ＣＰＵによる命令の実行が許可されないように、カーネルを変更している。スタックスマッシング攻撃によりスタック上に置かれた攻撃コードが実行された場合、ページ違反（page fault）としてプロセスを停止させる。
【００４０】
一方、ＰａＸの方法では、スタックだけでなく全てのデータページにおいてＣＰＵによる命令実行の許可／不許可をマークできるように、カーネルを変更している。
【００４１】
何れの方法においても、スタック上に置かれたコードを実行できなくすることにより、スタックスマッシング攻撃を防止している。
【００４２】
以上述べた、スタックスマッシング攻撃を防止する３つの方法とは別に、［特許文献２］においては、既知や未知のコンピュータウィルスの検索・駆除を行なう技術が開示されている。
【００４３】
［特許文献２］の技術では、ウィルスが存在する仮想のコンピュータ環境を作成して、感染を誘発するためのバイト列からなる複数の対象を提供し、検査対象に付着している可能性のあるウィルスを誘引して、この複数の対象にウィルスを感染させる。そして、感染を誘発させた後の複数の対象と、もともと提供された複数の対象とを比較し、これらに変化があるかどうかを調べることにより、ウィルスが含まれているか否かを決定する。また、この比較結果からウィルスに関する情報や知識を抽出し、ウィルスの駆除を行なう。更に、ウィルスによって変更されたキー情報を、このウィルスに関して抽出した情報や知識、感染したバイト列に対してウィルスが行なった修正に基づき修正する。
【非特許文献１】Arash Baratloo，他２名、  ‘Transparent Run-Time Defense Against Stack Smashing Attacks’、  In Proceedings of 2000 USENIX Annual Technical Conference、（米国）、  ２０００年
【非特許文献２】Crispin Cowan，他８名、  ‘Automatic Adaptive Detection and Prevention of Buffer-Overflow Attacks’、  In Proceedings of the 7th USENIX Security Symposium、（米国）、  １９９８年
【特許文献１】特開２００１−２１６１６１号公報
【特許文献２】特開２００２−３４２１０６号公報
【発明の開示】
【発明が解決しようとする課題】
【００４４】
ところで、数多くの被害報告がなされている上述したスタックスマッシング攻撃に対処するためには、その攻撃内容を詳しく分析することが必須であり、そのためには、攻撃者が送り込んできた攻撃コードを抽出して調べなくてはならない。
【００４５】
しかしながら、スタックスマッシング攻撃に対抗する上述した３つの方法は、何れもスタックオーバーフローの発生や、禁止されたアドレスの命令コードの実行を検出して、プロセスを停止または終了させるのみであり、攻撃コードを抽出することに関しては何ら手立てを与えるものではない。
【００４６】
そのため、攻撃コードがいかなるものかを知るためには、人手で攻撃内容を分析しなくてはならず、それには多大な時間とコストが要求されるという不利益がある。
【００４７】
また、［特許文献２］に開示される技術では、ウィルスが感染する対象のバイト列をある瞬間保持しておき、感染を誘発させた後の感染対象のバイト列とこれを比較することによりウィルス感染を判断する。
しかしながら、スタックスマッシング攻撃は動作中のプロセスに対する攻撃であり、動作中のプロセスのメモリの状態は逐一変化しているので、［特許文献２］に開示される技術のように、以前のある瞬間のバイト列と感染を誘発させた後の感染対象のバイト列との比較を行なうことは不可能である。すなわち、この方法では、スタックスマッシング攻撃を利用したコンピュータウィルスの検索・駆除、ならびに攻撃コードの抽出を行なうことはできない。
【００４８】
本発明はかかる事情に鑑みてなされたものであり、その目的は、スタックのオーバーフローを利用した攻撃によりコンピュータにおいて実行され得る有害な攻撃コードを効率的に抽出することができるプログラムと、攻撃コード抽出装置および方法を提供することにある。
【課題を解決するための手段】
【００４９】
上記の目的を達成するため、本発明の第１の観点のプログラムは、攻撃コードを含む不正データの入力によってスタックにオーバーフローを引き起こし、上記オーバーフローによって、スタックに格納される呼び出し元関数のコードの戻りアドレスを上記攻撃コードの開始アドレスに書き換えることにより、上記攻撃コードを実行させることが可能なコンピュータに、上記不正データの入力を検知する第１のステップと、上記第１のステップにおいて上記不正データの入力が検知された場合、上記不正データの入力による上記オーバーフローで書き換えられた上記戻りアドレスに基づいて、上記攻撃コードの開始アドレスを特定する第２のステップとを有する処理を実行させる。
【００５０】
本発明の第１の観点によると、上記不正データの入力が検知された場合、上記不正データの入力による上記オーバーフローで書き換えられた上記戻りアドレスに基づいて、上記攻撃コードの開始アドレスが特定される。
【００５１】
好適には、上記第２のステップにおいて、上記コンピュータの所定のレジスタに格納されるポインタであって、上記戻りアドレスが格納されるスタック上のアドレスに関連付けられたポインタに基づいて、上記書き換えられた戻りアドレスを取得する。上記ポインタは、例えば、フレーム・ポインタやスタック・ポインタであっても良い。
【００５２】
また、上記第１のステップにおいて上記不正データの入力が検知された後に新たな関数が呼び出された場合、上記第２のステップにおいて、上記コンピュータの所定のレジスタに格納されるポインタであって、呼び出し元関数のスタック・フレームにおいて基準となるアドレスを指示するポインタが格納されるスタック上のアドレスに関連付けられたポインタに基づいて、呼び出し元関数の上記基準アドレスを取得し、取得した上記基準アドレスに基づいて、上記書き換えられた戻りアドレスを取得しても良い。
上記攻撃検知後に呼び出される関数が複数の場合には、上記第２のステップにおいて、取得した上記基準アドレスに基づいて、更に上位の呼び出し元関数のスタック・フレームにおける上記基準アドレスを取得する処理を反復し、上記反復処理の結果として取得される上記基準アドレスに基づいて、上記書き換えられた戻りアドレスを取得しても良い。
これにより、上記不正データの入力検知後に関数が呼び出されることによって、上記オーバーフローを生じたスタック・フレーム上に別のスタック・フレームが積み重ねられた状態でも、上記基準アドレスを辿って上記書き換えられた戻りアドレスが取得される。
【００５３】
また、本発明の第１の観点のプログラムは、上記第１のステップにおいて上記不正データの入力が検知された場合、上記不正データの入力によって上記オーバーフローが引き起こされたメモリ領域のデータを取得する第４のステップと、上記第２のステップにおいて特定された上記攻撃コードの開始アドレスと、上記第４のステップにおいて取得されたデータとに応じて、上記攻撃コードが格納されるアドレス範囲を特定する第５のステップとを有しても良い。
これにより、上記不正データの入力が検知された場合、上記オーバーフローが引き起こされたメモリ領域のデータが取得され、この取得されたデータと、上記第２のステップにおいて特定された上記攻撃コードの開始アドレスとに応じて、上記攻撃コードが格納されるアドレス範囲が特定される。
【００５４】
また、本発明の第１の観点のプログラムは、上記第２のステップにおいて上記攻撃コードの開始アドレスが特定された場合、少なくとも、当該特定された開始アドレスに関する情報、または、当該開始アドレスより格納される攻撃コードに関する情報を含んだ所定の攻撃通知情報を生成する第７のステップを有しても良い。
【００５５】
本発明の第２の観点のプログラムは、上記コンピュータに、予め設定されたメモリ領域のデータが実行すべき命令コードとして上記コンピュータに取得されたか否かを検知する第１のステップと、上記第１のステップにおいて上記命令コードの取得が検知された場合、上記コンピュータの所定のレジスタに格納される、実行すべき命令コードのアドレスを指示するポインタに基づいて、上記攻撃コードの開始アドレスを特定する第２のステップとを有する処理を実行させる。
【００５６】
本発明の第２の観点によると、予め設定されたメモリ領域のデータが実行すべき命令コードとして上記コンピュータに取得されたことが検知された場合、上記コンピュータの所定のレジスタに格納される、実行すべき命令コードのアドレスを指示するポインタに基づいて、上記攻撃コードの開始アドレスが特定される。
【００５７】
本発明の第３の観点の攻撃コード抽出装置は、上記コンピュータへの上記不正データの入力を検知する不正データ入力検知手段と、上記不正データ入力検知手段において上記不正データの入力が検知された場合、上記不正データの入力による上記オーバーフローで書き換えられたスタックに格納される上記戻りアドレスに基づいて、上記攻撃コードの開始アドレスを特定する開始アドレス特定手段とを有する。
【００５８】
本発明の第３の観点によると、上記不正データ入力検知手段において上記不正データの入力が検知された場合、上記開始アドレス特定手段において、上記不正データの入力による上記オーバーフローで書き換えられたスタックに格納される上記戻りアドレスに基づいて、上記攻撃コードの開始アドレスが特定される。
【００５９】
本発明の第４の観点は、予め設定されたメモリ領域のデータが実行すべき命令コードとして上記コンピュータに取得されたか否かを検知する命令コード取得検知手段と、上記命令コード取得検知手段において上記命令コードの取得が検知された場合、上記コンピュータの所定のレジスタに格納される、実行すべき命令コードのアドレスを指示するポインタに基づいて、上記攻撃コードの開始アドレスを特定する開始アドレス特定手段とを有する。
【００６０】
本発明の第４の観点によると、上記命令コード取得検知手段において上記命令コードの取得が検知された場合、上記開始アドレス特定手段において、上記コンピュータの所定のレジスタに格納される、実行すべき命令コードのアドレスを指示するポインタに基づいて、上記攻撃コードの開始アドレスが特定される。
【００６１】
本発明の第５の観点は、上記コンピュータへの上記不正データの入力を検知する第１の工程と、上記第１の工程において上記不正データの入力が検知された場合、上記不正データの入力による上記オーバーフローで書き換えられたスタックに格納される上記戻りアドレスに基づいて、上記攻撃コードの開始アドレスを特定する第２の工程とを有する。
【００６２】
本発明の第６の観点は、予め設定されたメモリ領域のデータが実行すべき命令コードとして上記コンピュータに取得されたか否かを検知する第１の工程と、上記命令コード取得検知手段において上記命令コードの取得が検知された場合、上記コンピュータの所定のレジスタに格納される、実行すべき命令コードのアドレスを指示するポインタに基づいて、上記攻撃コードの開始アドレスを特定する第２の工程とを有する。
【発明の効果】
【００６３】
本発明によれば、スタックのオーバーフローを利用した攻撃によりコンピュータにおいて実行され得る有害な攻撃コードを効率的に抽出できる。
【発明を実施するための最良の形態】
【００６４】
以下、本発明の５つの実施形態を述べる。
【００６５】
＜第１の実施形態＞
図１は、本発明の実施形態に係るコンピュータの構成の一例を示すブロック図である。
【００６６】
図１に示すコンピュータは、ＣＰＵ１０と、記憶装置２０と、入出力部３０と、プログラムメモリ４０と、ＲＡＭ５０とを有する。
【００６７】
ＣＰＵ１０は、プログラムメモリ４０に格納される本実施形態に係るプログラムを読み出し、これに基づいて所定の処理を実行する。
【００６８】
ここでは例として、ＣＰＵ１０は、インテル社（米国）において開発されたＩＡ−３２と称されるアーキテクチャを有するものとする。ＩＡ−３２アーキテクチャのプロセッサは、演算処理に用いる種々のレジスタを有しており、スタックの処理に係わるレジスタとしては、ＥＳＰレジスタ１１、ＥＢＰレジスタ１２、およびＥＩＰレジスタ１３を有する。（図４参照）。
【００６９】
ＥＳＰレジスタ１１は、スタック・ポインタを格納する。
ＥＢＰレジスタ１２は、フレーム・ポインタを格納する。このフレーム・ポインタは、呼び出し元関数の戻りアドレスが格納されているスタック上のアドレスを指示する。
ＥＩＰレジスタ１３は、命令ポインタを格納する。
【００７０】
記憶装置２０は、ＣＰＵ１０の処理過程において利用されるデータや、処理結果のデータを記憶する。
【００７１】
入出力部３０は、ＣＰＵ１０の処理過程において利用されるデータを入力する処理や、処理結果のデータを出力する処理を行なう。
入出力部３０には、例えば、ＬＡＮ（local area network）やインターネットなどのネットワークを介して他の機器との間でデータをやり取りするネットワーク・インターフェース装置や、磁気ディスク、光ディスク、ＩＣカードなどの可搬性を有する記録媒体に対してデータの書き込みや読み出しを行なう装置、キーボードやマウスなどのユーザ・インターフェース装置、ディスプレイ装置などが含まれる。
【００７２】
プログラムメモリ４０は、後述する本実施形態に係るプログラムを記憶する。
【００７３】
ＲＡＭ５０は、ＣＰＵ１０による処理の過程で利用するプログラム・コードやデータを一時的に記憶する。スタックを構成するデータは、このＲＡＭ５０における所定のスタック領域に格納される。
【００７４】
なお、これらのユニット（ＣＰＵ１０、記憶装置２０、入出力部３０、プログラムメモリ４０、ＲＡＭ５０）は、図１の例において、共通のバス６０に接続される。各ユニットの間におけるデータの受け渡しは、ＣＰＵ１０の制御の基に、このバス６０を介して行なわれる。
【００７５】
図２は、本実施形態に係るプログラムの機能的な構成の一例を示すブロック図である。
本実施形態に係るプログラムは、不正データ入力検知部１０１と、開始アドレス特定部１０２と、通知情報生成部１０３とを有する。
【００７６】
［不正データ入力検知部１０１］
不正データ入力検知部１０１は、スタックにオーバーフローを引き起こす不正なデータの入力を検知する。
【００７７】
例えば、不正データ入力検知部１０１は、新たな関数が呼び出された場合、スタック・フレーム中の所定のアドレス（フレーム・ポインタと戻りアドレスとの間や、ローカル変数とフレーム・ポインタとの間など）に、所定値の上書き検出用のデータを挿入する。この値は、例えば、図示しない乱数生成部において生成される乱数を用いて設定する。そして、呼び出し元の関数へ戻る場合に、この所定のアドレスに格納されるデータと上記所定値とを比較し、上書き検出用のデータが変化しているか否かを調べる。この結果、上書き検出用のデータが変化している場合に、スタックオーバーフローが発生したと判定する。
【００７８】
不正なデータの入力が検知されると、不正データ入力検知部１０１は、開始アドレス特定部１０２にその旨を通知する。
【００７９】
［開始アドレス特定部１０２］
開始アドレス特定部１０２は、不正データ入力検知部１０１より不正データの入力が通知された場合、この不正データの入力により生じるスタックオーバーフローによって書き換えられた、呼び出し元関数の戻りアドレスに基づいて、入力された不正データに含まれる攻撃コードの開始アドレスを特定する。
【００８０】
例えば、開始アドレス特定部１０２は、ＣＰＵ１０のＥＢＰレジスタ１２に格納されるフレーム・ポインタに基づいて、攻撃コードの開始アドレスを取得する。
【００８１】
既に述べたように、ＥＢＰレジスタ１２は、呼び出し元関数への戻りアドレスを指示するフレーム・ポインタを格納している。また、攻撃コードを含む不正データによてスタックオーバーフローが引き起こされる場合、この戻りアドレスは、攻撃コードへのアドレスに上書きされる。したがって、開始アドレス特定部１０２は、不正データの入力が検知された場合に、ＥＢＰレジスタ１２のフレーム・ポインタで指示されるスタック上のアドレスの内容を参照することによって、攻撃コードの開始アドレスを取得することができる。
【００８２】
開始アドレス特定部１０２において特定された攻撃コードの開始アドレスは、通知情報生成部１０３に入力される。
【００８３】
［通知情報生成部１０３］
通知情報生成部１０３は、開始アドレス特定部１０２において攻撃コードの開始アドレスが特定された場合、この特定された開始アドレスに関する情報や、この開始アドレスより格納される攻撃コードに関する情報を含んだ所定の通知情報を生成する。
【００８４】
例えば、通知情報生成部１０３は、開始アドレス特定部１０２において特定された開始アドレスや攻撃コードに関する情報を含む所定のファイルを生成し、これを記憶装置２０に書き込む。これにより、ユーザは、このファイルを参照することにより、攻撃コードのアドレスを知ることができる。
【００８５】
また、通知情報生成部１０３は、この開始アドレスや攻撃コードに関する情報をネットワーク経由で他の機器に伝送するための情報を生成しても良い。例えば、入出力部３０がインターネットに接続されているのであれば、この情報をＥ−ｍａｉｌによって所定のアドレスに送信しても良い。
また、通知情報生成部１０３は、入出力部３０がディスプレイ装置を含む場合、ディスプレイ画面上にこの開始アドレスや攻撃コードに関する情報を表示させるための情報を生成しても良い。
【００８６】
次に、上述した構成を有した本実施形態のプログラムによる処理を説明する。
【００８７】
図３は、本実施形態に係るプログラムによる処理の流れの一例を図解したフローチャートである。
【００８８】
ステップＳＴ１０：
図２には示されていない他のプロセスによる処理が進められる。
【００８９】
ステップＳＴ２０：
不正データ入力検知部１０１は、このプロセスの処理過程において、不正なデータの入力の有無を監視する。不正データの入力が検知されない場合は、プロセスの処理（ステップＳＴ１０）を通常通り進行させ、不正データの入力が検知された場合は、開始アドレス特定部１０２へ不正データの入力を通知する。
【００９０】
ステップＳＴ３０：
開始アドレス特定部１０２は、不正データ入力検知部１０１より不正データの入力が通知されると、例えばＥＢＰレジスタ１２のフレーム・ポインタを参照して、スタックオーバーフローにより書き換えられた戻りアドレスを取得し、これにより、攻撃コードの開始アドレスを特定する。
【００９１】
図４は、不正データの入力が検出された場合におけるスタックの状態の一例を図解した図である。
【００９２】
図４に示すように、スタック・フレームは、その下位から上位に向かって、引数（‘ａ’〜‘ｃ’）、戻りアドレス、呼び出し元関数のスタック・フレームにおけるフレーム・ポインタｓｆｐ、および、ローカル変数‘ｂｕｆ’を格納している。また、ＥＳＰレジスタ１１のスタック・ポインタは、スタックの先頭を指しており、ＥＢＰレジスタ１２のフレーム・レジスタは、スタック上に格納された呼び出し元関数への戻りアドレスを指している。
【００９３】
このような構造のスタックにおいて、ローカル変数に不正データが入力されると、図４に示すようにスタックオーバーフローが発生し、スタック領域を含むメモリ上に攻撃コードが書き込まれる。また、スタック上に格納される戻りアドレスは、不正データに含まれるデータによって、この攻撃コードを指示するアドレス‘ａｄｄｒ’に書き換えられる。
【００９４】
開始アドレス特定部１０２は、図４に示すようなスタックの状態において、ＥＢＰレジスタ１２に格納されるフレーム・ポインタを参照し、フレーム・ポインタによって指示されるスタック上のアドレス、すなわち攻撃コードへのアドレス‘ａｄｄｒ’を取得する。
【００９５】
ステップＳＴ４０：
開始アドレス特定部１０２において攻撃コードの開始アドレスが特定されると、通知情報生成部１０３は、この特定された開始アドレスや攻撃コードに関する情報を含んだ所定の通知情報を生成する。例えば、特定された開始アドレスを含む情報を、記憶装置２０にファイルとして格納したり、Ｅ−ｍａｉｌとしてインターネットのメールサーバに送信したり、ディスプレイ装置の画面上に画像として表示させる処理を行なう。
【００９６】
以上説明したように、本実施形態に係るプログラムによれば、プロセスの処理過程において不正データの入力が検知された場合、戻りアドレスが格納されるスタック上のアドレスに関連付けられた所定のポインタ（例えばフレーム・ポインタ）に基づいて、不正データの入力によるスタックオーバーフローで書き換えられた戻りアドレスが取得され、これにより、攻撃コードの開始アドレスが特定される。
したがって、スタックスマッシング攻撃によりコンピュータに送り込まれた攻撃コードを、人手に依らず自動的に抽出することが可能になり、従来の方法で攻撃コードを調べるために費やされていた時間とコストを大幅に削減することができる。
【００９７】
また、上述したプログラムによれば、新たな関数が呼び出された場合に所定の値を有する上書き検出用のデータがスタック上の所定のアドレスに格納され、呼び出し元関数へ戻る場合に当該アドレスに格納されるデータの値と上記所定値とが比較され、この比較結果に基づいて、スタックオーバーフローの発生の有無が検知されて、攻撃コードの開始アドレスが取得される。したがって、ネットワーク経由によるアクセスや、ウィルス感染したファイルとして入力される場合など、不正データがコンピュータに侵入する経路に依存することなく、不正データの侵入を検知し、その攻撃コードを抽出することができる。このことから、既知の攻撃だけでなく、侵入経路が不明な未知の攻撃についても攻撃コードの抽出を行なうことができる。
【００９８】
なお、上述した実施形態では、不正データの入力検知後に、ＥＢＰレジスタ１２のフレーム・ポインタを参照することによって、スタックオーバーフローで書き換えられた戻りアドレスが取得される。これは、スタックオーバーフローを起こしたスタック・フレームがスタックの最上位にある場合に有効であるが、次に述べるように、この条件が成り立たない場合もあり得る。
【００９９】
すなわち、不正データ入力検知部１０１において不正データの入力が検知された後、開始アドレス特定部１０２によるアドレスの特定が行なわれる前に、何らかの処理（例えば攻撃データの実行を阻止する処理など）を実行するハンドラ関数へ処理が移行すると、図５に示すように、スタックオーバーフローを起こしたスタック・フレームの上には、新たに呼び出された関数のためのスタック・フレームが積まれる。スタック・ポインタおよびフレーム・ポインタは、この新たに積まれたスタック・フレームを指す。
【０１００】
このような場合、開始アドレス特定部１０２は、フレーム・ポインタによって指示されるアドレスの１つ手前のアドレスを参照して、呼び出し元関数のスタック・フレームにおけるフレーム・ポインタ‘ｓｆｐ’を読み出し、更に、このフレーム・ポインタ‘ｓｆｐ’によって指示されるアドレスを参照して、書き換えられた戻りアドレス‘ａｄｄｒ’を取得する。
【０１０１】
既に述べたように、ＥＢＰレジスタ１２のフレーム・ポインタは、呼び出し元関数への戻りアドレス‘ｒｅｔ’が格納されるスタック上のアドレスを指示しているが、このアドレスの１つ手前には、図５に示すように、呼び出し元関数のスタック・フレームにおけるフレーム・ポインタ‘ｓｆｐ’が格納されている。そして、そのフレーム・ポインタ‘ｓｆｐ’の指示アドレスには、オーバーフローによって上書きされたスタック・フレーム上の戻りアドレスが格納されている。
したがって、開始アドレス特定部１０２は、ＥＢＰレジスタ１２のフレーム・ポインタの指示アドレスに基づいて、フレーム・ポインタ‘ｓｆｐ’を取得し、さらにその取得したフレーム・ポインタ‘ｓｆｐ’の指示アドレスを参照することによって、書き換えられた戻りアドレス‘ａｄｄｒ’を取得することができる。
【０１０２】
以上は、攻撃検知後に呼び出される関数が１つの場合の例であるが、これが複数の場合でも、上述と同様な方法によって、戻りアドレス‘ａｄｄｒ’を取得可能である。
すなわち、開始アドレス特定部１０２は、スタック・フレームから取得したフレーム・ポインタ‘ｓｆｐ’に基づいて、更に上位の呼び出し元関数のスタック・フレームにおけるフレーム・ポインタ‘ｓｆｐ’を取得する処理を反復する。この処理を反復することにより、結果として、スタックオーバーフローにより書き換えられたスタック・フレームにおけるフレーム・ポインタ‘ｓｆｐ’を取得する。そして、当該フレーム・ポインタ‘ｓｆｐ’の指示アドレスから、書き換えられた戻りアドレス‘ａｄｄｒ’を取得する。
【０１０３】
＜第２の実施形態＞
次に、本発明の第２の実施形態について述べる。
【０１０４】
上述した第１の実施形態に対する本実施形態の違いは、本実施形態において、新たな関数が呼び出される前にスタックオーバーフローの発生の有無が事前に検知される点と、スタックオーバーフローの発生が事前に検知された場合において強制的にオーバーフローが引き起こされる点にある。
【０１０５】
図６は、本発明の第２の実施形態に係るプログラムの機能的な構成の一例を示すブロック図である。
【０１０６】
図６に示すプログラムは、不正データ入力検知部１０１Ａと、強制オーバーフロー部１０４と、開始アドレス特定部１０２と、通知情報生成部１０３とを有する。ただし、図２と図６の同一符号は、同一の構成要素を示す。
以下では、図２に示すプログラムと比較して異なる構成である、不正データ入力検知部１０１Ａおよび強制オーバーフロー部１０４について説明する。
【０１０７】
［不正データ入力検知部１０１Ａ］
不正データ入力検知部１０１Ａは、新たな関数が呼び出される前に、オーバーフローの発生の有無を予測する。
【０１０８】
例えば、不正データ入力検知部１０１Ａは、新たに呼び出すべき関数に引数として渡されるデータのサイズと、この関数において引数に割り当てられているデータサイズとを比較し、この比較結果に基づいて、この関数が呼び出された場合におけるスタックオーバーフローの発生の有無を事前に検知する。この引数のチェックは、例えば、‘ｓｔｒｃｐｙ（）’などの境界チェックを欠いた関数について行なう。
【０１０９】
スタックオーバーフローの発生が事前に検知されると、不正データ入力検知部１０１Ａは、強制オーバーフロー部１０４にその旨を通知する。
【０１１０】
［強制オーバーフロー部１０４］
強制オーバーフロー部１０４は、不正データ入力検知部１０１Ａよりスタックオーバーフローの発生が事前に通知された場合、オーバーフローの発生が検知された関数を呼び出して、強制的にオーバーフローを発生させる。
【０１１１】
次に、上述した構成を有する図６に示すプログラムの処理について、図７のフローチャートを参照して説明する。
【０１１２】
ステップＳＴ１０：
図３と同様に、他のプロセスによる処理が進められる。
【０１１３】
ステップＳＴ２０Ａ：
不正データ入力検知部１０１Ａは、このプロセスの処理過程において、不正なデータの入力の有無を監視する。すなわち、スタックオーバーフローを引き起こす可能性のある関数の引数をチェックし、スタックオーバーフローの発生の有無を事前に検知する。スタックオーバーフローの発生が検知されない場合は、プロセスの処理（ステップＳＴ１０）を通常通り進行させ、スタックオーバーフローの発生が事前に検知された場合は、強制オーバーフロー部１０４へその旨を通知する。
【０１１４】
ステップＳＴ５０：
不正データ入力検知部１０１Ａにおいてスタックオーバーフローの発生が事前に検知されると、強制オーバーフロー部１０４は、この関数を呼び出して、オーバーフローを強制的に発生させる。
【０１１５】
ステップＳＴ３０、ＳＴ４０：
強制オーバーフロー部１０４によるスタックオーバーフローが発生すると、開始アドレス特定部１０２は、既に述べたものと同様の処理により、攻撃コードの開始アドレスを特定する。そして、通知情報生成部１０３は、この特定された開始アドレスや攻撃コードに関する情報を含んだ所定の通知情報を生成する。
【０１１６】
以上説明したように、図６に示すプログラムによれば、不正データの入力検知後にスタックオーバーフローを強制的に引き起こす点が異なるものの、それ以降における攻撃コードの開始アドレスの特定処理については、図２に示すプログラムと同様である。したがって、スタックスマッシング攻撃の攻撃コードを自動的に抽出することが可能になり、時間とコストの削減を図ることができる。
【０１１７】
また、上述したプログラムによれば、プログラム上で呼び出される関数の引数をチェックすることによりスタックオーバーフローの発生の有無が検知されて、攻撃コードが取得されるため、図２に示すプログラムと同様に、不正データがコンピュータに侵入する経路に依存することなく、攻撃コードを抽出することができる。
【０１１８】
＜第３の実施形態＞
次に、本発明の第３の実施形態について述べる。
【０１１９】
上述した第１の実施形態に対する本実施形態の違いは、第１の実施形態において攻撃コードの開始アドレスが特定されるところを、本実施形態においては、更に攻撃コードが格納されるアドレス範囲が特定される点にある。
【０１２０】
図８は、本発明の第３の実施形態に係るプログラムの機能的な構成の一例を示すブロック図である。
【０１２１】
図８に示すプログラムは、不正データ入力検知部１０１と、開始アドレス特定部１０２と、データ取得部１０５と、アドレス範囲特定部１０６と、通知情報生成部１０３とを有する。ただし、図２と図８の同一符号は、同一の構成要素を示す。
以下では、図２に示すプログラムと比較して異なる構成である、データ取得部１０５およびアドレス範囲特定部１０６について説明する。
【０１２２】
［データ取得部１０５］
データ取得部１０５は、不正データ入力検知部１０１において不正データの入力が検知された場合、この不正データの入力によってオーバーフローが引き起こされたメモリ領域のデータを取得する。
【０１２３】
［アドレス範囲特定部１０６］
アドレス範囲特定部１０６は、特定された攻撃コードの開始アドレスと、データ取得部１０５において取得されたデータとに応じて、攻撃コードが格納されるアドレス範囲を特定する。
【０１２４】
例えば、アドレス範囲特定部１０６は、データ取得部１０５において取得されたデータと、文字列の終端を示す終端文字（ヌル文字）とを、開始アドレス特定部１０２において特定された攻撃コードの開始アドレスから順に比較し、終端文字と一致するデータが格納されるアドレスを検索する。
【０１２５】
図９は、スタックスマッシング攻撃によってメモリに書き込まれた攻撃コードの一例を図解した図である。
図９に示すように、バッファオーバーフロー攻撃は、しばしば文字列のコピーを利用して行なわれる。文字列は終端文字で終端されているため、攻撃を受けたメモリ領域において終端文字を検索することにより、攻撃コードの終端のアドレスを特定することができる。
アドレス範囲特定部１０６は、このようにして特定された攻撃コードの終端アドレスと、開始アドレス特定部１０２において特定された攻撃コードの開始アドレスとに基づいて、攻撃コードが格納されるメモリ上のアドレス範囲を特定する。
【０１２６】
次に、上述した構成を有する図８に示すプログラムの処理について、図１０のフローチャートを参照して説明する。
【０１２７】
ステップＳＴ１０，ＳＴ２０：
不正データ入力検知部１０１は、通常プロセス（ステップＳＴ１０）の処理過程において、不正なデータの入力の有無を監視する（ステップＳＴ２０）。
不正データの入力が検知されない場合、不正データ入力検知部１０１は、プロセスの処理（ステップＳＴ１０）を通常通り進行させる。
不正データの入力が検知された場合、不正データ入力検知部１０１は、開始アドレス特定部１０２へ不正データの入力を通知する。
【０１２８】
ステップＳＴ３０：
不正データの入力が通知されると、開始アドレス特定部１０２は、既に述べたものと同様の処理により、攻撃コードが格納される開始アドレスを特定する。
【０１２９】
ステップＳＴ６０：
また、データ取得部１０５は、不正データの入力によりスタックオーバーフローが引き起こされたメモリ領域のデータを取得する。
【０１３０】
ステップＳＴ７０：
アドレス範囲特定部１０６は、データ取得部１０５において取得されたデータと、文字列の終端を示す終端文字とを、開始アドレス特定部１０２において特定された攻撃コードの開始アドレスから順に比較し、終端文字と一致するデータが格納されるアドレスを検索する。このようにして検索したアドレスを、攻撃コードの終端アドレスとして特定することにより、攻撃コードが格納されるアドレス範囲を特定する。
【０１３１】
ステップＳＴ４０：
通知情報生成部１０３は、アドレス範囲特定部１０６において特定された攻撃コードのアドレス範囲に関する情報や、そのアドレス範囲に含まれる攻撃コードに関する情報を含んだ所定の通知情報を生成する。例えば、データ取得部１０５において取得されたデータの中から、アドレス範囲特定部１０６において特定されたアドレス範囲のデータを抽出し、これを攻撃コードとして通知する情報を生成しても良い。
【０１３２】
以上説明したように、図８に示すプログラムによれば、攻撃コードの開始アドレスのみならず、攻撃コードの終端アドレスも特定することにより、攻撃コードのアドレス範囲を特定することが可能になる。このため、図２に示すプログラムに比べて、攻撃コードに関するさらに詳しい情報を自動的に抽出することが可能になり、解析に要する時間とコストをより効果的に削減することができる。
【０１３３】
また、不正データの侵入経路に依存することなく、不正データの侵入を検知し、その攻撃コードを抽出することができる点は図２に示すプログラムと同じでありであり、これと同様な効果を奏することができる。
【０１３４】
＜第４の実施形態＞
次に、本発明の第４の実施形態について述べる。
【０１３５】
上述した第３の実施形態に対する本実施形態の違いは、第３の実施形態において、攻撃を受けたメモリ領域から終端文字などの所定のデータと一致するデータを検索することにより攻撃コードの終端アドレスが特定されるのに対し、本実施形態においては、プロセスへの入力データの記録結果に基づいて、攻撃コードの終端アドレスが特定される点にある。
【０１３６】
図１１は、本発明の第４の実施形態に係るプログラムの機能的な構成の一例を示すブロック図である。
【０１３７】
図１１に示すプログラムは、不正データ入力検知部１０１と、開始アドレス特定部１０２と、アドレス範囲特定部１０６Ａと、データ取得部１０５と、通知情報生成部１０３と、入力データベース１０７とを有する。ただし、図８と図１１の同一符号は、同一の構成要素を示す。
以下では、図８に示すプログラムと比較して異なる構成である、アドレス範囲特定部１０６Ａおよび入力データベース１０７について説明する。
【０１３８】
［入力データベース１０７］
入力データデータベース１０７は、プロセスの実行に伴って入力されるデータを記録するデータベースである。
【０１３９】
例えば、入力データベース１０７は、データの入力を伴う所定のライブラリ関数がプロセスによって呼び出されるたびに、ヒープ領域に対するメモリの割り当てを行い、プロセスに入力されるデータのコピーを、このヒープ領域に記憶する。
【０１４０】
図１２は、入力データベース１０７による入力データの記録方法の一例を図解した図である。
入力データベース１０７は、プロセスに対する入力データのコピーを、例えば図１２に示すような、リスト状の構造でヒープ領域に記録する。すなわち、それぞれ入力データが格納されるメモリ領域の先頭部分にアドレスを付加し、この付加アドレスによって、次に入力されるデータのメモリ領域の先頭アドレスを指示する。
入力データベース１０７は、新たなデータがプロセスに入力されると、図１２に示すようなリストの先頭に、この入力データのコピーを記録する。
【０１４１】
［アドレス範囲特定部１０６Ａ］
アドレス範囲特定部１０６Ａは、データ取得部１０５において取得された攻撃後のメモリ領域のデータと、入力データベース１０７において記録された入力データとを、開始アドレス特定部１０２で特定された攻撃コードの開始アドレスから順に比較し、記録された入力データと一致するデータが格納されるアドレスを検索する。
例えば、アドレス範囲特定部１０６Ａは、入力データベース１０７に記録される直近の入力データから順にデータ取得部１０５の取得データとの比較を行い、入力データと一致する取得データの終端のアドレスから、攻撃コードの終端のアドレスを特定する。
【０１４２】
上述した構成を有する図１１に示すプログラムの処理は、ステップＳＴ７０において、入力データベース１０７に記録される入力データとデータ取得部１０５の取得データとの比較により、攻撃コードの終端のアドレスが特定される点を除いて、図１０のフローチャートに示す処理と同じである。
【０１４３】
以上説明したように、図１１に示すプログラムにおいても、図８に示すプログラムと同様に、攻撃コードのアドレス範囲を特定可能であり、これと同様な効果を奏することができる。
更に、図１１に示すプログラムによれば、プロセスの入力データに基づいて攻撃コードの検索を行なうので、終端文字を含まない攻撃コードについても、そのアドレス範囲を正確に特定することができる。
【０１４４】
＜第５の実施形態＞
次に、本発明の第５の実施形態について述べる。
【０１４５】
第５の実施形態では、上述した第１〜第４の実施形態とは異なり、予め設定されたメモリ領域のデータ（例えばスタック領域のデータ）が実行すべき命令コードとしてＣＰＵにフェッチされた場合に、この命令コードのアドレスを指示する命令ポインタに基づいて、攻撃コードのアドレスが取得される。
【０１４６】
図１３は、本発明の第５の実施形態に係るプログラムの機能的な構成の一例を示すブロック図である。
【０１４７】
図１３に示すプログラムは、命令コード取得検知部１０８と、開始アドレス特定部１０２Ａと、アドレス範囲特定部１０６と、データ取得部１０５Ａと、通知情報生成部１０３とを有する。ただし、図８と図１３の同一符号は、同一の構成要素を示す。
以下では、図８に示すプログラムと比較して異なる構成である、命令コード取得検知部１０８、開始アドレス特定部１０２Ａ、およびデータ取得部１０５Ａについて説明する。
【０１４８】
［命令コード取得検知部１０８］
命令コード取得検知部１０８は、予め命令の実行を禁止する領域として設定されたメモリ領域のデータが、実行すべき命令コードとしてＣＰＵ１０にフェッチされたか否かを検知する。そして、この実行不可のメモリ領域から命令フェッチが行なわれた場合、命令コード取得検知部１０８は、この命令コードを実行しようとしたプロセスを強制終了させる。例えば、命令コード取得検知部１０８は、オペレーティング・システムに対して、このプロセスの強制終了を指示する。
【０１４９】
［開始アドレス特定部１０２Ａ］
開始アドレス特定部１０２Ａは、命令コード取得検知部１０８において、禁止されたメモリ領域における命令フェッチが検知された場合、ＥＩＰレジスタ１３に格納される命令ポインタに基づいて、攻撃コードの開始アドレスを特定する。
【０１５０】
図１４は、メモリ上に書き込まれた攻撃コードの開始アドレスがＣＰＵによってフェッチされた状態を図解した図である。
図１４に示すように、予め設定された実行不可のメモリ領域に攻撃コードの開始アドレスが含まれている場合、命令コード取得検知部１０８は、このアドレスがＥＩＰレジスタ１３に格納されたところで、プロセスを強制終了させる。したがって、開始アドレス特定部１０２Ａは、命令コード取得検知部１０８において禁止された命令フェッチが検知されたときのＥＩＰレジスタ１３の命令ポインタを参照することにより、攻撃コードの開始アドレスを特定することができる。
【０１５１】
［データ取得部１０５Ａ］
命令コード取得検知部１０８の指示に応じてプロセスが強制終了した場合、この強制終了したプロセスに対応するメモリ領域のデータを取得する。
【０１５２】
例えば、オペレーティング・システムは、命令コード取得検知部１０８の指示に応じてプロセスを強制終了させる場合、そのプロセスのメモリイメージであるコアダンプ（core dump）ファイルを生成する。データ取得部１０５Ａは、強制終了したプロセスのコアダンプファイルを取得し、コアダンプファイルのフォーマットと、オペレーティング・システムによって設定されているスタック領域のメモリ割り当てとに従って、そのプロセスのスタックだったメモリ領域を割り出す。そして、割り出したメモリ領域を、アドレス範囲特定部１０６を実現するプロセスのメモリ領域にマップし、攻撃を受けたプロセスの終了時におけるスタックの状態を復元する。
【０１５３】
次に、上述した構成を有する図１３に示すプログラムの処理について、図１５のフローチャートを参照して説明する。
【０１５４】
ステップＳＴ１０，ＳＴ８０：
命令コード取得検知部１０８は、通常プロセス（ステップＳＴ１０）の処理過程において、禁止されたメモリ領域からの命令フェッチの有無を監視する（ステップＳＴ８０）。
禁止されたメモリ領域からの命令フェッチが検知されない場合、命令コード取得検知部１０８は、プロセスの処理（ステップＳＴ１０）を通常通り進行させる。
禁止されたメモリ領域からの命令フェッチが検知された場合、命令コード取得検知部１０８は、開始アドレス特定部１０２Ａへこの違反の発生を通知するとともに、禁止された命令コードを実行させようとしたプロセスの強制終了をオペレーティング・システムに指示する。この指示に応じて、オペレーティング・システムは、当該プロセスを強制終了させ、そのコアダンプファイルを生成する。
【０１５５】
ステップＳＴ３０Ａ：
命令フェッチ違反の発生が通知されると、開始アドレス特定部１０２Ａは、ＥＩＰレジスタ１３に格納される命令ポインタに基づいて、攻撃コードの開始アドレスを特定する。
【０１５６】
ステップＳＴ６０Ａ：
また、データ取得部１０５Ａは、スタックオーバーフローが生じたプロセスのコアダンプファイルに基づいて、そのプロセスの終了時におけるスタック領域のデータを取得する。
【０１５７】
ステップＳＴ７０，ＳＴ４０：
アドレス範囲特定部１０６、通知情報生成部１０３の処理については、図８に示すプログラムと同様である。
すなわち、アドレス範囲特定部１０６は、データ取得部１０５Ａにおいて取得されたデータと、文字列の終端を示す終端文字とを、開始アドレス特定部１０２Ａにおいて特定された攻撃コードの開始アドレスから順に比較し、終端文字と一致するデータが格納されるアドレスを検索することにより、攻撃コードが格納されるアドレス範囲を特定する。通知情報生成部１０３は、アドレス範囲特定部１０６において特定された攻撃コードのアドレス範囲に関する情報や、当該アドレス範囲に含まれる攻撃コードに関する情報を含んだ所定の通知情報を生成する。
【０１５８】
以上説明したように、図１３に示すプログラムにおいても、図２に示すプログラムと同様に、攻撃コードの開始アドレスを自動的に特定することができる。
また、図１３に示すプログラムによれば、禁止されたメモリ領域から命令フェッチが行なわれるか否かによって不正データの入力が検知されるため、既に述べた実施形態と同様に、不正データの侵入経路に依存することなく、不正データの侵入を検知し、その攻撃コードを抽出することができる。
また、攻撃コードのアドレス範囲を自動的に抽出できる点については、図８に示すプログラムと同じであり、同様な効果を奏することができる。
【０１５９】
なお、本発明は上述した実施形態に限定されない。
例えば、本発明のプログラムは、上述した実施形態のようにＲＯＭ４０に予め書き込まれたものでも良いし、記憶装置２０から読み出したものでも良い。あるいは、入出力部３０において光ディスクなどの記録媒体から読み出したものや、ネットワークを介して他の機器から入力したものでも良い。あるいは、上述のような幾つかの方法によって取得されたプログラムの部分データを組み合わせたものでも良い。
【０１６０】
また、本発明は、上述した実施形態のように、プログラムによって実現することも可能であるが、その一部または全部の処理を、専用のハードウェアによって実行させることも可能である。すなわち、図２、図６、図８、図１１、図１３に示すブロック図において、機能ブロックの一部または全部をハードウェアの回路に置き換えることも可能である。その場合の回路は、ＣＰＵと同一の半導体チップ上に形成しても良いし、別のチップ上に形成しても良い。
【０１６１】
また、本明細書における「不正データの入力」とは、コンピュータに不正データが入力されることを広く意味する。
例えば、入力命令の実行によりスタック上のローカル変数領域に不正データが入力される場合に加えて、入出力部３０においてネットワークや記録媒体などから不正データが入力される場合や、記憶装置２０やＲＡＭ５０に既に格納された不正データがＣＰＵ１０によって処理される場合なども、「不正データの入力」に含まれる。
したがって、不正データ入力検知部における不正データの入力検知方法は、上述した実施形態に限定されない。すなわち不正データ入力検知部は、例えば、不正な入力データに含まれる特定のデータ・パターンや、ファイル名、データの送信元のネットワーク・アドレスなど、不正データの入力を特徴付けるさまざまな情報に基づいて、これを検知しても良い。
【図面の簡単な説明】
【０１６２】
【図１】本発明の実施形態に係るコンピュータの構成の一例を示すブロック図である。
【図２】本発明の第１の実施形態に係るプログラムの機能的な構成の一例を示すブロック図である。
【図３】図２に示すプログラムにおける処理の流れの一例を図解したフローチャートである。
【図４】図２に示すプログラムにおいて不正データの入力が検出された場合におけるスタックの状態の一例を図解した図である。
【図５】スタックオーバーフローを起こしたスタック・フレーム上に、新たに呼び出された関数のためのスタック・フレームが積まれる様子を図解した図である。
【図６】本発明の第２の実施形態に係るプログラムの機能的な構成の一例を示すブロック図である。
【図７】図６に示すプログラムにおける処理の流れの一例を図解したフローチャートである。
【図８】本発明の第３の実施形態に係るプログラムの機能的な構成の一例を示すブロック図である。
【図９】スタックスマッシング攻撃によってメモリに書き込まれた攻撃コードの一例を図解した図である。
【図１０】図８に示すプログラムにおける処理の流れの一例を図解したフローチャートである。
【図１１】本発明の第４の実施形態に係るプログラムの機能的な構成の一例を示すブロック図である。
【図１２】入力データベースによる入力データの記録方法の一例を図解した図である。
【図１３】本発明の第５の実施形態に係るプログラムの機能的な構成の一例を示すブロック図である。
【図１４】メモリ上に書き込まれた攻撃コードの開始アドレスがＣＰＵによってフェッチされた状態を図解した図である。
【図１５】図１３に示すプログラムにおける処理の流れの一例を図解したフローチャートである。
【図１６】Ｃ言語のソース・コードの一例を示す図である。
【図１７】図１６に示すソース・コードが実行された場合におけるスタックの状態の一例を図解した図である。
【図１８】スタックオーバーフローが発生した場合におけるスタックの状態の一例を図解した図である。
【図１９】スタックスマッシング攻撃によって攻撃コードが実行される様子を図解した図である。
【図２０】非特許文献１の方法によるスタックスマッシング攻撃の防御方法を説明するための図である。
【図２１】非特許文献２の方法によるスタックスマッシング攻撃の防御方法を説明するための第１の図である。
【図２２】非特許文献２の方法によるスタックスマッシング攻撃の防御方法を説明するための第２の図である。
【符号の説明】
【０１６３】
１０…ＣＰＵ、１１〜１３…レジスタ、２０…記憶装置、３０…入出力部、４０…プログラムメモリ、５０…ＲＡＭ、１０１，１０１Ａ…不正データ入力検知部、１０２，１０２Ａ…開始アドレス特定部、１０３…通知情報生成部、１０４…強制オーバーフロー部、１０５，１０５Ａ…データ取得部、１０６，１０６Ａ…アドレス範囲特定部、１０７…入力データベース
【図１】
2005032182.tif 000003
【図２】
2005032182.tif 000004
【図３】
2005032182.tif 000005
【図４】
2005032182.tif 000006
【図５】
2005032182.tif 000007
【図６】
2005032182.tif 000008
【図７】
2005032182.tif 000009
【図８】
2005032182.tif 000010
【図９】
2005032182.tif 000011
【図１０】
2005032182.tif 000012
【図１１】
2005032182.tif 000013
【図１２】
2005032182.tif 000014
【図１３】
2005032182.tif 000015
【図１４】
2005032182.tif 000016
【図１５】
2005032182.tif 000017
【図１６】
2005032182.tif 000018
【図１７】
2005032182.tif 000019
【図１８】
2005032182.tif 000020
【図１９】
2005032182.tif 000021
【図２０】
2005032182.tif 000022
【図２１】
2005032182.tif 000023
【図２２】
2005032182.tif 000024