(57)【要約】      （修正有）【課題】不正アクセスの検出精度を高める。【解決手段】所定の関数の呼び出しを検出し、関数の検出が行われた際に、スタック領域に格納されているリターンアドレスを取得し（Ｓ９０１）、検出された関数が、メモリ上の指定されたアドレス範囲の領域に実行可能属性を付与する関数であり（Ｓ９０３でＹＥＳ）、リターンアドレスの指し示す先の１つ前の命令が関数の呼び出し命令でない場合（Ｓ９０４でＮＯ）に、当該アドレス範囲をアドレス範囲記憶部に記憶し（Ｓ９０５）、検出された関数のリターンアドレスがアドレス範囲記憶部に記憶されているアドレス範囲内である場合（Ｓ９０６でＹＥＳ）に、不正アクセスが行われていると判定する（Ｓ９０７）。【選択図】図９
2013131157.tif 000002
【特許請求の範囲】
【請求項１】
コンピュータを、
所定の関数の呼び出しを検出する呼び出し検出部と、
前記関数の検出が行われた際に、スタック領域に格納されているリターンアドレスを取得するリターンアドレス取得部と、
前記検出された関数が、メモリ上の指定されたアドレス範囲の領域に実行可能属性を付与する関数であり、前記リターンアドレスの指し示す先の１つ前の命令が関数の呼び出し命令でない場合に、当該アドレス範囲をアドレス範囲記憶部に記憶する属性変更検出部と、
前記リターンアドレスが前記アドレス範囲記憶部に記憶されている前記アドレス範囲内である場合に、不正アクセスが行われていると判定する不正アクセス検出部と、
して機能させるためのプログラム。
【請求項２】
請求項１に記載のプログラムであって、
前記リターンアドレス取得部は、前記関数の検出が行われた際に、前記スタック領域に格納されている複数のリターンアドレスを順次取得し、
前記属性変更検出部は、前記順次取得されるリターンアドレスのそれぞれについて、前記検出された関数が、メモリ上の指定されたアドレス範囲の領域に実行可能属性を付与する関数であり、前記リターンアドレスの指し示す先の１つ前の命令が関数の呼び出し命令でない場合に、当該アドレス範囲を前記アドレス範囲記憶部に記憶し、
前記不正アクセス検出部は、前記順次取得されるリターンアドレスのそれぞれについて、前記リターンアドレスが前記アドレス範囲記憶部に記憶されている前記アドレス範囲内である場合に、不正アクセスが行われていると判定する、
プログラム。
【請求項３】
所定の関数の呼び出しを検出する呼び出し検出部と、
前記関数の検出が行われた際に、スタック領域に格納されているリターンアドレスを取得するリターンアドレス取得部と、
前記検出された関数が、メモリ上の指定されたアドレス範囲の領域に実行可能属性を付与する関数であり、前記リターンアドレスの指し示す先の１つ前の命令が関数の呼び出し命令でない場合に、当該アドレス範囲をアドレス範囲記憶部に記憶する属性変更検出部と、
前記リターンアドレスが前記アドレス範囲記憶部に記憶されている前記アドレス範囲内である場合に、不正アクセスが行われていると判定する不正アクセス検出部と、
を備える情報機器。
【請求項４】
コンピュータが、
所定の関数の呼び出しを検出し、
前記関数の検出が行われた際に、スタック領域に格納されているリターンアドレスを取得し、
前記検出された関数が、メモリ上の指定されたアドレス範囲の領域に実行可能属性を付与する関数であり、前記リターンアドレスの指し示す先の１つ前の命令が関数の呼び出し命令でない場合に、当該アドレス範囲をアドレス範囲記憶部に記憶し、
前記リターンアドレスが前記アドレス範囲記憶部に記憶されている前記アドレス範囲内である場合に、不正アクセスが行われていると判定する、
不正アクセス検出法方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、プログラム、情報機器、及び不正アクセス検出方法に関する。
【背景技術】
【０００２】
近年、不正なプログラムコードがコンピュータにおいて実行されることにより、個人情報や機密情報が流出する事件が後をたたず、社会問題となっている。このような不正なプログラムコードの実行、すなわち、不正アクセスを行うためのプログラム等は、マルウェアとも呼ばれ、ソフトウェアの脆弱性を利用するものが多い。例えば、ソフトウェアの脆弱性としては、バッファオーバーフローが良く知られている。バッファオーバーフローとは、例えば、プログラムで用いられる変数に、当該変数のために確保された領域より大きいサイズの文字列等が入力されることにより、他の領域に文字列等が書き込まれてしまうことである。
【０００３】
プログラムで関数が呼び出される際には、当該関数の呼び出し元へと戻ることを可能とするために、戻り先のアドレス（リターンアドレス）がスタックへと格納される。マルウェアは、例えば、関数の脆弱性を利用することにより、関数の実行時にバッファオーバーフローを発生させ、リターンアドレスを不正なアドレスへと書き換える。この不正なアドレスは、例えば、プログラムコードが格納されるメモリ領域ではなく、データ領域を指しており、このデータ領域には不正なプログラムコードが格納されている。また、不正なアドレスは、例えば、不正アクセスのために使用される別の関数の開始アドレスである場合もある。この状態で関数の実行が終了すると、プログラムの実行は、当該関数の呼び出し元ではなく、不正なアドレスへと遷移することとなる。これにより、この不正なアドレスに格納されているプログラムコードが実行され、不正アクセスが行われることとなる。
【０００４】
このような不正アクセスを検出するための様々な手法が提案されている。例えば、特許文献１に開示されている手法では、プログラムコードは、プログラムコードのためのメモリ領域、または、書き込み不可能な属性となっているデータ領域の何れかに格納されるという特性が利用されている。具体的には、例えば、リターンアドレスの指し示す先が、プログラムコードを格納するためのメモリ領域でなければ不正アクセスであると判断される。また、例えば、リターンアドレスの指し示す先の属性が、書込み可能となっていれば不正アクセスであると判断される。
【０００５】
また、例えば、特許文献２には、Ｒｅｔｕｒｎ−ｔｏ−ＬｉｂｃやＲＯＰ（Ｒｅｔｕｒｎ  Ｏｒｉｅｎｔｅｄ  Ｐｒｏｇｒａｍｍｉｎｇ）と呼ばれる攻撃手法による不正アクセスを検出するための手法が開示されている。例えば、リターンアドレスの指し示す先が関数の開始アドレスであるか、リターンアドレスの指し示す先の１つ前の命令が関数の呼び出し命令（ｃａｌｌ命令）でなければ不正アクセスであると判断される。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】特開２００９−１９９５２９号公報
【特許文献２】特開２０１０−２５７２７５号公報
【発明の概要】
【発明が解決しようとする課題】
【０００７】
しかしながら、例えば、正常なプログラムの中には、メモリ上のデータ領域に別のプログラムコードを展開したうえで、当該データ領域に実行属性を付与し、当該プログラムコードを実行するものがある。この場合、当該データ領域には実行属性とともに書き込み属性も付与されているため、特許文献１に開示されている手法を適用すると、不正アクセスであると誤って検出されることとなる。また、正常なプログラムの中には、ｃａｌｌ命令を用いずに関数呼び出しを行うものもある。そのため、このようなプログラムに特許文献２に開示されている手法を適用すると、不正アクセスであると誤って検出されることとなる。
そこで、本発明は、不正アクセスの検出精度を高めることを目的とする。
【課題を解決するための手段】
【０００８】
本発明の一側面に係るプログラムは、コンピュータを、所定の関数の呼び出しを検出する呼び出し検出部と、関数の検出が行われた際に、スタック領域に格納されているリターンアドレスを取得するリターンアドレス取得部と、検出された関数が、メモリ上の指定されたアドレス範囲の領域に実行可能属性を付与する関数であり、リターンアドレスの指し示す先の１つ前の命令が関数の呼び出し命令でない場合に、当該アドレス範囲をアドレス範囲記憶部に記憶する属性変更検出部と、検出された関数のリターンアドレスがアドレス範囲記憶部に記憶されているアドレス範囲内である場合に、不正アクセスが行われていると判定する不正アクセス検出部と、して機能させるためのものである。
【０００９】
さらに、リターンアドレス取得部は、関数の検出が行われた際に、スタック領域に格納されている複数のリターンアドレスを順次取得し、属性変更検出部は、順次取得されるリターンアドレスのそれぞれについて、検出された関数が、メモリ上の指定されたアドレス範囲の領域に実行可能属性を付与する関数であり、リターンアドレスの指し示す先の１つ前の命令が関数の呼び出し命令でない場合に、当該アドレス範囲をアドレス範囲記憶部に記憶し、不正アクセス検出部は、順次取得されるリターンアドレスのそれぞれについて、リターンアドレスがアドレス範囲記憶部に記憶されているアドレス範囲内である場合に、不正アクセスが行われていると判定することとしてもよい。
【００１０】
また、本発明の一側面に係る情報機器は、所定の関数の呼び出しを検出する呼び出し検出部と、関数の検出が行われた際に、スタック領域に格納されているリターンアドレスを取得するリターンアドレス取得部と、検出された関数が、メモリ上の指定されたアドレス範囲の領域に実行可能属性を付与する関数である場合に、当該アドレス範囲をアドレス範囲記憶部に記憶する属性変更検出部と、検出された関数のリターンアドレスがアドレス範囲記憶部に記憶されているアドレス範囲内である場合に、不正アクセスが行われていると判定する不正アクセス検出部と、を備える。
【００１１】
また、本発明の一側面に係る不正アクセス検出方法では、コンピュータが、所定の関数の呼び出しを検出し、関数の検出が行われた際に、スタック領域に格納されているリターンアドレスを取得し、検出された関数が、メモリ上の指定されたアドレス範囲の領域に実行可能属性を付与する関数である場合に、当該アドレス範囲をアドレス範囲記憶部に記憶し、検出された関数のリターンアドレスがアドレス範囲記憶部に記憶されているアドレス範囲内である場合に、不正アクセスが行われていると判定する。
【００１２】
なお、本発明において、「部」とは、単に物理的手段を意味するものではなく、その「部」が有する機能をソフトウェアによって実現する場合も含む。また、１つの「部」や装置が有する機能が２つ以上の物理的手段や装置により実現されても、２つ以上の「部」や装置の機能が１つの物理的手段や装置により実現されてもよい。
【発明の効果】
【００１３】
本発明によれば、不正アクセスの検出精度を高めることができる。
【図面の簡単な説明】
【００１４】
【図１】本発明の一実施形態である情報機器のハードウェア構成の一例を示す図である。
【図２】情報機器において実現される機能部の構成例を示す図である。
【図３】スタック領域の構造の一例を示す図である。
【図４】脆弱性のあるプログラムが実行されている際のメモリマップの一例を示す図である。
【図５】バッファオーバーフローの脆弱性により、スタック領域に上書きされた攻撃コードの一例を示す図である。
【図６】攻撃コードの動作の一例を示す図である。
【図７】攻撃コードの動作の一例を示す図である。
【図８】攻撃コードの動作の一例を示す図である。
【図９】不正アクセスの検出処理の一例を示すフローチャートである。
【発明を実施するための形態】
【００１５】
以下、図面を参照して本発明の一実施形態について説明する。
＝＝構成＝＝
【００１６】
まず、本発明の一実施形態である情報機器の構成について説明する。図１は、本発明の一実施形態である情報機器のハードウェア構成の一例を示す図である。図１に示すように、情報機器１０は、プロセッサ２０、メモリ２２、記憶装置２４、入力インタフェース（Ｉ／Ｆ）２６、データインタフェース（Ｉ／Ｆ）２８、通信インタフェース（Ｉ／Ｆ)３０、及び表示装置３２を含んで構成されている。情報機器１０は、例えば、パーソナルコンピュータや携帯情報端末等の情報処理装置である。
【００１７】
プロセッサ２０は、メモリ２２に記憶されているプログラムを実行することにより情報機器１０における様々な処理の実行を制御する。なお、図１には示していないが、プロセッサ２０は、命令やアドレスを記憶するための各種レジスタを備えている。本実施形態では、プロセッサ２０の構成は、インテル（登録商標）社が開発した３２ビットマイクロプロセッサのアーキテクチャであるＩＡ−３２を前提として説明する。なお、プロセッサ２０の構成はこれに限られず、任意の構成を採用することができる。
【００１８】
メモリ２２は、例えばＲＡＭ（Ｒａｎｄｏｍ  Ａｃｃｅｓｓ  Ｍｅｍｏｒｙ）等の記憶領域であり、プロセッサ２０によって実行されるプログラムのプログラムコードや、プログラムの実行時に必要となるデータを一時的に記憶する。例えば、メモリ２２の記憶領域には、プログラムの実行時に必要となるスタック領域が確保される。
【００１９】
記憶装置２４は、例えばハードディスクやフラッシュメモリ等の記憶領域であり、オペレーティングシステムをはじめとした各種プログラムや、各種データ等が記憶される。記憶装置２４に記憶されているプログラムやデータは、必要に応じてメモリ２２にロードされ、プロセッサ２０により参照される。
【００２０】
入力Ｉ／Ｆ２６は、ユーザからの入力を受け付けるためのデバイスであり、例えば、キーボードやマウス、タッチパネル、各種センサ等である。入力Ｉ／Ｆ２６は、例えば、ＵＳＢ（Ｕｎｉｖｅｒｓａｌ  Ｓｅｒｉａｌ  Ｂｕｓ）等のインタフェースを介して情報機器１０の外部に設けられていてもよい。
【００２１】
データＩ／Ｆ２８は、情報機器１０の外部からデータを入力するためのデバイスであり、例えば、各種記憶媒体に記憶されているデータを読み取るためのドライブ装置等である。データＩ／Ｆ２８は、ＵＳＢ等のインタフェースを介して情報機器１０の外部に設けられていてもよい。
【００２２】
通信Ｉ／Ｆ３０は、情報機器１０の外部の装置との間でデータ通信を行うためのデバイスであり、例えば、有線または無線によりデータ通信を行うことができる。通信Ｉ／Ｆ３０は、ＵＳＢ等のインタフェースを介して情報機器１０の外部に設けられていてもよい。
【００２３】
表示装置３２は、各種情報を表示するためのデバイスであり、例えば、液晶ディスプレイや有機ＥＬ（Ｅｌｅｃｔｒｏ−Ｌｕｍｉｎｅｓｃｅｎｓｅ）ディスプレイ等である。表示装置３２は、ディスプレイケーブル等を介して情報機器１０の外部に設けられていてもよい。
【００２４】
図２は、情報機器１０において実現される機能部の構成例を示す図である。図２に示される機能部は、例えば、メモリ２２上の記憶領域を用いたり、メモリ２２に記憶されているプログラムをプロセッサ２０が実行したりすることにより実現することができる。
【００２５】
図２に示すように、情報機器１０は、呼び出し検出部４０、リターンアドレス取得部４２、属性変更検出部４４、アドレス範囲記憶部４６、及び不正アクセス検出部４８を含んで構成することができる。
【００２６】
呼び出し検出部４０は、情報機器１０において、所定のＡＰＩ（Ａｐｐｌｉｃａｔｉｏｎ  Ｐｒｏｇｒａｍ  Ｉｎｔｅｒｆａｃｅ）関数の呼び出しを検出することができる。呼び出し検出部４０による関数の呼び出し検出は、例えば、任意の手法によるフックを用いることにより行うことができる。本実施形態では、Ｗｉｎｄｏｗｓ（登録商標）におけるＡＰＩ関数である、ＶｉｒｔｕａｌＰｒｏｔｅｃｔおよびＷｉｎＥｘｅｃをフックする場合を一例として説明する。なお、本実施形態では、検出する関数の一例としてＶｉｒｔｕａｌＰｒｏｔｅｃｔおよびＷｉｎＥｘｅｃを示すが、関数はこれに限られず、不正アクセスに用いられる可能性のある任意の関数を検出対象とすることができる。また、例えば、ＵＮＩＸ（登録商標）等の他の環境においても同様に、フックによりＡＰＩ関数の呼び出しを検出することができる。
【００２７】
リターンアドレス取得部４２は、呼び出し検出部４０により所定のＡＰＩ関数の呼び出しが検出された際に、スタック領域に格納されているリターンアドレスを取得する。図３に、スタック領域の構造の一例を示す。図３に示すように、スタック領域には、関数ごとに、スタックフレームという領域が確保されている。そして、図３に示すように、スタック領域におけるポインタとして、スタックポインタ（ｅｓｐ：Ｅｘｔｅｎｄｅｄ  Ｓｔａｃｋ  Ｐｏｉｎｔｅｒ）およびベースポインタ（ｅｂｐ：Ｅｘｔｅｎｄｅｄ  Ｂａｓｅ  Ｐｏｉｎｔｅｒ）が設けられている。スタックポインタは、スタックの一番上の場所を示すものであり、その値はスタックポインタレジスタに格納されている。また、ベースポインタは、実行中の関数のスタックフレームの底（ベース）の場所を示すものであり、その値はベースポインタレジスタに格納されている。
【００２８】
そして、ベースポインタが指し示す場所には、呼び出し元の関数のスタックフレームにおけるベースのアドレス（ｅｂｐ  Ｂａｃｋｕｐ）が格納され、その下にはリターンアドレスが格納されている。したがって、リターンアドレス取得部４２は、ベースのアドレスを辿ることにより、スタック領域に格納されている複数のリターンアドレスを順次取得することができる。このようにベースのアドレスを辿ることにより複数のリターンアドレスを順次取得する処理は、バックトレースと呼ばれる。
【００２９】
ただし、アプリケーションの中にはこの規定に従わない関数が存在し、ｅｂｐ  Ｂａｃｋｕｐには不正な値が格納されている可能性がある。そのため、リターンアドレス取得部４２は、ｅｂｐ  Ｂａｃｋｕｐに格納されたアドレスがスタック領域の範囲外であるか、それが格納されているアドレスよりも小さいアドレスであるときは不正な値であると判断し、バックトレースを終了する。
【００３０】
属性変更検出部４４は、呼び出し検出部４０により検出された関数が、メモリ上の指定されたアドレス範囲の領域に実行可能属性を付与する関数である場合に、当該アドレス範囲を、メモリ２２上で確保された領域であるアドレス範囲記憶部４６に記憶する。本実施形態では、属性変更検出部４４は、呼び出し検出部４０によってＶｉｒｔｕａｌＰｒｏｔｅｃｔの呼び出しが検出され、当該関数により、指定されたアドレス範囲の領域に実行属性が付与される場合には、当該アドレス範囲をアドレス範囲記憶部４６に記憶する。ＶｉｒｔｕａｌＰｒｏｔｅｃｔは、属性変更の対象領域の先頭のアドレス（第１引数）、対象領域のサイズ（第２引数）、変更後の属性（第３引数）、変更前の属性の保存先（第４引数）の４つの引数を取る。そのため、属性変更検出部４４は、ＶｉｒｔｕａｌＰｒｏｔｅｃｔの呼び出しが検出された際には、第３引数により、実行可能属性を付与するものであるかを判断し、第１引数及び第２引数により、属性変更のアドレス範囲を取得することができる。なお、アドレス範囲記憶部４６に記憶されるアドレス範囲の情報の形式は任意である。例えば、アドレス範囲の開始アドレスと最終アドレスが記憶されることとしてもよいし、アドレス範囲の開始アドレスとアドレス範囲のサイズが記憶されることとしてもよい。
【００３１】
また、属性変更検出部４４は、リターンアドレス取得部４２により取得されたリターンアドレスを考慮することができる。具体的には、属性変更検出部４４は、ＶｉｒｔｕａｌＰｒｏｔｅｃｔにより、指定されたアドレス範囲の領域に実行属性が付与される場合であって、取得されたリターンアドレスの指し示す先の１つ前の命令がｃａｌｌ命令（呼び出し命令）でない場合に、当該アドレス範囲をアドレス範囲記憶部４６に記憶することができる。リターンアドレス取得部４２により複数のリターンアドレスが順次取得される場合、属性変更検出部４４は、各リターンアドレスについて当該判定を行うことができる。
【００３２】
不正アクセス検出部４８は、リターンアドレス取得部４２により取得されたリターンアドレスが、アドレス範囲記憶部４６に記憶されているアドレス範囲内である場合に、不正アクセスが行われていると判定する。本実施形態では、不正アクセス検出部４８は、例えば、呼び出し検出部４０によってＷｉｎＥｘｅｃの呼び出しが検出され、リターンアドレス取得部４２により取得されたリターンアドレスが、アドレス範囲記憶部４６に記憶されているアドレス範囲内である場合に、不正アクセスが行われていると判定する。リターンアドレス取得部４２により複数のリターンアドレスが順次取得される場合、不正アクセス検出部４８は、各リターンアドレスについて当該判定を行うことができる。
【００３３】
＝＝不正アクセスの検出処理＝＝
次に、情報機器１０における不正アクセスの検出処理について説明する。図４は、脆弱性のあるプログラムが実行されている際のメモリマップの一例を示す図である。図４に示す例では、０ｘ６５３０００００〜０ｘ６５４７ＦＦＦＦ番地までの１．５ＭＢの領域にプログラムコードが配置され、０ｘ６５４８００００〜０ｘ６５４ＦＦＦＦ番地までの０．５ＭＢの領域に静的データが配置されている。このプログラムには、バッファオーバーフローを引き起こす可能性のある、脆弱性のある関数が含まれている。なお、図４に示すように、プログラム領域の０ｘ６５４０１１２２番地には０ｘ５４が格納され、０ｘ６５４０１１２３番地には０ｘＣ３が格納されている。ＩＡ−３２において、０ｘ５４はｐｕｓｈ  ｅｓｐ命令、０ｘＣ３はｒｅｔ命令である。ｐｕｓｈ  ｅｓｐ命令は、スタックポインタレジスタに記憶されている値をスタック領域にプッシュするための命令である。また、ｒｅｔ命令は、呼び出された関数から呼び出し元の関数へと制御を戻すための命令である。本実施形態では、これらのｐｕｓｈ  ｅｓｐ命令およびｒｅｔ命令は、不正アクセスを行うための攻撃コードによって利用されることとなる。
【００３４】
図５は、図４に示したプログラムにおけるバッファオーバーフローの脆弱性により、スタック領域に上書きされた攻撃コードの一例を示す図である。図５の例では、スタック領域は４バイト（ダブルワード）幅で構成されており、攻撃コードは１６進数で示されている。図５に示す例では、攻撃コードはブロックＡ〜ブロックＣの３つのブロックにより構成されている。
【００３５】
ブロックＡは、ＶｉｒｔｕａｌＰｒｏｔｅｃｔ関数を呼び出すことにより、データ領域に実行属性を付与するためのＲＯＰ（Ｒｅｔｕｒｎ  Ｏｒｉｅｎｔｅｄ  Ｐｒｏｇｒａｍｍｉｎ）のプログラムコードである。ブロックＡのスタック領域の右側には、各ダブルワードの意味が示されている。先頭のダブルワードは、本来であれば、呼び出し元の関数へと戻るためのリターンアドレスが格納される領域であるが、ＶｉｒｔｕａｌＰｒｏｔｅｃｔ関数のアドレスに上書きされている。なお、ＶｉｒｔｕａｌＰｒｏｔｅｃｔ関数のアドレスはＷｉｎｄｏｗｓ（登録商標）のバージョンや実行環境により異なるが、図５の例では、０ｘ７Ｃ８０１ＡＤ０としている。そして、図５に示すように、ブロックＡには、ｒｅｔ命令のドレス（０ｘ６５４０１１２３）、ＶｉｒｔｕａｌＰｒｏｔｅｃｔ関数の引数、ｐｕｓｈ  ｅｓｐ命令のアドレス（０ｘ６５４０１１２２）が格納されている。
【００３６】
ブロックＢは、ＶｉｒｔｕａｌＰｒｏｔｅｃｔ関数により実行属性が付与されたデータ領域に攻撃コード本体をコピーするプログラムコードである。ブロックＢのスタック領域の右側には、当該プログラムコードのアセンブリ言語表記が示されている。このブロックＢのプログラムコードは、プロセッサ２０がこのスタック領域を参照することにより実行される。
【００３７】
ブロックＣは、ブロックＢのプログラムコードによってデータ領域にコピーされる攻撃コード本体である。ブロックＣのスタック領域の右側には、当該プログラムコードのアセンブリ言語表記が示されている。このブロックＣのプログラムコードは、プロセッサ２０がコピー先のデータ領域を参照することにより実行される。なお、図５に示す例では、説明を簡単にするために、攻撃コード本体では、ＷｉｎＥｘｅｃ（”ｃａｌｃ”，１）が実行され、電卓アプリケーションが起動されるのみとなっている。実際に用いられる攻撃コードでは、不正アクセスを行うための任意のアプリケーションや関数が起動される。
【００３８】
図６〜図８を参照して、図５に示した攻撃コードの動作について説明する。図６〜図８において、ｅｓｐはスタックポインタ、ｅｉｐ（Ｅｘｔｅｎｄｅｄ  Ｉｎｓｔｒｕｃｔｉｏｎ  Ｐｏｉｎｔｅｒ）は命令ポインタを示している。命令ポインタは、プロセッサ２０が次に実行する命令のアドレスを保持するものであり、その値は命令ポインタレジスタに格納されている。図６〜図８に示す例では、状態Ｓ１から状態Ｓ９までの状態変化が示されている。
【００３９】
図６に示す状態Ｓ１は、図４に示した脆弱性のある関数の実行によりスタック領域が上書きされ、当該関数から呼び出し元の関数へとリターンする直前の状態を示している。このとき、ｅｓｐは攻撃コードの先頭を示している。そして、ｅｉｐは脆弱性のある関数から呼び出し元の関数に制御を戻すためのｒｅｔ命令（リターン命令）の位置を指している。プロセッサ２０は、ｅｉｐに従ってｒｅｔ命令を実行し、ｅｓｐが指していた場所の内容、すなわち、ＶｉｒｔｕａｌＰｒｏｔｅｃｔ関数のアドレス０ｘ７Ｃ８０１ＡＤ０をｅｉｐに設定し、ｅｓｐを１ダブルワード（４バイト）増加させる。これにより、状態Ｓ２へと遷移する。すなわち、脆弱性のある関数の呼び出し元ではなく、ＶｉｒｔｕａｌＰｒｏｔｅｃｔ関数へ遷移することとなる。
【００４０】
状態Ｓ２では、プロセッサ２０は、ｅｉｐに従ってＶｉｒｔｕａｌＰｒｏｔｅｃ関数を実行する。このとき、ＶｉｒｔｕａｌＰｒｏｔｅｃｔ関数は、ｅｓｐが指す場所の次のダブルワードから順に４つのダブルワードを引数として受け取る。第１引数０ｘ６５４８００００は、属性変更の対象領域の先頭アドレスであり、第２引数０ｘ００００１０００は対象領域のサイズである。図４を参照すると、このアドレス範囲は、静的変数１のアドレス範囲となっている。第３引数０ｘ００００００４０は、変更後の属性が「読み出し、書き込み、実行」の全属性であることを示している。第４引数０ｘ６５４８１０００は、変更前の属性の保存先であり、図４を参照すると、静的変数２の領域が変更前の属性の保存先として設定されていることがわかる。これにより、静的変数１の４０９６バイトの領域に、「読み出し、書き込み、実行」の属性が付与される。
【００４１】
状態Ｓ３は、ＶｉｒｔｕａｌＰｒｏｔｅｃｔ関数からリターンする直前の状態を示している。このとき、ｅｉｐはｒｅｔ  １６命令の位置を指している。Ｗｉｎｄｏｗｓ（登録商標）のＡＰＩの場合、関数からリターンする際にはｅｓｐは引数領域の次のアドレスまで移動される。したがって、プロセッサ２０は、ＶｉｒｔｕａｌＰｒｏｔｅｃｔ関数のｒｅｔ  １６命令を実行すると、ｅｓｐが指していたアドレスの値０ｘ６５４０１１２３をリターンアドレスとしてｅｉｐに設定し、ｅｓｐを５ダブルワード（２０バイト）分増加させる。これにより、図７に示す状態Ｓ４へと遷移する。
【００４２】
状態Ｓ４において、ｅｉｐが指す０ｘ６５４０１１２３番地には、ｒｅｔ命令が格納されている。そのため、プロセッサ２０は、ｅｉｐに従ってｒｅｔ命令を実行し、ｅｓｐが指している場所に格納されている０ｘ６５４０１１２２をｅｉｐに設定し、ｅｓｐを１ダブルワード（４バイト）増加させる。図４を参照すると、０ｘ６５４０１１２２番地には、０ｘ５４（ｐｕｓｈ  ｅｓｐ命令）が格納されていることがわかる。これにより、状態Ｓ５へと遷移する。
【００４３】
状態Ｓ５では、プロセッサ２０は、ｅｉｐに従ってｐｕｓｈ  ｅｓｐ命令を実行する。プロセッサ２０は、ｐｕｓｈ  ｅｓｐ命令を実行すると、ｅｓｐを１ダブルワード（４バイト）減少させ、ｅｓｐが指す場所に元のｅｓｐの値（図７の例ではｅｓｐ＋４）を格納する。また、プロセッサ２０は、ｅｉｐを１命令分先へ進める。これにより、状態Ｓ６へと遷移する。
【００４４】
状態Ｓ６では、プロセッサ２０は、ｅｉｐに従ってｒｅｔ命令を実行する。そして、プロセッサ２０は、ｅｓｐが指す場所に格納されている値（ｅｓｐ＋４）をｅｉｐにセットし、ｅｓｐを１ダブルワード（４バイト）増加させる。これにより、図８に示す状態Ｓ７へと遷移する。
【００４５】
状態Ｓ７では、ｅｓｐとｅｉｐはともに、図５に示したスタック領域上のブロックＢの先頭を指している。プロセッサ２０は、ｅｉｐに従って、ブロックＢのプログラムコードをスタック領域から順次読み出して実行していく。これにより、データ領域上の静的変数１の領域に攻撃コード本体がコピーされる。これにより、状態Ｓ８へと遷移する。
【００４６】
状態Ｓ８では、ｅｉｐはブロックＢのプログラムコードの最後の命令を指している。プロセッサ２０は、ｅｉｐに従って、静的変数１のアドレスをｅｉｐに設定するｊｍｐ命令を実行する。これにより、状態Ｓ９へと遷移する。
【００４７】
状態Ｓ９では、ｅｉｐは、データ領域上の静的変数１の領域の先頭を指している。前述したように、静的変数１の領域には、攻撃コード本体が格納されている。したがって、プロセッサ２０は、ｅｉｐに従って、攻撃コード本体のプログラムコードを静的変数１の領域から順次読み出して実行していく。これにより、プロセッサ２０は、ＷｉｎＥｘｅｃ関数により電卓アプリケーションを起動する。前述したように、ここでは電卓アプリケーションが起動されることとしたが、攻撃コード本体のプログラムコードを変更することにより、任意の処理の実行が可能となる。
【００４８】
ここで、状態Ｓ９において、ＷｉｎＥｘｅｃ関数が呼び出されたとき、リターンアドレスが指している領域である静的変数１の領域には実行属性が付与されており、通常のプログラムコードのためのメモリ領域と同様に見える。そのため、リターンアドレスの指し示す先がプログラムコードを格納するためのメモリ領域であるかどうか判断することにより不正アクセスを検出するという一般的な手法では、図４〜図８に示したような不正アクセスを検出することができない。また、リターンアドレスの指し示す先の属性が書込み可能であるかどうか判断することにより不正アクセスを検出するという一般的な手法を用いれば、当該不正アクセスの検出は可能になるものの、この手法では、前述したように誤検出の可能性がある。
【００４９】
また、状態Ｓ９において、ＷｉｎＥｘｅｃ関数が呼び出されたとき、リターンアドレスの指し示す先が関数の先頭である可能性は低い。そのため、リターンアドレスの指し示す先が関数の開始アドレスであるかどうか判断することにより不正アクセスを検出するという一般的な手法では、当該不正アクセスを検出することができない。さらに、正常なプログラムの中には、ｃａｌｌ命令を用いずに関数呼び出しを行うものもあるため、リターンアドレスの指し示す先の１つ前の命令がｃａｌｌ命令かどうか判断することにより不正アクセスを検出するという一般的な手法では誤検出の可能性がある。
【００５０】
一方、本実施形態における検出手法を用いることにより、上述したような誤検出をすることなく、不正アクセスを検出することが可能となる。以下に本実施形態における検出の手順について説明する。
【００５１】
図９は、本実施形態における不正アクセスの検出処理の一例を示すフローチャートである。図９に示す処理は、呼び出し検出部４０が、所定のＡＰＩ関数の呼び出しを検出することにより開始される。リターンアドレス取得部４２は、呼び出し検出部４０によりＡＰＩ関数の呼び出しが検出されると、図９に示すバックトレースのループ処理において、スタック領域を参照してリターンアドレスを順次取得する（Ｓ９０１）。そして、順次取得されるリターンアドレスのそれぞれについて、バックトレースのループ内の処理が実行される。
【００５２】
属性変更検出部４４は、呼び出し検出部４０により検出されたＡＰＩ関数が、例えばＶｉｒｔｕａｌＰｒｏｔｅｃｔ等のメモリ属性変更関数であるかどうか判断する（Ｓ９０２）。メモリ属性変更関数である場合（Ｓ９０２：ＹＥＳ）、属性変更検出部４４は、さらに、変更後の属性が実行属性を含むものであるかどうか判断する（Ｓ９０３）。変更後の属性が実行属性を含むものである場合（Ｓ９０３：ＹＥＳ）、属性変更検出部４４は、さらに、リターンアドレス取得部４２により取得されたリターンアドレスによって示されるリターン先の１つ前の命令がｃａｌｌ命令であるかどうか判断する（Ｓ９０４）。そして、ｃａｌｌ命令であれば（Ｓ９０４：ＹＥＳ）、属性変更検出部４４は、属性変更の対象となっている領域のアドレス範囲をアドレス範囲記憶部４６に記憶する（Ｓ９０５）。すなわち、属性変更検出部４４は、呼び出し検出部４０により検出されたＡＰＩ関数の呼び出しは攻撃コードによるものである可能性が高いとして、属性変更の対象となっている領域のアドレス範囲をアドレス範囲記憶部４６に記憶する。
【００５３】
呼び出し検出部４０により検出されたＡＰＩ関数がメモリ属性変更関数でない場合（Ｓ９０２：ＮＯ）、不正アクセス検出部４８は、リターンアドレス取得部４２により取得されたリターンアドレスが、アドレス範囲記憶部４６に記憶されているアドレス範囲内に含まれるかどうか判断する（Ｓ９０６）。また、変更後の属性に実行属性が含まれない場合（Ｓ９０３：ＮＯ）、リターンアドレスによって示されるリターン先の１つ前の命令がｃａｌｌ命令である場合（Ｓ９０４：ＮＯ）、もしくは、アドレス範囲を保存した場合（Ｓ９０５）においても、当該判定処理（Ｓ９０６）に遷移する。
【００５４】
そして、リターンアドレスがアドレス範囲内に含まれる場合（Ｓ９０６：ＹＥＳ）、不正アクセス検出部４８は、攻撃コードによる不正アクセスが行われていると判定する（Ｓ９０７）。この場合、不正アクセス検出部４８は、例えば、不正アクセスの判定結果を示す情報を出力し（Ｓ９０８）、実行中のプログラムを強制終了させる。
【００５５】
一方、リターンアドレスがアドレス範囲内に含まれない場合（Ｓ９０６：ＮＯ）、不正アクセス検出部４８は、必要に応じて、他の一般的な手法による不正アクセスの検出処理を実行する（Ｓ９０９）。
【００５６】
そして、リターンアドレス取得部４２により順次取得される複数のリターンアドレスについて上述の処理が実行された後、呼び出し検出部４０は、検出されたＡＰＩ関数の本体を実行する（Ｓ９１０）。
【００５７】
図９に示した処理により、図５に示した攻撃コードによる不正アクセスを検出する場合を説明する。まず、図６に示す状態Ｓ２において、呼び出し検出部４０が、ＶｉｒｔｕａｌＰｒｏｔｅｃｔ関数の呼び出しを検出すると、図９に示す処理が開始される。そして、リターンアドレス取得部４２は、スタック領域を参照し、リターンアドレス０ｘ６５４０１１２３を取得する（Ｓ９０１）。図６の状態Ｓ２において実行されるＶｉｒｔｕａｌＰｒｏｔｅｃｔ関数は、メモリ属性変更関数であり（Ｓ９０２：ＹＥＳ）、図４に示したデータ領域における静的変数１の領域に実行属性を付与するものである（Ｓ９０３：ＹＥＳ）。また、図４に示すように、取得されたリターンアドレス０ｘ６５４０１１２３の指し示す先の１つ前の命令はｃａｌｌ命令ではない（Ｓ９０４：ＮＯ）。したがって、属性変更検出部４４は、ＶｉｒｔｕａｌＰｒｏｔｅｃｔ関数により実行属性が付与される領域のアドレス範囲０ｘ６５４８００００〜０ｘ６５４８０ＦＦＦをアドレス範囲記憶部４６に記憶する（Ｓ９０５）。
【００５８】
そして、リターンアドレス０ｘ６５４０１１２３は保存されたアドレス範囲０ｘ６５４８００００〜０ｘ６５４８０ＦＦＦに含まれないため（Ｓ９０６：ＮＯ）、不正アクセス検出部４８は、他の一般的な手法による不正アクセスの検出処理を実行する（Ｓ９０９）。そして、リターンアドレス取得部４２は次のリターンアドレスの取得を試みるが、スタックに格納されていたベースアドレスはバッファオーバーフローにより別の値に上書きされているため不正なアドレスであると判定される。そのため、ここでバックトレース処理のループが終了し、呼び出し検出部４０は、ＡＰＩ関数の本体、すなわち、ＶｉｒｔｕａｌＰｒｏｔｅｃｔ関数を呼び出して属性変更処理を実行する（Ｓ９１０）。これにより、データ領域における静的変数１の領域に実行属性が付与される。
【００５９】
その後、図８に示す状態Ｓ９に遷移するまでの間にはＡＰＩ関数の呼び出しは行われないため、図９に示す処理は実行されない。そして、図８に示す状態Ｓ９において、呼び出し検出部４０が、ＷｉｎＥｘｅｃ関数の呼び出しを検出すると、図９に示す処理が開始される。ＷｉｎＥｘｅｃ関数の呼び出しが行われたとき、スタック領域には、ＷｉｎＥｘｅｃ関数を呼び出すｃａｌｌ命令の次の命令のアドレスがリターンアドレスとして格納されている。リターンアドレス取得部４２は、スタック領域を参照し、このリターンアドレスを取得する（Ｓ９０１）。ＷｉｎＥｘｅｃ関数は、メモリ属性変更関数ではないため（Ｓ９０２：ＮＯ）、不正アクセス検出部４８は、リターンアドレスが、保存されたアドレス範囲０ｘ６５４８００００〜０ｘ６５４８０ＦＦＦに含まれるかどうか判定する（Ｓ９０６）。
【００６０】
ここで、ＷｉｎＥｘｅｃ関数を呼び出すｃａｌｌ命令は、属性変更が行われた静的変数１の領域にあるため、リターンアドレスも当該領域内にある。つまり、リターンアドレスは、保存されたアドレス範囲０ｘ６５４８００００〜０ｘ６５４８０ＦＦＦに含まれている（Ｓ９０６：ＹＥＳ）。そのため、不正アクセス検出部４８は、攻撃コードによる不正アクセスが行われていると判定する（Ｓ９０７）。そして、不正アクセス検出部４８は、不正アクセスの判定結果を出力し（Ｓ９０８）、処理を強制終了させる。これにより、ＷｉｎＥｘｅｃ関数の本体は実行されず、不正アクセスを防止することが可能となる。
【００６１】
本実施形態によれば、呼び出し検出部４０により検出された関数が、メモリ上の指定されたアドレス範囲の領域に実行可能属性を付与する関数（例えばＶｉｒｔｕａｌＰｒｏｔｅｃｔ）であり、リターンアドレスの指し示す先の１つ前の命令が関数の呼び出し命令でない場合に、当該アドレス範囲がアドレス範囲記憶部４６に記憶される。そして、リターンアドレスがアドレス範囲記憶部４６に記憶されているアドレス範囲内である場合に、不正アクセスが行われていると判定される。
【００６２】
したがって、リターンアドレスの指し示す先がプログラムコードを格納するためのメモリ領域と同様に見える場合であっても、不正アクセスを検出することができる。さらに、リターンアドレスの指し示す先の属性が書込み可能であっても、その領域に実行属性を付与した関数の各リターンアドレスの指し示す先の１つ前の命令が関数の呼び出し命令であれば不正アクセスとして誤検出されることはない。そのため、メモリ上のデータ領域に別のプログラムコードを展開する正常なプログラムによる処理を不正アクセスとして誤検出することを防ぐことができる。このように、本実施形態によれば、不正アクセスの検出精度を高めることが可能となる。
【００６３】
また、本実施形態によれば、リターンアドレスの指し示す先が関数の先頭でない場合であっても、不正アクセスを検出することができる。さらに、本実施形態では、単に、リターンアドレスの指し示す先の１つ前の命令がｃａｌｌ命令でない場合に不正アクセスが行われていると判定するのではない。そのため、ｃａｌｌ命令を用いずに関数呼び出しを行う正常なプログラムによる処理を不正アクセスとして誤検出することを防ぐことができる。したがって、本実施形態によれば、不正アクセスの検出精度を高めることが可能となる。
【００６４】
また、本実施形態によれば、リターンアドレス取得部４２は、バックトレースにより、スタック領域に格納されている複数のリターンアドレスを順次取得することができる。そして、順次取得されるリターンアドレスのそれぞれについて、図９に示したように、属性変更検出部４４による処理と、不正アクセス検出部４８による処理とが実行される。したがって、複数の関数が階層的に呼び出される構成となっている場合においても同様に、不正アクセスを検出することが可能となる。
【００６５】
なお、本実施形態は、本発明の理解を容易にするためのものであり、本発明を限定して解釈するためのものではない。本発明は、その趣旨を逸脱することなく、変更／改良され得るととともに、本発明にはその等価物も含まれる。
【符号の説明】
【００６６】
１０  情報機器
２０  プロセッサ
２２  メモリ
２４  記憶装置
２６  入力インタフェース
２８  データインタフェース
３０  通信インタフェース
３２  表示装置
４０  呼び出し検出部
４２  リターンアドレス取得部
４４  属性変更検出部
４６  アドレス範囲記憶部
４８  不正アクセス検出部
【図１】
2013131157.tif 000003
【図２】
2013131157.tif 000004
【図３】
2013131157.tif 000005
【図４】
2013131157.tif 000006
【図５】
2013131157.tif 000007
【図６】
2013131157.tif 000008
【図７】
2013131157.tif 000009
【図８】
2013131157.tif 000010
【図９】
2013131157.tif 000011