(57)【要約】【課題】ＣＰＵが所有する機能に依存せずバッファオーバーフローに関する不正アクセスを確実且つ容易に防止する。【解決手段】情報機器１は、メモリに展開された各プログラムコードと中央制御部との協働によりデータ処理を行い、フック処理によって、プログラムコードの呼び出し時を検出し、スタックレイアウトチェック処理によって、ＲＡＭ３０に展開された各プログラムコードのリターンアドレスを順次取得して、この取得されたリターンアドレスが示す先のアドレスに基づいて不正アクセスを検出し、不正アクセスが検出された場合にはデータ処理を停止させる。【選択図】図４
2010257275.tif 000002
【特許請求の範囲】
【請求項１】
メモリに展開された各プログラムコードと中央制御部との協働によりデータ処理を行う情報機器であって、
前記いずれかのプログラムコードの呼び出し時を検出する検出手段と、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記メモリに展開された各プログラムコードのリターンアドレスを順次取得するリターンアドレス取得手段と、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記リターンアドレス取得手段により順次取得されたリターンアドレスが示す先のアドレスに基づいて不正アクセスを検出し、当該不正アクセスが検出された場合には前記データ処理を停止させる停止手段と、
を備える情報機器。
【請求項２】
前記メモリは、各プログラムコードのリターンアドレスを格納するスタック領域を備え、
前記リターンアドレス取得手段は、前記スタック領域に格納されたリターンアドレスをトレースして取得する請求項１に記載の情報機器。
【請求項３】
前記停止手段は、前記属性取得手段により取得された各リターンアドレスが示す先のアドレスが関数の開始アドレスである場合に不正アクセスを検出し、当該不正アクセスが検出された場合には、前記データ処理を停止させる請求項１又は２に記載の情報機器。
【請求項４】
前記停止手段は、前記属性取得手段により取得された各リターンアドレスが示す先のアドレスに対応する一つ前の命令がコール命令ではない場合に不正アクセスを検出し、当該不正アクセスが検出された場合には、前記データ処理を停止させる請求項１〜３の何れか一項に記載の情報機器。
【請求項５】
メモリに展開された各プログラムコードを実行するコンピュータを、
前記いずれかのプログラムコードの呼び出し時を検出する検出手段、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記メモリに展開された各プログラムコードのリターンアドレスを順次取得するリターンアドレス取得手段、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記リターンアドレス取得手段により順次取得されたリターンアドレスが示す先のアドレスに基づいて不正アクセスを検出し、当該不正アクセスが検出された場合には前記データ処理を停止させる停止手段、
として機能させるためのプログラム。
【請求項６】
メモリに展開された各プログラムコードを実行するコンピュータにおける不正なプログラムコードの実行防止方法であって、
前記いずれかのプログラムコードの呼び出し時を検出し、当該検出されたプログラムコードの呼び出し時において、前記メモリに展開された各プログラムコードのリターンアドレスを順次取得し、当該取得された各リターンアドレスが示す先のアドレスに基づいて不正アクセスを検出し、当該不正アクセスが検出された場合には前記データ処理を停止させる不正なプログラムコードの実行防止方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、情報機器、プログラム及び不正なプログラムコードの実行防止方法に関する。
【背景技術】
【０００２】
一般的に、ＰＣ（Personal  Computer）やＷＳ（Work  Station）等の情報機器では、ＣＰＵ（Central  Processing  Unit）などの制御部がＲＡＭ（Random  Access  Memory）等の記憶部の作業領域に展開されたプログラムコードを順次実行することで、各種データ処理を実行している。近年、悪意のあるユーザによって作成されたプログラムコードによる不正な処理によって、情報機器に対する不正アクセスが発生している。
【０００３】
通常、情報機器が管理するデータにはアクセス権限が設定されている。従って、データへのアクセス権限がなければ、不正アクセスが行われることはない。しかしながら、データへのアクセス権限がある通常のプログラムコードを利用し、不正な操作が実行された場合は、不正アクセスが可能となる。このような手法としては、プログラムコードの実行時のデータをＲＡＭ等に確保された所定領域からオーバーフローさせる、いわゆるバッファオーバーフローを用いた手法が知られている。
【０００４】
ここで、バッファオーバーフローを用いた不正アクセスについて、正常にプログラムコードが実行された場合と、プログラムコードの実行時に不正が行われた場合と、を比較して詳細に説明する。
【０００５】
先ず、図９、図１０を参照して正常にプログラムコードが実行された場合を説明する。
図９に、プログラムコードのソースコードを例示する概念図を示す。図９に示すプログラムコードは、main()関数から開始され、main()関数の中でstrcpy_helloworld()関数を呼び出している。このプログラムコードでは、strcpy_helloworld()関数の中で「Hello!」という文字列を用意し、main()関数のprintf()関数でこの文字列をモニタ等に表示させている。なお、関数とは、所定の機能をモジュール化してまとめたサブルーチンやサブプログラムなどであり、メインとなるプログラム内で随時呼び出すことができる。
【０００６】
図９に示すプログラムコードの実行時のデータは、ＲＡＭ等に確保されたスタック領域に格納される。このスタック領域では、後入れ先出し (LIFO: Last In First Out; FILO: First In Last Out) 構造でデータが格納される。
【０００７】
図１０に、プログラムコード実行時におけるスタック領域の概要を例示する概念図を示す。図１０に示すように、上から下に向かって順次確保された領域へプログラムコードの実行時のデータが格納される。
【０００８】
例えば、図９に例示したソースコードによるプログラムコードの実行時には、main()関数を処理した際に、ReturnAddress1、ebp  backup、char  buf[8]などが１つのスタックフレームとして格納される。次いで、main()関数の中でstrcpy_helloworld()関数が呼び出された際に、ReturnAddress2、ebp  backup2、int  i等が一つのスタックフレームとして格納される。
【０００９】
ReturnAddress（リターンアドレス）は、プログラムの終了時に戻るべきアドレス値や、関数などによりサブプログラムが呼び出された場合の当該サブプログラム終了時に戻るべきアドレス値を示す。このReturnAddressは、プログラムの実行直後や関数などによりサブプログラムが呼び出された直後に、ＣＰＵにより自動的にスタック領域へ格納される。
【００１０】
ebpは、ＣＰＵのレジスタの一種であり、現在使用している一時的なメモリ領域のアドレスの直前を示す。図１０の例では、char  buf[8]、int  iの前のアドレスであり、スタックフレームのReturnAddressが該当する。従って、スタックフレームにおいて、上記レジスタ値をebp  backupとしてバックアップすることで、このスタックフレーム内の一領域を一時的なデータ（変数や配列等）を格納するメモリ領域として簡単に使用することが可能となる。
【００１１】
char  buf[8]は、main()関数で使用される配列であるbufを格納する。このbufは、char型の変数（１バイト）を８個格納する配列であり、８バイト分のデータが格納可能となっている。int  iは、strcpy_helloworld()関数で使用されるint型の変数であるiを格納する。
【００１２】
従って、上記プログラムコードの実行により、スタック領域では、main()関数のスタックフレームが確保され、strcpy_helloworld()関数のスタックフレームが確保される。次いで、int  iの値が順次インクリメントされて、「Hello!」という６バイト分の文字列がchar  buf[8]に格納される。次いで、strcpy_helloworld()関数の終了により、ReturnAddress2が読み出されてmain()関数へ復帰され、main()関数の終了により、ReturnAddress1が読み出されてプログラムは正常終了する。
【００１３】
次に、図１１、図１２を参照してプログラムコードの実行時に不正が行われた場合を説明する。
【００１４】
図１１に、プログラムコードのソースコードを例示する概念図を示す。図１１に示すプログラムコードは、配列bufへ「Hello World」という１２バイト分（11文字+文字列終端）のデータを書き込む点において、図９に示すプログラムコードと異なる。
【００１５】
図１２に、プログラムコード実行時におけるスタック領域の概要を例示する概念図を示す。図１２に示すように、スタック領域では、配列bufを格納する領域として８バイト分の領域が確保されている。従って、strcpy_helloworld()関数が実行された際には、確保されているサイズ以上のデータが書き込まれる。このように、メモリに確保されているサイズ以上のデータが書き込まれるとバッファオーバーフローが発生する。なお、このバッファオーバーフローがスタック領域で起きる場合をスタックベースのバッファオーバーフローという。
【００１６】
図１２に示したスタック領域おいて、領域の確保は上から下に向かって順次行われ、その確保された領域へのデータの書き込みは下から上に向かって行われる。従って、ReturnAddress1、ebp  backupはstrcpy_helloworld()関数が実行された際に、「Hello World」という１２バイト分のデータにより不正に上書き（overwrite）される。上述した上書きにより、ReturnAddress1の内容が実行可能なプログラムコードが置いてあるアドレスに書き換えられた場合は、main()関数の終了によりReturnAddress1が読み出され、その書き換えられたプログラムコードが実行される。
【００１７】
図１１に示したソースコードでは、「Hello World」という予め定義された文字列によりオーバーフローとなっている。しかしながら、実際には、メールサーバやＷｅｂサーバ等の通信ポートで受信されたデータや、コンソールやファイルから入力されたデータなどが配列bufに格納される場合もある。このような場合は、悪意のあるユーザにより通信、コンソール入力、ファイル入力などを介して任意のプログラムコードが実行され、データの盗みだしや改竄などの不正アクセスが発生する。
【００１８】
これらの不正アクセスを検出する方法として、スタック領域に格納されているリターンアドレスを検査し、正常なプログラム実行時と攻撃コード動作時のリターンアドレスの配置パターンの違いを比べることによって不正アクセスが実行されるか否かを検出する方法が考えられる。例えば、リターンアドレスが示す先のメモリ属性が、プログラムコードを配置するためのメモリ領域を支援している場合又はこのメモリ領域が書き込み不可能な属性にある場合は正常なプログラムと判断する等である。
【００１９】
しかし、このような不正アクセスの検出方法では、Return-to-libc攻撃（非特許文献１参照）を検出できない可能性がある。Return-to-libc攻撃とは、悪意のあるコードをプログラムコードに書き加えることなく、コンピュータに既に記憶されている関数を呼び出すことによって不正アクセスを行う攻撃手法である。
【００２０】
図１３に、図１１に示すプログラムコード実行時においてReturn-to-libc攻撃された際のスタック領域の概要を例示する概念図を示す。図１３に示すように、Return-to-libc攻撃では、上記説明したリターンアドレスが示す値が、ＯＳ（Operating System）の標準関数等の正常な関数の先頭アドレスに設定される。スタック領域上のリターンアドレスが、プログラムコードを置くためのメモリ領域を示していたり、このメモリ領域が書き込み不可能な属性にあったりした場合には、正常なプログラムと区別がつかない可能性がある。
【００２１】
このReturn-to-libc攻撃を応用し、既に情報機器の記憶部に記憶されているプログラムのプログラムコードを組み合わせることによって所定のプログラムコードを実行する攻撃が考えられる。この攻撃方法においても、スタック領域上のリターンアドレスはReturn-to-libc攻撃と同様の特徴があるため、正常なプログラムと区別がつかない可能性がある。
【００２２】
特許文献１には、ＣＰＵの機能の一つであるブランチトレースを使用し、実行中の関数から呼び出し元の関数の処理に戻る際に、ＯＳの標準関数の先頭アドレスに戻るという動きを検出することによってReturn-to-libc攻撃を検出する技術が開示されている。
【先行技術文献】
【特許文献】
【００２３】
【特許文献１】米国特許第１０／７６３，８６７号明細書
【非特許文献】
【００２４】
【非特許文献１】”Return-to-libc attack”、［ｏｎｌｉｎｅ］、ウィキメディア財団、［２００９年３月２３日検索］、インターネット、（ＵＲＬ：http://en.wikipedia.org/wiki/Return-to-libc_attack）
【発明の概要】
【発明が解決しようとする課題】
【００２５】
しかしながら、特許文献１に記載の技術では、Return-to-libc攻撃をブランチトレースという機能を使用して検出することはできるが、ＣＰＵが所有する機能を使用しているため、ＣＰＵの処理負荷の増大、ブランチトレース機能を使用する他のアプリケーション（パフォーマンス計測ツール等）の使用の制限等が発生する可能性がある。つまり、Return-to-libc攻撃を検出するための処理が実行されている間は、コンピュータの処理負荷が増大し、ユーザビリティの低下を招く可能性がある。
【００２６】
本発明の課題は、上記従来技術の問題に鑑みてなされたものであり、ＣＰＵが所有する機能に依存せずバッファオーバーフローに関する不正アクセスを確実且つ容易に防止する技術を提供することである。
【課題を解決するための手段】
【００２７】
上記課題を解決するために、請求項１に記載の発明は、
メモリに展開された各プログラムコードと中央制御部との協働によりデータ処理を行う情報機器であって、
前記いずれかのプログラムコードの呼び出し時を検出する検出手段と、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記メモリに展開された各プログラムコードのリターンアドレスを順次取得するリターンアドレス取得手段と、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記リターンアドレス取得手段により順次取得されたリターンアドレスが示す先のアドレスに基づいて不正アクセスを検出し、当該不正アクセスが検出された場合には前記データ処理を停止させる停止手段と、
を備える。
【００２８】
請求項２に記載の発明は、請求項１に記載の発明において、
前記メモリは、各プログラムコードのリターンアドレスを格納するスタック領域を備え、
前記リターンアドレス取得手段は、前記スタック領域に格納されたリターンアドレスをトレースして取得する。
【００２９】
請求項３に記載の発明は、請求項１又は２に記載の発明において、
前記停止手段は、前記属性取得手段により取得された各リターンアドレスが示す先のアドレスが関数の開始アドレスである場合に不正アクセスを検出し、当該不正アクセスが検出された場合には、前記データ処理を停止させる。
【００３０】
請求項４に記載の発明は、請求項１〜３の何れか一項に記載の発明において、
前記停止手段は、前記属性取得手段により取得された各リターンアドレスが示す先のアドレスに対応する一つ前の命令がコール命令ではない場合に不正アクセスを検出し、当該不正アクセスが検出された場合には、前記データ処理を停止させる。
【００３１】
請求項５に記載の発明は、
メモリに展開された各プログラムコードを実行するコンピュータを、
前記いずれかのプログラムコードの呼び出し時を検出する検出手段、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記メモリに展開された各プログラムコードのリターンアドレスを順次取得するリターンアドレス取得手段、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記リターンアドレス取得手段により順次取得されたリターンアドレスが示す先のアドレスに基づいて不正アクセスを検出し、当該不正アクセスが検出された場合には前記データ処理を停止させる停止手段、
として機能させる。
【００３２】
請求項６に記載の発明は、
メモリに展開された各プログラムコードを実行するコンピュータにおける不正なプログラムコードの実行防止方法であって、
前記いずれかのプログラムコードの呼び出し時を検出し、当該検出されたプログラムコードの呼び出し時において、前記メモリに展開された各プログラムコードのリターンアドレスを順次取得し、当該取得された各リターンアドレスが示す先のアドレスに基づいて不正アクセスを検出し、当該不正アクセスが検出された場合には前記データ処理を停止させる。
【発明の効果】
【００３３】
本発明によれば、ＣＰＵが所有する機能に依存せずバッファオーバーフローに関する不正アクセスを確実且つ容易に防止することが可能となる。
【図面の簡単な説明】
【００３４】
【図１】本実施の形態に係る情報機器の機能的構成を模式的に示すブロック図である。
【図２】（ａ）は、Return-to-libc攻撃が実行されている場合のＲＡＭ３０の所定領域に確保されるスタック領域の一例を示す図であり、（ｂ）は、Return-to-libc攻撃の応用手法を用いた攻撃の場合におけるＲＡＭ３０の所定領域に確保されるスタック領域の一例を示す図である。
【図３】情報機器のフック処理を示すフローチャートである。
【図４】情報機器において実行されるスタックレイアウトチェック処理の実装例を示すフローチャートである。
【図５】リターンアドレスが関数の開始アドレス付近の場合におけるコードの一例を示す概念図である。
【図６】リターンアドレスが関数の開始アドレスとは全く別のプログラムコードのアドレスに設定して、このプログラムを実行させる場合におけるコードの一例を示す概念図である。
【図７】Return-to-libc攻撃においてCreateFileが実行中である場合のスタックの内容を示す図である。
【図８】Return-to-libc攻撃においてURLDownloadTofileが実行中である場合のスタックの内容を示す図である。
【図９】プログラムコードのソースコードを例示する概念図である。
【図１０】プログラムコード実行時におけるスタック領域の概要を例示する概念図である。
【図１１】プログラムコードのソースコードを例示する概念図である。
【図１２】プログラムコード実行時におけるスタック領域の概要を例示する概念図である。
【図１３】Return-to-libc攻撃時におけるプログラムコード実行時におけるスタック領域の概要を例示する概念図である。
【発明を実施するための形態】
【００３５】
以下、本発明の実施の形態について図を参照して説明するが、この発明の範囲は以下の実施の形態に限定されない。
【００３６】
先ず、本実施の形態に係る情報機器の構成について説明する。
図１に、情報機器１の機能的構成を模式的に示す。図１に示すように、情報機器１は、ＣＰＵ１０、記憶部２０、ＲＡＭ３０、操作部４０、表示部５０、Ｉ／Ｆ部６０を有する。上記情報機器１の各部はバス７０により電気的に接続されている。具体的には、情報機器１は、ＰＣ、ＷＳ、ＰＤＡ（Personal  Digital  Assistant）、携帯電話等である。
【００３７】
ＣＰＵ１０は、情報機器１の動作を中央制御する。ＣＰＵ１０は、記憶部２０に記憶されたプログラムコードや各種データをＲＡＭ３０のワークエリアに展開し、ＲＡＭ３０に展開されたデータとの協働により各部へ制御信号を出力する。
【００３８】
記憶部２０は、プログラムコードや各種設定情報などのデータをＣＰＵ１０から読み書き可能に記憶する。例えば、記憶部２０は、ＨＤＤ（Hard  Disk  Drive）や半導体メモリ等である。また、記憶部２０は、上記データをＲＯＭ（Read  Only  Memory）などに記憶する構成であってもよい。なお、記憶部２０が記憶するプログラムコードとしては、ＯＳ（Operating System）などの基本的なソフトウエアの他、ベンダーが提供した各種アプリケーションプログラム、後述する処理に係るプログラムなどが含まれる。
【００３９】
ＲＡＭ３０には、プログラムコードの実行時のデータを格納するスタック領域が確保される。
【００４０】
図２（ａ）に、Return-to-libc攻撃が実行されている場合のＲＡＭ３０のスタック領域における、あるスタックフレームの一例を示す。図２（ａ）に示すように、スタック領域には、Exitprocessの引数、ReturnAddress、WinExecの引数2及び1、ExitProcessの開始アドレス、ebp  backup等のデータが格納される。Return-to-libc攻撃では、WinExec()が実行された後のリターンアドレスとして、ExitProcess()の開始アドレスが設定される場合がある。図２（ａ）に示す例は、Return-to-libc攻撃が行われ、WinExec()が実行されている最中におけるスタック領域を示している。
【００４１】
Exitprocess()は、プログラムを終了させるための関数であり、引数には終了すべきプログラムの終了コードが設定される。WinExec()は、指定されたプログラムを実行させるための関数である。ebp  backupの直前にはReturnAddressがあるので、ebp  backupを辿ることでReturnAddressを順次トレースして取得することが可能となる。
【００４２】
スタック領域に含まれるスタックフレームは、各プログラムコードが順次実行された場合に、そのプログラムコードの実行に伴って順次確保される。例えば、メインとなるプログラムコードが実行され、そのプログラムコード内でサブルーチンに関するプログラムコードが呼び出され、更に別のプログラムコードが呼び出された場合などは、スタックフレームの各々の順に各プログラムコードに係る領域が確保される。この各プログラムコードに係る処理が終了した際には、スタックフレームのReturnAddressが読み出されることで、メインとなるプログラムコードへの復帰や、プログラム終了後の処理が行われる。
【００４３】
図２（ｂ）に、先述したReturn-to-libc攻撃の応用手法におけるＲＡＭ３０の所定領域に確保されるスタック領域のスタックフレームの一例を示す。「既存のプログラムコード」の領域には、既存のプログラムコード内のExitProcessを呼び出すコードが格納されている。
【００４４】
操作部４０は、ユーザからの操作入力を受け付け、当該操作に応じた操作信号をＣＰＵ１０へ出力する。例えば、操作部４０は、文字入力キー、数字入力キー、その他各種機能に対応付けられたキーを備えたキーボード、マウス等のポインティングデバイス等である。
【００４５】
表示部５０は、ＣＰＵ１０から出力された表示制御信号に基づいた画像を表示画面に表示する。例えば、表示部５０は、ＣＲＴ（Cathode  Ray  Tube）、ＬＣＤ（Liquid  Crystal  Display）などであってよい。
【００４６】
Ｉ／Ｆ部６０は、データ通信用ＩＣ（Integrated  Circuit）や接続コネクタなどを備え（いずれも図示しない）、外部機器や通信ネットワークと通信可能に接続する。例えば、Ｉ／Ｆ部６０は、ＵＳＢ（Universal Serial Bus）通信ポートや、ＬＡＮ（Local  Area  Network）、ＷＡＮ（Wide  Area  Network）、インターネットなどと接続するネットワークインターフェイスカード（ＮＩＣ：Network  Interface  Card）であってよい。
【００４７】
次に、情報機器１が不正なプログラムコードの実行を検出する際の動作について説明する。情報機器１において、不正なプログラムコードの実行を防止するためには、不正なプログラムコードの実行に必要なＡＰＩ、ライブラリ関数、システムコールなどを検出し、不正なプログラムコードの実行の有無をチェックする処理を挿入する必要がある。本実施の形態の情報機器１では、所定のライブラリ関数を呼び出す悪意のあるコードの検出と、不正のチェックを行う処理の挿入を、フック（Hook）を用いて実現している。
【００４８】
フックは、プログラム中の特定の箇所に、利用者が独自の処理を追加できるようにする仕組みである。すなわち、フックされる側のプログラムコードを作成したプログラマーと、フックする側のプログラムコードを作成したプログラマーと、が同じプログラマーでなく、互いのプログラムコードに関するソースコードが同一のプログラマーにより作成されない場合に利用される仕組みである。従って、ベンダーが提供するＯＳや関数の機能変更や、任意の処理の追加時に使用される。
【００４９】
なお、フックは、チェック対象となる関数などのサブプログラムをプログラマー自身が修正可能である場合であっても用いてよい。但し、プログラマー自身がサブプログラムを修正可能であり、当該サブプログラムが実行された際に不正のチェックを行うように修正した場合は、フックを使用する必要はなくなるとともに、既存の関数やライブラリをより安全なものとして実装することが可能となる。
【００５０】
先ず、ＡＰＩフック（ライブラリ関数をフックする）を行って不正なプログラムコードの実行の有無をチェックする場合について図３を参照して説明する。
【００５１】
以下では、ベンダーが用意したWinExec()というライブラリ関数のフック処理（図３）を例示し、当該ライブラリ関数が呼び出された際に実行されるスタックレイアウトチェック処理（図４）を例示している。なお、他のライブラリ関数（例えば、ExitProcess()等）のフック処理についても同様である。
【００５２】
図３に、情報機器１において実行されるフック処理のフローチャートを示す。フック処理は、ＣＰＵ１０と記憶部２０に記憶されたプログラムとの協働により実行される。
【００５３】
図３に示すように、まずWinExec()の関数の開始アドレスを取得する。（ステップＳ１）。この関数のアドレス取得は、ベンダーから提供される関数を呼び出すことで可能である。
【００５４】
次いで、ＡＰＩの実行にフックをかける小さな関数（一時的な関数）を動的に生成する（ステップＳ２）。この動的に生成する関数とは、後述するスタックレイアウトチェック処理を呼び出す関数である。
【００５５】
次いで、WinExec()の先頭コードの書き換えが行われ、ステップＳ２で生成された関数が実行されるように変更される（ステップＳ３）。
【００５６】
情報機器１では、上述したフック処理により、サブプログラムコードの呼び出しを検出し、不正のチェックを行う処理の挿入が可能となっている。通常、関数に係るサブプログラムが呼び出された場合は、ある関数で呼び出された関数がそのまま実行される。しかしながら、情報機器１では、サブプログラムコードが呼び出される前に上述したフック処理を行うことで、サブプログラムコード呼び出し時にスタックレイアウトチェック処理を実行させることができる。
【００５７】
図４に、情報機器１において実行されるスタックレイアウトチェック処理のフローチャートを示す。スタックレイアウトチェック処理は、ＣＰＵ１０と記憶部２０に記憶されたプログラムとの協働により、フック処理によって動的に生成された関数から呼び出される。なお、このスタックレイアウトチェック処理では、StackWalk()関数を使用してスタックトレースを行っているが、StackWalk()を使用しないでスタックトレースを行うことも可能である。
【００５８】
図４に示すように、StackWalk()ライブラリの初期化が行われる（ステップＳ１１）。StackWalk()ライブラリは、ベンダーが用意したスタックトレースを行う関数である。このStackWalk()を利用してトレース位置をインクリメント又はデクリメントすることで、スタック領域に格納されたリターンアドレスを順次取得することが可能となる。
【００５９】
次いで、StackWalk()が呼び出されてスタック領域のスタックフレームを順次呼び出すように、スタックが１つバックトレースされ（ステップＳ１２）、トレース後にリターンアドレスが正しく取得できたか否かが判定される（ステップＳ１３）。
【００６０】
ステップＳ１３において、リターンアドレスが正しく取得できたと判断されない場合は（ステップＳ１３；ＮＯ）、正常終了としてチェック対象であるWinExec()の実行が続行される。これは不正アクセス以外の未知の理由などにより、スタックが破壊されており、StackWalk()が正常に動作しない場合等が該当する。なお、本実施の形態では、StackWalk()が正常に動作しない場合に正常終了しているが、このスタックトレースが失敗した場合にも、プログラムの停止や、ユーザに停止するか否かを確認するためのダイアログを表示部５０へ表示してもよい。
【００６１】
一方、リターンアドレスが正しく取得できたと判断された場合は（ステップＳ１３；ＹＥＳ）、このリターンアドレスが関数の開始アドレスであるか否かが判断される（ステップＳ１４）。関数の開始アドレスは、公知の様々な取得方法によって取得されるようにすればよく、例えば、予め記憶部２０に記憶されている値を参照してもよいし、インポートされる関数の実際のメモリアドレスが格納するための配列であるＩＡＴ（Import Address Table）を参照することによって取得されるようにしてもよい。
【００６２】
開始アドレスであると判断されない場合（ステップＳ１４；ＮＯ）、リターンアドレスの一つ前の命令がＣＡＬＬ命令であるか否かが判断される（ステップＳ１５）。ＣＡＬＬ命令とは、サブルーチンを呼び出すための命令であり、ステップＳ１５においては、リターンアドレスの指し示す先の一つ前の命令が判断される。
ＣＡＬＬ命令であると判断された場合（ステップＳ１５；ＹＥＳ）、未チェックのリターンアドレスが存在するか否かが判定される（ステップＳ１６）。
【００６３】
未チェックのリターンアドレスが存在すると判断された場合（ステップＳ１６；ＹＥＳ）、ステップＳ１２へ戻って、次のリターンアドレスがトレースされる。
未チェックのリターンアドレスが存在すると判断されない場合（ステップＳ１６；ＮＯ）、正常終了としてチェック対象であるWinExec()が実行される。
【００６４】
一方、開始アドレスであると判断された場合（ステップＳ１４；ＹＥＳ）、ＣＡＬＬ命令ではないと判断した場合（ステップＳ１５；ＮＯ）、不正アクセス等の攻撃を検出し、不正なプログラムコードの実行を防止するためにデータ処理を一時的に停止する旨のダイアログが表示部５０に表示され（ステップＳ１７）、プログラムの実行が停止される（ステップＳ１８）。
【００６５】
以上説明したスタックレイアウトチェック処理では、ステップＳ１４及びステップＳ１５においてReturn-to-libc攻撃を検出する。Return-to-libc攻撃が行われた際には、リターンアドレスの指し示す先が関数の開始アドレスであるという特徴がある。通常のプログラムの場合には、リターンアドレスの指し示す先が関数の開始アドレスではなく、この関数の続きから処理が継続される。
【００６６】
また、Return-to-libc攻撃の応用手法である、情報機器１に記憶されているプログラムコードを組み合わせた攻撃では、リターンアドレスの指し示す先の一つ前の命令がＣＡＬＬ命令でないという特徴がある。これらの２つの特徴は、正常なプログラムを実行する際には無い特徴である。スタックレイアウトチェック処理では、これらの２つの特徴に基づいてReturn-to-libc攻撃を検出する。
【００６７】
次に、スタックレイアウトチェック処理において検出可能な、Return-to-libc攻撃の派生パターンについて説明する。上記説明したスタックレイアウトチェック処理においては、リターンアドレスの指し示す先をチェックすることによりReturn-to-libc攻撃の検出が可能となるが、Return-to-libc攻撃には様々な攻撃パターンが知られている。
【００６８】
図５に、リターンアドレスが関数の開始アドレス付近の場合におけるコードＣ１の一例を示す。通常、ＯＳが提供している関数の開始アドレスの直前には、ＣＰＵで実行しても何も行わない命令が配置されていることが多い。Return-to-libc攻撃においては、リターンアドレスを関数の開始アドレスではなく、わざと開始アドレス付近に指定することも考えられる。図５に示すように、関数の開始アドレスの位置の前に複数のnop命令が挿入されている。nop命令とは、ＣＰＵが何も実行しないことを示す命令である。
【００６９】
図５に示す場合、リターンアドレスが指し示す先が関数の開始アドレスではないため、ステップＳ１４においてReturn-to-libc攻撃を検出することはできないが、ステップＳ１５においてリターンアドレスの指し示す先の一つ前の命令がＣＡＬＬ命令であるか否かをチェックすることにより、Return-to-libc攻撃を検出することができる。
【００７０】
図６に、リターンアドレスが関数の開始アドレスとは全く別のプログラムコードのアドレスに設定して、このプログラムを実行させる場合におけるコードＣ２の一例を示す。図６に示す例では、リターンアドレスの指し示す先に「jmp eax」という命令コードが格納されている。「jmp eax」という命令は、eaxレジスタに格納されている値が指し示す先の命令を実行させるという命令である。eaxレジスタには、実行させたい関数の開始アドレスが格納されている。図６に示す状態でリターンアドレスの指し示す先のコードが実行されると、まず、「jmp eax」が実行され、次に、実行させたい関数の開始アドレスが実行される。
【００７１】
図６に示す場合、リターンアドレスが指し示す先が関数の開始アドレスではないため、ステップＳ１４においてReturn-to-libc攻撃を検出することはできない。但し、悪意のある攻撃者は別のプログラムコードの領域内から「jmp eax」となっている命令コードを探しだし、リターンアドレスに設定する必要がある。Return-to-libc攻撃においては、「jmp eax」となっている命令コードの一つ前の命令がＣＡＬＬ命令でない場合が多く、ステップＳ１５においてReturn-to-libc攻撃を検出することができる。
【００７２】
次に、Windows（登録商標。以下、注記を省略する。）において実行されるReturn-to-libc攻撃の例を挙げ、本発明に係る情報機器１がReturn-to-libc攻撃を検出するタイミングについて述べる。
【００７３】
まず、ＣＰＵ１０が作成したファイルを実行することによるReturn-to-libc攻撃の一例を説明する。この場合では、Windowsが提供する関数であるCreateFile()、WriteFile()、WinExec()、Exitprocess()等の関数を使用し、Return-to-libc攻撃を行う。CreateFile()とは、ファイル等を作成するための関数であり、作成するファイル名等が引数となる。WriteFile()とは、ファイルにデータを書き込むための関数であり、データを書き込む対象を示すファイルハンドルや書き込むデータ、データサイズ等が引数となる。
【００７４】
まず、Return-to-libc攻撃においては、CreateFile()、WriteFile()を使用して、所定のファイルが作成される。この作成されたファイルをWinExec()で実行させ、ExitProcess()で終了させる手順となっている。
【００７５】
図７に、Return-to-libc攻撃においてCreateFile()が実行中である場合のＲＡＭ３０に記憶されたスタック領域の一例を示す。図７に示すスタックの状態では、スタックレイアウトチェック処理におけるチェック対象のリターンアドレスとして、「WriteFileの開始アドレス」、「WinExecの開始アドレス」、「ExitProcessの開始アドレス」の３つがチェック対象となる。開始アドレスが、図５に示すような開始アドレス付近や、図６に示すような別のプログラムコードを示している場合でも、ステップＳ１５においてReturn-to-libc攻撃を検出することができる。
【００７６】
Return-to-libc攻撃における攻撃コードがインターネットを介して悪意のあるコードをダウンロードし、そのファイルが実行される場合もある。例えば、まずWindowsが提供するURLDownloadTofile()という関数を使用して、Ｉ／Ｆ部６０を介してインターネットから悪意のあるファイルをダウンロードする。ダウンロードされたファイルは、WinExec()を使用することにより実行される。
【００７７】
図８に、Return-to-libc攻撃においてURLDownloadTofile()が実行中である場合のＲＡＭ３０に記憶されるスタック領域の一例を示す。図８に示すスタックの状態では、スタックレイアウトチェック処理におけるチェック対象のリターンアドレスとして、「WinExecの開始アドレス」、「ExitProcessの開始アドレス」の２つがチェック対象となる。開始アドレスが、図５に示すような開始アドレス付近や、図６に示すような別のプログラムコードを示している場合でも、ステップＳ１５においてReturn-to-libc攻撃を検出することができる。
【００７８】
以上のように、本発明に係る情報機器によれば、ＣＰＵが所有する機能に依存せずバッファオーバーフローに関する不正アクセスの手法であるReturn-to-libc攻撃を確実且つ容易に防止することができる。
【００７９】
なお、上述した実施の形態における記述は、一例を示すものであり、これに限定するものではない。上述した実施の形態における構成及び動作に関しては、適宜変更が可能である。
【００８０】
例えば、以上の説明では、本発明に係るプログラムのコンピュータ読み取り可能な媒体として記憶部２０やＲＯＭを使用した例を開示したが、この例に限定されない。その他のコンピュータ読み取り可能な媒体として、フラッシュメモリ等の不揮発性メモリ、ＣＤ-ＲＯＭ等の可搬型記録媒体を適用することが可能である。また、本発明に係るプログラムのデータをＩ／Ｆ部６０と接続する通信回線を介して提供する媒体として、キャリアウエーブ(搬送波)も本発明に適用される。
【符号の説明】
【００８１】
１  情報機器
１０  ＣＰＵ
２０  記憶部
３０  ＲＡＭ
４０  操作部
５０  表示部
６０  Ｉ／Ｆ部
７０  バス
【図１】
2010257275.tif 000003
【図２】
2010257275.tif 000004
【図３】
2010257275.tif 000005
【図４】
2010257275.tif 000006
【図５】
2010257275.tif 000007
【図６】
2010257275.tif 000008
【図７】
2010257275.tif 000009
【図８】
2010257275.tif 000010
【図９】
2010257275.tif 000011
【図１０】
2010257275.tif 000012
【図１１】
2010257275.tif 000013
【図１２】
2010257275.tif 000014
【図１３】
2010257275.tif 000015
【手続補正書】
【提出日】平成22年6月28日(2010.6.28)
【手続補正１】
【補正対象書類名】明細書
【補正対象項目名】００２７
【補正方法】変更
【補正の内容】
【００２７】
上記課題を解決するために、請求項に記載の発明は、
メモリに展開された各プログラムコードと中央制御部との協働によりデータ処理を行う情報機器であって、
前記メモリは、前記各プログラムコードのリターンアドレスを格納するスタック領域を備え、
前記いずれかのプログラムコードの呼び出し時を検出する検出手段と、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記スタック領域に格納された各プログラムコードの複数のリターンアドレスをスタックレイアウトを解析することによりトレースして順次取得するリターンアドレス取得手段と、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記リターンアドレス取得手段により順次取得されたリターンアドレスが示す先のアドレスが関数の開始アドレスである場合に不正アクセスを検出し、当該不正アクセスが検出された場合には、前記データ処理を停止させる停止手段と、
を備える。
【手続補正２】
【補正対象書類名】明細書
【補正対象項目名】００２８
【補正方法】変更
【補正の内容】
【００２８】
請求項２に記載の発明のプログラムは、
各プログラムコードを展開するとともに当該展開された各プログラムコードのリターンアドレスを格納するスタック領域を備えるメモリに展開された各プログラムコードを実行するコンピュータを、
前記いずれかのプログラムコードの呼び出し時を検出する検出手段、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記スタック領域に格納された各プログラムコードの複数のリターンアドレスをスタックレイアウトを解析することによりトレースして順次取得するリターンアドレス取得手段、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記リターンアドレス取得手段により順次取得されたリターンアドレスが示す先のアドレスが関数の開始アドレスである場合に不正アクセスを検出し、当該不正アクセスが検出された場合には、前記データ処理を停止させる停止手段、
として機能させる。
【手続補正３】
【補正対象書類名】明細書
【補正対象項目名】００２９
【補正方法】変更
【補正の内容】
【００２９】
請求項３に記載の発明は、
各プログラムコードを展開するとともに当該展開された各プログラムコードのリターンアドレスを格納するスタック領域を備えるメモリに展開された各プログラムコードを実行するコンピュータにおける不正なプログラムコードの実行防止方法であって、
前記いずれかのプログラムコードの呼び出し時を検出し、当該検出されたプログラムコードの呼び出し時において、前記スタック領域に格納された各プログラムコードの複数のリターンアドレスをスタックレイアウトを解析することによりトレースして順次取得し、当該取得されたリターンアドレスが示す先のアドレスが関数の開始アドレスである場合に不正アクセスを検出し、当該不正アクセスが検出された場合には、前記データ処理を停止させる。
【手続補正４】
【補正対象書類名】明細書
【補正対象項目名】００３０
【補正方法】削除
【補正の内容】
【手続補正５】
【補正対象書類名】明細書
【補正対象項目名】００３１
【補正方法】削除
【補正の内容】
【手続補正６】
【補正対象書類名】明細書
【補正対象項目名】００３２
【補正方法】削除
【補正の内容】
【手続補正７】
【補正対象書類名】特許請求の範囲
【補正対象項目名】全文
【補正方法】変更
【補正の内容】
【特許請求の範囲】
【請求項１】
メモリに展開された各プログラムコードと中央制御部との協働によりデータ処理を行う情報機器であって、
前記メモリは、前記各プログラムコードのリターンアドレスを格納するスタック領域を備え、
前記いずれかのプログラムコードの呼び出し時を検出する検出手段と、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記スタック領域に格納された各プログラムコードの複数のリターンアドレスをスタックレイアウトを解析することによりトレースして順次取得するリターンアドレス取得手段と、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記リターンアドレス取得手段により順次取得されたリターンアドレスが示す先のアドレスが関数の開始アドレスである場合に不正アクセスを検出し、当該不正アクセスが検出された場合には、前記データ処理を停止させる停止手段と、
を備える情報機器。
【請求項２】
各プログラムコードを展開するとともに当該展開された各プログラムコードのリターンアドレスを格納するスタック領域を備えるメモリに展開された各プログラムコードを実行するコンピュータを、
前記いずれかのプログラムコードの呼び出し時を検出する検出手段、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記スタック領域に格納された各プログラムコードの複数のリターンアドレスをスタックレイアウトを解析することによりトレースして順次取得するリターンアドレス取得手段、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記リターンアドレス取得手段により順次取得されたリターンアドレスが示す先のアドレスが関数の開始アドレスである場合に不正アクセスを検出し、当該不正アクセスが検出された場合には、前記データ処理を停止させる停止手段、
として機能させるためのプログラム。
【請求項３】
各プログラムコードを展開するとともに当該展開された各プログラムコードのリターンアドレスを格納するスタック領域を備えるメモリに展開された各プログラムコードを実行するコンピュータにおける不正なプログラムコードの実行防止方法であって、
前記いずれかのプログラムコードの呼び出し時を検出し、当該検出されたプログラムコードの呼び出し時において、前記スタック領域に格納された各プログラムコードの複数のリターンアドレスをスタックレイアウトを解析することによりトレースして順次取得し、当該取得されたリターンアドレスが示す先のアドレスが関数の開始アドレスである場合に不正アクセスを検出し、当該不正アクセスが検出された場合には、前記データ処理を停止させる不正なプログラムコードの実行防止方法。