API フックによる DEP 回避の防止

APIフックによるDEP回避の防止(岡本)
[研究論文]
35
API フックによる DEP 回避の防止
岡本剛
情報ネットワーク・コミュニケーション学科
Prevention of DEP bypass by API hooks
Takeshi OKAMOTO
Abstract
This paper proposes a method for prevention of DEP bypass, using API hooks. The method reduces the
overhead of ROP detection by focusing on when the only Windows APIs for the DEP bypass are
called. ROP detection performs the check whether Windows API is called by a CALL instruction and
the check of the stack address. Experiments showed that a prototype system can prevent the DEP
bypass by vulnerability attacks of Metasploit Framework, while legitimate normal applications work
without false alarms.
Keywords: DEP, API hook, ROP, shellcode, DLL injection, Metasploit Framework
1.
まえがき
2013 年頃から、有名な企業や団体のウェブサイトを改
の機能を無効にするか、DEP が機能しないメモリ領域を
確保して、任意のコードを実行する。本論文では、ROP
ざんすることにより、脆弱性攻撃を行うサーバーへ誘導
により、DEP の機能を無効にするか、DEP が機能しないメ
し、Internet Explorer(IE)や Adobe Reader の脆弱性
モリ領域を確保することを DEP 回避と呼ぶことにする。
を攻撃して、マルウェアに感染させる手口が増加してい
これらの問題に対して、ROP を検知・防止する手法が
る 1),2),3)。これらの脆弱性攻撃を防ぐために、OS やアプ
提案されている。それらの手法は、アプリケーションを
リケーションとその拡張機能などを最新のバージョンに
実行する前に行う手法 8),9),10),11)と、アプリケーションが
維持するとともに、セキュリティ対策ソフトを利用する
実行されている最中に行う手法 13),14),15),16)がある。これ
ことが求められている。しかし、未知の脆弱性の場合、
までの研究では、前者は、アプリケーションを実行する
最新バージョンでも攻撃を防ぐことはできず、従来のパ
前にアプリケーション毎に対策が必要であるが、後者
ターンマッチングを行う手法のセキュリティ対策ソフト
は、事前の対策が必要なく、透過性のあるユーザビリテ
では、攻撃を防げない。
ィを提供できることから、本研究は、後者の手法を応用
Microsoft 製品の脆弱性のうち、脆弱性が公表される
することにより、DEP 回避を防止する手法を提案する。
前に攻撃された未知の脆弱性は約 16%を占めたという報
なお、後者の手法の欠点として、実行時のオーバーヘッ
告もある 4)。また、未知の脆弱性攻撃が確認されてか
ドが挙げられるが、本研究手法では、あらゆる ROP をチ
ら、修正プログラムが配布されるまで、平均 1 ヶ月かか
ェックするのではなく、DEP 回避に関連する一部の ROP
っている 5)。このように、従来の対策だけでは、未知の
だけをチェックすることにより、実行時のオーバーヘッ
脆弱性攻撃を防ぐことが困難である。
ドを軽減する。
脆弱性攻撃を防ぐために、Microsoft は、Windows XP
本研究手法は、攻撃者が ROP により DEP 回避を行う Wi
Service Pack 2 以降(以下、SP2)に、データ実行防止(D
ndows API を呼び出して、任意のコードを実行するとい
EP:Data Execution Prevention)を導入した 6)が、Retu
う作法に基づき、DEP 回避の Windows API をフックし、
rn-Oriented Programing(ROP)と呼ばれるテクニック 7)
フック関数により、ROP を検知し、DEP 回避を防止する。
により、DEP が機能していても、攻撃者はガジェットと
ROP の検知手法は、ROP は CALL 命令ではなく RET 命令や
呼ばれるマシン語命令で構成された数バイトのマシン語
JMP 命令などの命令により Windows API を呼び出すこと
命令列(以下、コード)を実行できるようになった。攻
と、ROP はスレッドのスタック領域外で実行されること
撃者は、このガジェットを組み合わせることにより、DEP
が多いことに基づいて、フック関数により、API の呼び
36
神奈川工科大学研究報告 B‐39(2015)
出し元が CALL 命令ではないか、または、スタックのアド
レスがスレッドのスタック領域外であるかを確認するこ
2.2 DEP
Microsoft は、脆弱性攻撃によるシェルコードの実行
を防止するために、Windows XP SP2 以降に、DEP を導入
とにより、ROP を検知する。
本論文では、まず、DEP 以前の従来の攻撃手法と、DEP
した。DEP は、スタックやヒープなどのデータ領域でプ
の仕組み、ROP と DEP 回避の仕組みについて述べる。次
ログラムの実行を防止する。具体的には、メモリ保護オ
に、本研究手法の詳細について述べ、本研究手法を実現
プションで実行を許可していないメモリ領域に実行の制
するシステムについて述べる。続いて、本研究手法の有
御を渡そうとしたときに、OS がアクセス違反の例外を生
効性を評価する。最後に、本研究手法の関連研究と実装
成して、実行を防止する。一般に、このようなデータ領
方法について考察する。
域で、プログラムが実行されることはないので、通常の
プログラムが DEP により動作が妨害されることはない。
2.
DEP と DEP 回避
ただし、一部のメモリ管理の粗雑なアプリケーションは
バッファオーバーフロー攻撃などの脆弱性攻撃は、プ
ロセスのデータ領域に、シェルコードと呼ばれる 100 バ
動作しないことがあるので、DEP は、特定のプロセスに
対して無効にするなどの設定が可能である。
イトから 500 バイト程度の小さなコードを送り込み、脆
弱性を悪用することにより、このシェルコードを実行す
る。このシェルコードは、インターネットからマルウェ
アをダウンロードし、感染させることが多い。
本章では、この種の脆弱性攻撃で最も単純なスタック
2.3 ROP
DEP の設定が有効でも、コードを実行するテクニック
がある。それが ROP と呼ばれる方法である。この方法
は、スタックなどのデータ領域でコードを実行しないた
バッファオーバーフロー攻撃によるシェルコードの実行
め、DEP の制限を受けない。ROP は、スタックにプッシュ
の仕組みと、そのシェルコードの実行を防止する DEP
されたリターンアドレスを、すでにプロセスにロードさ
と、その DEP を回避して、シェルコードを実行する仕組
れた実行可能領域にある正規のコードのアドレスに書き
みについて述べる。
換えて、その正規のコードにジャンプさせる。その正規
のコードは、実行可能領域にあることから、DEP により
2.1 スタックバッファオーバーフロー攻撃によるシ
ェルコードの実行
実行を防止できない。
ROP では、まず、実行したいコードを作成し、それと
スタックバッファオーバーフローとは、プロセスのス
同じ処理が可能な「コード断片」を攻撃対象のプロセス
タックにあるバッファ変数にその変数の容量を超える入
の実行可能領域から探しだし、そのアドレスへジャンプ
力が行われることである。スタックには、呼び出し元の
するように、リターンアドレスを書き換える。ただし、
関数のローカル変数、呼び出し先の関数の引数、呼び出
その「コード断片」の直後に必ずリターン命令(RET 命
し元の関数に実行の制御を戻すリターンアドレス、呼び
令)が必要である。RET 命令がなければ、スタックに制
出し元のスタックフレームのアドレス、呼び出し先の関
御が戻ってこないためである。ROP では、この「コード
数のローカル変数の順にデータがプッシュされる。図 1
断片」をガジェット呼ぶ。つまり、ROP では、攻撃対象
にスタックの構造とバッファオーバーフロー攻撃の例を
のプロセスに含まれるガジェットのアドレスを、スタッ
示す。
クに積み上げることにより、ガジェットを連続して呼び
この攻撃で重要なデータは、リターンアドレスであ
出すことができる。これにより、ROP は任意のコードを
る。この攻撃は、呼び出し先の関数のローカル変数に容
実行できる。ROP によるコードの実行の例を図 2 に示
量を超える入力を行って、リターンアドレスをシェルコ
す。
ードのアドレスに書き換えることにより、プロセスの実
行の制御をシェルコードに移す。シェルコードは、バッ
ファオーバーフローさせるデータの中に含まれる場合
や、事前に、ヒープスプレーなどの何らかの方法で、複
数のデータ領域にばらまかれている場合がある。
呼び出し先関数の
ローカル変数
シェルコード
オーバーフロー
実行したいコード
ROP の
スタック
POP EAX
POP ECX
MOV [ECX], EAX
ガジェット A
※仮想メモリの
0x40000000h 番
地の値を 1 にする
0x00000001
ガジェット B
0x40000000
ガジェット C
.text セクション
(実行可能領域)
ガジェット A
POP EAX
RET
ガジェット B
POP ECX
RET
ガジェット C
MOV [ECX], EAX
RET
スタックフレームアドレス
リターンアドレス
シェルコードのアドレス
図 2 ROP によるコードの実行
呼び出し先関数の引数
呼び出し元ローカル変数
2.4 DEP 回避によるシェルコードの実行
図 1 バッファオーバーフロー攻撃
ROP だけで、シェルコードのような自由度のある高度
な機能を実現することは容易ではないため、2.4.1 節で
APIフックによるDEP回避の防止(岡本)
37
述べる DEP を無効にする API や、2.4.2 節で述べる DEP
メモリ保護オプションを実行可能に設定して、ファイ
の制限を受けない実行可能領域を作る API を、ROP によ
ルなどをメモリにマッピングすることにより、マッピ
り呼び出して DEP を回避する。具体的には、これらの AP
ングされたメモリ上でコードが実行できるようになる。
I の引数とその API のアドレスをスタックにプッシュし
この処理は、次のいずれかの API により実行できる。
て、ROP により、これらの API を呼び出して、DEP を回避
-
KERNEL32.DLL: CreateFileMappingA 関数
する。DEP を回避できるようにしたら、シェルコードの
-
KERNEL32.DLL: CreateFileMappingW 関数
アドレスにリターンさせ、シェルコードを実行させる。
-
KERNEL32.DLL: CreateFileMappingNumaA 関数
-
KERNEL32.DLL: CreateFileMappingNumaW 関数
2.4.1 DEP を無効にする方法
DEP は、SetProcessDEPPolicy 関数または NtSetInform
ationProcess 関数で無効にできる。ただし、この方法
-
KERNELBASE.DLL: CreateFileMappingW 関数
-
KERNELBASE.DLL: CreateFileMappingNumaW 関数
-
NTDLL.DLL: NtCreateSection 関数
は、OS 起動時の DEP ポリシーがオプトインかオプトアウ
トのときに有効であり、常時有効(AlwaysOn)の場合、D
EP は無効にならないため、この方法が悪用される脆弱性
攻撃は少ない。
3.
API フックによる DEP 回避の防止
API フックが本研究のコアとなる。API フックは、オリ
ジナルの関数の呼び出しに対して、別の関数(フック関
数)を呼び出すことができるテクニックの 1 つである。
2.4.2 DEP の制限を受けない実行可能領域を作る方法
DEP の制限を受けない実行可能領域は、次の 4 種類の
DEP を回避するには、ROP により、DEP 回避の API を呼
び出す必要がある。そこで、本研究手法では、これらの
方法のいずれかにより確保できる。
API をフックし、ROP による呼び出しであるかをフック関

実行可能なメモリ領域を確保する
数で調べ、ROP による呼び出しであれば、RaiseExceptio
メモリ保護オプションを実行可能に設定して、プロセ
n 関数により、ROP による攻撃を知らせる例外を生成し
スの仮想メモリ内にメモリを割り当てることにより、
て、実行を防止する。一方、ROP による呼び出しでなけ
割り当てられたメモリ上でコードが実行できるように
れば、オリジナルの API を呼び出す。
なる。この処理は、次のいずれかの API により実行で
きる。


ROP による呼び出しであるかのチェックは、呼び出し
元命令のチェックとスタックアドレスのチェックにより
-
KERNEL32.DLL: VirtualAlloc 関数
-
KERNEL32.DLL: VirtualAllocEx 関数
-
KERNEL32.DLL: VirtualAllocExNuma 関数
-
KERNELBASE.DLL: VirtualAlloc 関数
-
KERNELBASE.DLL: VirtualAllocEx 関数
が CALL 命令で呼び出されると、CALL 命令の次の命令の
-
KERNELBASE.DLL: VirtualAllocExNuma 関数
アドレスがリターンアドレスとしてスタックにプッシュ
-
NTDLL.DLL: NtAllocateVirtualMemory 関数
メモリ保護オプションを実行可能に変更する
行う。
3.1 呼び出し元命令のチェック
Windows API は、通常、CALL 命令で呼び出される。API
される。つまり、CALL 命令で API が呼び出されたら、プ
ッシュされたリターンアドレスにある命令の前の命令
指定したメモリのメモリ保護オプションを実行可能に
は、CALL 命令である。一方、ROP の場合、RET 命令で API
することにより、指定したメモリ上でコードが実行で
が呼び出されるので、リターンアドレスがあるべき場所
きるようになる。この処理は、次のいずれかの API に
には、ガジェットのアドレスがある。これまでの攻撃に
より実行できる。
使われてきた ROP では、ガジェットの前の命令が CALL 命
-
KERNEL32.DLL: VirtualProtect 関数
令であることはない。ROP の仕組み上、ガジェットの前
-
KERNEL32.DLL: VirtualProtectEx 関数
の命令が CALL 命令であるガジェットを利用すれば、この
-
KERNELBASE.DLL: VirtualProtect 関数
チェックを回避できるが、ガジェットの選択に厳しい制
-
KERNELBASE.DLL: VirtualProtectEx 関数
約を課すことになるので、ROP が困難になると考えられ
-
NTDLL.DLL: NtProtectVirtualMemory 関数
る。
ヒープ領域に実行可能領域を確保する
ヒープの割り当て属性を実行可能に設定して、ヒープ
そこで、フック関数は、リターンアドレスにある命令
の前の命令が CALL 命令でなければ、ROP による DEP 回避
領域にメモリを割り当てることにより、割り当てられ
として検出し、例外を生成する。一方、CALL 命令であれ
たヒープ領域でコードが実行できるようになる。この
ば、オリジナルの API を呼び出す。
処理は、次のいずれかの API により実行できる。
-

KERNEL32.DLL: HeapCreate 関数
-
KERNELBASE.DLL: HeapCreate 関数
-
NTDLL.DLL: RtlCreateHeap 関数
ファイルマッピングで実行可能領域を確保する
3.2 スタックアドレスのチェック
脆弱性がスタックバッファオーバーフローのように、
スタックの内容を操作できる場合は、そのスタックにガ
ジェットのアドレスを書き込めばよいが、必ずしもスタ
38
神奈川工科大学研究報告 B‐39(2015)
ックを操作できるとは限らない。このような場合、ヒー
4.1 プロセス生成通知ドライバ
プスプレーなど何らかの方法で別のデータ領域に ROP の
プロセス生成通知は、ユーザモードの API には存在し
コードを書き込んでから、スタックの場所を ROP のコー
ないが、カーネルモードで動作するデバイスドライバの
ド領域へ旋回(ピボット)させて、ROP のコードを実行
API として提供されている。その API は、PsSetCreatePr
させることがある。
ocessNotifyRoutine 関数である。この関数は、プロセス
そこで、フック関数は、現在のスタックのアドレス
生成時に、指定したコールバックルーチンを呼び出すこ
が、正しい範囲にあるかどうかをチェックする。スタッ
とができる。コールバックルーチンには、プロセスを生
クが範囲外であれば、ROP による DEP 回避として検出
成した親プロセス ID と生成されたプロセス ID が引き渡
し、例外を生成する。一方、スタックが範囲内であれ
される。このプロセス ID をキューに追加し、ユーザモー
ば、オリジナルの API を呼び出す。なお、スタックの正
ドで動作する DLL インジェクションサービスに通知を行
しい範囲は、スレッド毎に Thread Information Block
う。
(TIB)と呼ばれるデータ構造体で管理されており、その
カーネルモードのデバイスドライバからユーザモード
TIB は NtCurrentTeb 関数により取得できる。ただし、TI
のプロセス(DLL インジェクションサービス)にプロセ
B は読み書き可能なメモリ領域にあるため、ピボットし
ス ID を通知するために、IRP(I/O Request Packet)の
てから、スタックアドレスの範囲を変更されると、DEP
仕組みを利用する。IRP は、ユーザモードのプロセスと
回避を検出できないが、これまでの ROP ではそのような
カーネルモードのデバイスドライバとの入出力制御を可
工夫はされていない。
能にする。
4.
ションサービスが連動して動作するには 2 つの工夫が必
カーネルモードのこれらのルーチンと DLL インジェク
システムの構成
DEP 回避を防止するシステムは、次の 3 つのコンポー
要である。1 つは、カーネルモードで動作する 2 つのル
ネントから構成される。図 3 にシステムの構成図を示
ーチン間の工夫である。もう 1 つは、ディスパッチャル
す。
ーチンと DLL インジェクションサービス間の工夫であ

プロセス生成通知ドライバ
る。

DLL インジェクションサービス

プロセス生成時に呼び出されるコールバックルーチン
と、IRP で DLL インジェクションサービスから入力を要
API フック
プロセス生成通知ドライバは、デバイスドライバで動
求されるディスパッチャルーチンは、プロセス ID のキュ
作し、アプリケーションなどのプロセスが生成されたと
ーを共有し、アクセスが競合することがある。そこで、C
きに、ユーザモードの DLL インジェクションを行うサー
PU が提供する lock 命令を利用したスピンロックによ
ビスにそのプロセス ID を通知する。
り、競合を回避する。具体的には、デバイスドライバに
DLL インジェクションサービスは、プロセス生成通知
提供されている ExInterlockedInsertTailList 関数と Ex
ドライバから通知されたプロセスに、API フックを行う D
InterlockedRemoveHeadList 関数を利用する。これらの
LL をロードする。
関数はスピンロックにより排他的にキューへのアクセス
API フックは、2.4 節で述べた DEP 回避に悪用される A
PI 関数を、DEP 回避の検出と防止を行うフック関数に置
を制御する。
もう 1 つは、DLL インジェクションサービスが ReadFil
e 関数により、カーネルモードのディスパッチャルーチ
き換えて、DEP 回避を防止する。
API フックの処理は、3 章で述べたので、次節から、プ
ンからプロセス ID を読み出すとき、キューにデータがな
ロセス生成通知ドライバと DLL インジェクションサービ
ければ、ディスパッチャルーチンはキューの入力を待機
スの詳細な処理について述べる。
しなければならない。そこで、OS が提供するイベントを
利用する。ディスパッチャルーチンは、KeWaitForSingle
API フック
インジェクション
プロセス
Object 関数により、イベントを待機させ、コールバック
ルーチンで KeSetEvent 関数によりイベントを設定して、
シグナル状態に遷移させ、ディスパッチャルーチンの待
機を解除し、ディスパッチャルーチンが DLL インジェク
DLL インジェクション
サービス
ユーザモード
ションサービスにキューにあるすべてのデータを送信し
たら、イベントをクリアし、非シグナル状態に戻す。こ
れらの工夫により、3 つの処理が連動する。
カーネルモード
プロセス生成通知
ドライバ
4.2 DLL インジェクションサービス
ユーザモードで動作する API をフックする一般的な方
図 3 システムの構成図
法は、DLL インジェクションである。DLL インジェクショ
ンサービスは、プロセス生成通知ドライバから通知され
APIフックによるDEP回避の防止(岡本)
たプロセスに、DLL インジェクションを行う。
本システムでは、Windows セッションマネージャー(s
39
とその攻撃モジュール名を示す。
呼び出し元命令のチェックとスタックアドレスのチェ
mss.exe)やクライアントサーバーランタイムプロセス
ックによる DEP 回避防止手法について、これらの脆弱性
(csrss.exe)などの一部のシステムプロセスを除いて、
攻撃を阻止できるかどうかを評価した結果、すべての DE
あらゆるプロセスに DLL インジェクションできる Create
P 回避を検知するとともに、攻撃を阻止することに成功
RemoteThread 関数を利用する。CreateRemoteThread 関数
した。
は、他のプロセスで関数を実行する関数であるので、い
くつかの TIPS が必要である。その方法が、Advanced Win
表 1 実験に使用した脆弱性とその攻撃モジュール名
dows 第 5 版下巻 17)に例示されているので、本システムで
CVE
は、そのコードを利用する。ただし、この方法は、Windo
2014-1761
2014-0497
2014-0322
2014-0307
2013-3897
2013-3893
2013-3205
ws Vista 以降に導入されたセッション分離により、セッ
ション 0 として動作するプロセス(例えば、Windows サ
ービスなど)とセッション 0 以外で動作するプロセス
(通常のアプリケーション)が区別されるようになり、C
reateRemoteThread 関数で異なるセッションのプロセス
から DLL インジェクションできないようになった 18),19)。
この問題を回避するために、本システムでは、セッシ
ョン 0 のプロセスには Window サービスから DLL インジェ
クションを行い、セッション 0 以外のプロセスには、こ
れまでと同じ通常のアプリケーションから DLL インジェ
クションを行う。これにより、CreateRemoteThread 関数
で一部のシステムプロセス以外のすべてのプロセスに DL
L インジェクションできる。
5.
有効性評価
本研究手法の有効性を評価するため、32 ビットの Wind
ows 7 で動作するプロトタイプシステムを作成した。な
お、プロトタイプシステムは、4 章で述べたプロセス生
成通知ドライバと DLL インジェクションサービスを使わ
ずに、7.1.1 節で述べる AppInit_DLLs レジストリによる
方法で DLL インジェクションを行う。DLL インジェクシ
ョンの方法が異なるだけで、本研究手法の性能に影響は
ない。
有効性評価では、DEP 回避を行う脆弱性攻撃を正しく
検知し、その攻撃を阻止できるかどうかの欠報評価(フ
ォールスネガティブの評価)と、攻撃ではない正常なア
プリケーションの実行を妨害しないかどうかの誤報評価
(フォールスポジティブの評価)を行った。
5.1 欠報評価
Metasploit Framework20)により、実在する脆弱性に対
する攻撃を検知できるかどうかを調べた。Metasploit Fr
amework には、2014 年 9 月時点で 1,332 個もの脆弱性攻
撃モジュールが含まれるが、すべての脆弱性攻撃の実験
攻撃モジュール名
ms14_017_rtf
adobe_flash_avm2
ms14_012_cmarkup_uaf
ms14_012_textrange
ms13_080_cdisplaypointer
ie_setmousecapture_uaf
ms13_069_caret
CVE
攻撃モジュール名
2013-3184
2013-3163
2013-2730
2013-2551
2013-1347
2013-0634
ms13_059_cflatmarkuppointer
ms13_055_canchor
adobe_sandbox_adobecollabsync
ms13_037_svg_dashstyle
ie_cgenericelement_uaf
adobe_flash_regex_value
5.2 誤報評価
呼び出し元命令のチェックとスタックアドレスのチェ
ックによる DEP 回避防止手法について、OS やアプリケー
ションが正常に動作するかどうかを調べた。この評価で
も、すべてのアプリケーションの動作を調べるには膨大
な時間を要するので、主要なアプリケーションに限定し
た。具体的には、IE 11(11.0.9600.17501)
、Microsoft
Office 2013(15.0.4649.1000)、Adobe Reader XI(11.
0.10)
、Adobe Flash Player 16(16,0,0,235)
、Oracle J
ava 8(Update 25)
、Google Chrome(39.0.2171.95m)で
ある。これらの様々な機能を調べた結果、正常な動作を
妨害することはなかった。
さらに、本研究手法のオーバーヘッドを明らかにする
ために、本研究手法を利用していない状態と、呼び出し
元チェックを行っている状態、スタックアドレスのチェ
ックを行っている状態について、ベンチマークテストに
より定量的に評価した。ベンチマークには、PC 全体のパ
フォーマンスを評価する PassMark の PerformanceTest 821)
と、ブラウザのパフォーマンスを評価する Peacekeeper22)
を用いた。ベンチマークテストは、VMware Workstation
10 の仮想マシンで起動した Windows 7 Enterprise 32bit
SP1 に対して行った。その結果を表 2 に示す。各数値
は、2 回計測した平均値であり、数値が大きいほど、性
能がよいことを表す。表内の A は呼び出し元チェックを
行った結果、B はスタックアドレスのチェックを行った
結果を表す。表 2 から本研究手法のオーバーヘッドはな
いことがわかる。
には、膨大な時間を要するため、本研究では、実用上、
表 2 ベンチマークテストの結果
脅威があると考えられる最近の脆弱性攻撃として、2013
PC 全体
年以降に開発された脆弱性攻撃モジュールの中で、Windo
ws 7 を対象にした脆弱性攻撃モジュールとした。また、
本研究は、DEP 回避を行う攻撃を対象にしているため、D
EP 回避を使わない脆弱性攻撃は評価の対象にしない。表
1 に評価に使用した脆弱性の共通脆弱性識別子(CVE)
ブラウザのみ
なし
A
B
なし
A
B
386.10
389.35
389.35
918.00
926.00
914.50
40
6.
神奈川工科大学研究報告 B‐39(2015)
関連研究
本研究に関連する手法は、ROP を検知する手法であ
7.1 DLL インジェクション
7.1.1 レジストリによる方法
Windows にはレジストリに DLL ファイルを指定するだ
り、その中でも、特に、アプリケーションの実行中に RO
P を検出する手法である。これらの手法は、いずれも実
けで DLL インジェクションできる方法が用意されてい
行時に現れる ROP 固有の振る舞いと通常のプログラムの
る。本研究のプロトタイプシステムでは、この方法によ
振る舞いの違いに基づく。最近の研究例として、ROP は
り、DLL インジェクションを行った。
そのレジストリは、HKEY_LOCAL_MACHINE\SOFTWARE\Mic
スタックなどのデータ領域に実行可能領域(ガジェッ
ト)へのアドレスが多数含まれることに基づく手法 8),2
rosoft\WindowsNT\CurrentVersion\Windows にある。た
3)
だし、64bit の OS に 32bit の DLL をインジェクションす
基づく手法 12),24),25),26),27)、ROP が利用するガジェットの
る場合、そのレジストリは、HKEY_LOCAL_MACHINE\SOFTWA
アドレスは互いに近いことに基づく手法 28)、ROP のガジ
RE\Wow6432Node\Microsoft\WindowsNT\CurrentVersion\W
、ROP は RET 命令などの制御転送が多数発生することに
ェットの長さや間接ジャンプの距離に基づく手法
29)
、ROP
indows である。このレジストリに、次の 2 つのキーを設
は CPU の分岐予測の不一致回数が通常のプロセスの実行
定することにより、DLL インジェクションできる。
時と比べて多いことに基づく手法 15)などがある。これら

を識別する閾値があり、この閾値が検出精度を決定する
重要な要素となる。この閾値は、アプリケーションやユ
ーザの操作などに依存するため、ユニバーサルな閾値を
AppInit_DLLs
DLL インジェクションしたい DLL のパスを指定する。
の手法は、いずれも、正常な振る舞いと異常な振る舞い

LoadAppInit_DLLs
値を 1 に設定した直後から、起動したアプリケーショ
ンに DLL がインジェクションされる。
決定することが難しいという問題がある。これらの手法
この方法の利点は、DLL インジェクションに特別なプ
に対して、本研究手法は、閾値がなく、有効性評価でも
ログラムを必要としないことである。もう1つは、4 つ
誤報がないことから、あらゆる環境に適用できる可能性
のシステムプロセス(smss.exe、csrss.exe、lsm.exe、a
がある。
udiodg.exe)を除いて、システムプロセスにも DLL イン
本研究手法と同様に閾値がない手法が 3 つある。1 つ
は、ROP が API を呼び出すと、開放されたスタックに API
のアドレスがあることに基づく手法がある
16)
。本研究手
ジェクションできることである。
一方、この方法の欠点は、USER32.DLL をロードしない
アプリケーションに DLL インジェクションしないことで
法と同様に、API フックを前提にした手法であり、DEP 回
ある。これは、USER32.DLL がプロセスにロードされたと
避の防止にも有効であると考えられる。他の 2 つは、Mic
きに、USER32.DLL がこのレジストリに登録された DLL を
rosoft が無償で提供する Enhanced Mitigation Experien
読み込む仕様になっているためである。ただし、USER32.
ce Toolkit 5.0(EMET)
30)
に組み込まれた機能である。そ
DLL は GUI アプリケーションに必要なウインドウを操作
の機能は、
「呼び出し元チェック」と「スタックピボッ
する様々な関数を提供しているので、多くのアプリケー
ト」であり、本研究手法とコンセプトが同じと考えられ
ションは、USER32.DLL をロードする。したがって、この
る。EMET には、技術論文がなく、ソースコードも公開さ
方法でも多くのプロセスを保護できる。
れていないため、本研究手法との具体的な違いは明らか
でないが、EMET の「スタックピボット」は IE11 の動作
7.1.2 SetWindowsHookEx 関数による方法
を誤検知して、IE11 が起動しなかったり、EMET の「呼び
Windows が提供するユーザモードの SetWindowsHookEx
出し元チェック」は Microsoft Office 2013 と Adobe Re
関数は、起動中のプロセスや新規に起動したプロセスに
ader の動作を誤検知して、これらのアプリケーションで
対して、DLL インジェクションできる。
ファイルを保存しようとすると異常終了したりするな
この方法の利点は、DLL インジェクションと DLL のア
ど、本研究手法と異なる結果が得られることから、EMET
ンロードが容易にできることである。また、この方法を
のアルゴリズムまたは実装が、本研究手法と異なると考
実装するコードは、定型のコード 17)があるので、容易に
えられる。この他に、本研究手法と EMET が異なる点は、
実装できる。
保護するプロセスの適用範囲である。EMET はオプトイン
一方、この方法の欠点は、DLL インジェクションでき
方式であるため、Microsoft の製品や Adobe Reader など
るプロセスに大きな制限があることである。それは、プ
有名な製品以外のプロセスは、保護の対象になっていな
ロセスが Windows ユーザインターフェースに提供される
い。一方、本研究手法は、3 つのシステムプロセスを除
サービスの 1 つであるメッセージのイベントを利用しな
いて、すべてのプロセスを保護の対象にしている。
ければ、DLL インジェクションできないことである。つ
まり、DLL インジェクションの対象の多くが GUI アプリ
7.
実装に関する考察
ケーションに制限される。これは、GUI を利用しないシ
DLL インジェクションと API フックには、様々な方法
ステムプロセスやコンソールアプリケーションに DLL イ
がある。それらの利点と欠点、さらに、DEP 回避の防止
ンジェクションできないことを意味する。さらに、たと
に関する有効性について考察する。
え、メッセージイベントを利用するアプリケーションで
APIフックによるDEP回避の防止(岡本)
41
あっても、DLL がロードされるのは、メッセージのイベ
は、DLL インジェクション後にアクセス違反によりプロ
ントが起こった直後である。つまり、GUI アプリケーシ
セスが終了することがあるため、改良が必要である。
ョンであっても、メッセージの送受信を行う前に、脆弱
性攻撃を受けると、API フックが機能しないため、DEP 回
この方法の欠点は、スレッドがイベントなどの待機状
態であった場合には、待機が終了するまで DLL インジェ
避を防止できない。したがって、この方法は、DEP 回避
クションが行われないことである。また、CreateRemoteT
の防止に有効ではない。
hread 関数と同様に、新規に起動したプロセスに DLL イ
ンジェクションを行うには、プロセスの起動を監視しな
7.1.3 CreateRemoteThread 関数による方法
ければならない。
Windows が提供するユーザモードの CreateRemoteThrea
d 関数は、起動中のプロセスに、DLL インジェクションで
7.1.6 LdrLoadDll 関数のフックによる方法
ユーザモードのプロセスとカーネルの橋渡しをする NT
きる。
この方法の利点は、すでに定型の実装コード
17)
が公開
DLL.DLL 以外のすべての DLL は、ユーザモードで動作す
されているので、容易に実装できることである。もう 1
る LdrLoadDll 関数でプロセスにロードされる。つまり、
つは、4.2 節で述べたように、システムサービスとして
LdrLoadDll 関数をフックすることにより、アプリケーシ
実装すれば、一部のシステムプロセスを除いて、すべて
ョンが利用する DLL がロードされたときに、便乗して、D
のプロセスに DLL インジェクションできることである。
一方、この方法の欠点は、起動中のプロセスにしか DL
LL インジェクションを行うことができる。LdrLoadDll 関
数のフックは、7.2.3 節で述べる EAT の書き換えによっ
L インジェクションできないことである。新規に起動し
て行う。本手法は、これまでに公開されていない本研究
たプロセスに DLL インジェクションするには、プロセス
で新しく開発した手法である。
の起動を監視する機能が必要になる。本システムでは、
この方法の利点は、プロセスの起動時にロードされる
プロセス生成通知ドライバにより、この欠点を克服して
DLL に便乗して DLL インジェクションできるため、プロ
いる。
セスの起動を監視する必要がないことである。また、3
7.1.4 NtCreateThreadEx 関数による方法
exe)を除いて、システムプロセスにも DLL インジェクシ
つのシステムプロセス(smss.exe、csrss.exe、audiodg.
NtCreateThreadEx 関数は、Windows Vista 以降で導入
された非公開の関数であり、3 つのシステムプロセス(s
ョンできることである。
この方法の欠点は、一部のサイズの小さなアプリケー
mss.exe、csrss.exe、audiodg.exe)以外のすべてのプロ
ションには DLL インジェクションできないことである。
セスに DLL インジェクションできる 19)。
これらのアプリケーションは、フックされる前のオリジ
この方法の利点は、CreateRemoteThread 関数と異な
ナルの関数を呼び出している。この問題を解決する方法
り、セッション分離の制約を受けないので、1 つのアプ
は明らかでない。もう 1 つの欠点は、LdrLoadDll 関数は
リケーションで DLL インジェクションできることであ
非公開の関数であることである。7.1.4 節の NtCreateThr
る。この方法の欠点は、NtCreateThreadEx 関数は非公開
eadEx 関数と同様の問題がある。
の関数であり、リバースエンジニアリングにより、意図
した動作をするように引数の値をチューニングしている
ため、各引数の役割が明らかでないことや、将来、Micro
soft による仕様の変更により、関数が削除される可能性
や、関数の仕組みが変更される可能性があることであ
る。
7.2 API フック
7.2.1 IAT の書き換えによる方法
プロセスは、ユーザモードの API を呼び出すとき、そ
のプロセス自身が所有するインポートアドレステーブル
(IAT)にある API のアドレスを参照して、API を呼び出
す。つまり、この IAT にある API のアドレスをフック関
7.1.5 SetThreadContext 関数による方法
Windows が提供するユーザモードの SetThreadContext
関数により、実行中のスレッドのコンテキストを、DLL
数のアドレスに書き換えれば、API をフックできる。た
だし、IAT は、プロセスの起動時だけでなく、実行中に
も遅延ロードや、LoadLibrary 関数により DLL がロード
インジェクションのコードに切り替えて、DLL インジェ
され、IAT が更新されるため、その都度、IAT の確認と書
クションを行う。具体的には、DLL インジェクションを
き換えが必要になる。Advanced Windows 第 5 版下巻は、
行いたいプロセスのスレッドを SuspendThread 関数によ
この問題を解決するコードを例示している 17)。また、G.
りサスペンドして、GetThreadContext 関数により、スレ
Hoglund らの ROOTKITS には、デバイスドライバの API で
ッドのコンテキストを取得し、その中に含まれる CPU レ
ある PsSetLoadImageNotifyRoutine 関数により、EXE や D
ジスタの EIP を、DLL インジェクションを行うコードの
LL などの実行可能形式のファイルが仮想メモリへロード
アドレスに書き換えて、スレッドを ResumeThread 関数に
されたときに呼び出されるコールバックルーチンにより
よりレジュームすることにより、DLL インジェクション
IAT を書き換えるコードが例示されている 32)。しかし、I
を行う
31)
。なお、この文献
31)
で公開されているコード
AT は、このコールバックルーチンが呼び出された後に、
42
神奈川工科大学研究報告 B‐39(2015)
エクスポートテーブル(EAT)の値に従って更新されるた
されているため、Detours で実装したフック関数を移
め、フック関数が呼び出されることはないので動作しな
植しやすい。Mhook は、MIT ライセンスのため、ソース
い。
コードが無料で公開され、商用の利用も可能である。
DEP 回避では、ROP が利用されるが、ROP は IAT を参照
本研究のプロトタイプシステムは、Mhook が x64 系の
しないで関数を呼び出すことができるので、フック関数
CPU をサポートしていることと無料でソースコードを
は呼び出されないことがある。したがって、IAT の書き
利用・公開できることから、Mhook により実装した。た
換えによるフックは、DEP 回避の防止に有効ではない。
だ し 、 Mhook の バ ー ジ ョ ン 2.4 以 前 に は 、
VirtualProtect 関数などメモリ保護オプションを変更
7.2.2 インラインによる方法
する関数をフックすると、スタックオーバーフローを
フックしたい関数のマシン語コードの先頭数バイトを
フック関数へのジャンプ命令に書き換えることにより、
起こすバグがあるため、プロトタイプシステムの実装
にはこのバグの修正を加えている。
フックする。具体的には、例えば、次のコードをフック
したい関数の先頭に上書きする。
B8 FF FF FF FF
// MOV EAX, 0xFFFFFFFF
FF FE
// JMP EAX
上述の「FF FF FF FF」はフック関数の先頭アドレスに
書き換える必要がある。また、オリジナルの関数も呼び
7.2.3 EAT の書き換えによる方法
IAT の書き換えによるフックで述べた通り、プロセス
は、IAT にあるアドレスを参照して API を呼び出す。こ
の IAT にある API のアドレスは、ロードされた DLL のエ
クスポートアドレステーブル(EAT)の値から計算され
出せるようにするために、トランポリンと呼ばれる小さ
る。つまり、EAT にあるアドレスを書き換えれば、フッ
なメモリ領域を仮想メモリ内に確保し、上書きする前の
クできる。ただし、プロセスが実行してから、EAT を書
先頭 7 バイトのコードを、そのトランポリンへコピーす
き換えても、IAT は更新されないので、EAT の書き換え
る。フック関数がオリジナルのコードを呼び出すとき
は、DLL のイメージが仮想メモリへロードされたとき
は、トランポリンにジャンプして、トランポリンから、
に、EAT を書き換える必要がある。
オリジナルのコードの先頭 8 バイト目へジャンプする。
本研究では、デバイスドライバから PsSetLoadImageNo
オリジナルのコードの処理が終わると、リターン命令に
tifyRoutine 関数によりコールバックルーチンを設定
より、フック関数の呼び出し元に戻る。
し、このコールバックルーチンにより EAT を書き換える
この方法の利点は、IAT の書き換えで述べたような欠
方法を検討した。フック関数は、DLL の.text セクション
点がないことである。DLL がロードされるタイミング
(実行可能領域)の末尾にある未使用領域に配置する。
や、アプリケーションがどのような方法で関数のアドレ
この方法の利点は、DLL インジェクションサービスを必
スを解決しようとも、フックできる。
要としないことである。欠点は、フック関数のサイズ
一方、欠点もある。この方法は、マシン語を書き換え
が、DLL の.text セクションの空き領域に制限されること
るので、CPU アーキテクチャに依存する。また、スレッ
である。この制限を回避するために、LdrLoadDll 関数だ
ドがコードを書き換えている最中に、別のスレッドが、
けを EAT でフックして、API フックを行う DLL を LdrLoad
書き換え中のコードを実行して、意図しない動作を招く
Dll 関数によりロードすればよい。ただし、この方法
可能性がある。
は、7.1.6 節で述べた通り、一部のアプリケーションに
これらの問題を解決した API フックのためのライブラ
は DLL インジェクションできない問題がある。
リがある。代表的なライブラリとして、Microsoft が開
発した Detours33),34)と、M. Anka が開発している mhook35)
がある。

ユーザモードの API の一部は、カーネルモードの API
Detours
に対応する。つまり、カーネルモードの API をフック 32)
Windows が提供する関数に限らず、任意の関数をフッ
すれば、ユーザモードの API はフック関数を呼び出せ
クできる。定型のコードにより容易に実装でき、安定
る。しかし、DEP 回避の防止に使う API の中で、カーネ
して動作する。Detours には、Detours Professional
ルモードの API に対応するユーザモードの API は、4 つ
3.0 と Detours
3.0 が あ る 。 Detours
の API(NtAllocateVirtualMemory 関数、NtProtectVirtu
Professional 3.0 は、有償であり、x86 系、x64 系、
Express
alMemory 関数、NtCreateSection 関数、NtSetInformatio
IA64 系の CPU をサポートし、商用の利用が認められて
nProcess 関数)だけであるため、この方法だけでは、DE
いる。Detours Express 3.0 は、無償であるが、x86 系
P 回避を防止できない。
のみであり、商用の利用は認められていない。ソース

7.2.4 カーネルモードの API フック
なお、カーネルモードの API フックは、ルートキット
コードは公開されている。
に悪用されやすいことから、Microsoft は 64 ビット版の
Mhook
Windows に、Kernel Patch Protection(KPP)36)を導入し
サポートする CPU は x86 系と x64 系である。Detours
た。KPP が API フックを検知すると、システムをクラッ
と同等の機能と類似した API インターフェースが提供
シュさせる仕様になっている。そのため、カーネルモー
APIフックによるDEP回避の防止(岡本)
ドの API フックは採用すべきでない。
8.
むすび
本論文では、バッファオーバーフロー攻撃などの脆弱
[11]
性攻撃に利用される DEP 回避を防止する手法を提案し
た。本研究手法は、従来の手法と比べて、ROP の検出を D
EP 回避に利用される Windows API の呼び出し時に限定す
ることにより、実行時のオーバーヘッドを軽減してい
[12]
る。ROP の検知は、API の呼び出し元の命令を確認するこ
とと、スタックのアドレスを確認することにより実現し
ている。また、従来の手法と比べて、閾値を設定する必
[13]
要がないことも利点である。
本研究手法の有効性を確認するため、プロトタイプシ
ステムを実装し、Metasploit Framework により脆弱性攻
[14]
撃を行い、すべての攻撃を阻止できることを確認すると
ともに、Microsoft Office 2013 など主要なアプリケー
ションについて、正常な動作を妨害しないことを確認し
た。また、プロトタイプシステムによるオーバーヘッド
[15]
もないことを確認した。最後に、本研究手法と関連する
[16]
手法と実装方法について考察した。
[17]
今後は、ROP を使わないで DEP を回避する方法とその
対策手法について研究を進める。
[18]
参考文献
[19]
[1]
読売新聞:角川サイト改ざん、1週間公表せず,(20
14)http://www.yomiuri.co.jp/it/security/goshinjyutsu/20
140117-OYT8T00410.html
[2] 産経新聞:ワコールのサイトに改ざん、ウイルス感
染の恐れ,(2014)http://sankei.jp.msn.com/economy/ne
ws/140401/biz14040119340045-n1.htm
[3] 日経新聞:日産、下取りサイト改ざんされる 不正
アクセスで,(2014)http://www.nikkei.com/article/DG
XLASFL26H7U_W4A820C1000000/
[4] 情報処理推進機構: サイバー攻撃の被害回避のた
め、サポートが終了した XP 等 Microsoft 製品の移
行を, (2014) https://www.ipa.go.jp/files/000038636.pdf
[5] トレンドマイクロ: TrendLabs 2013 年間 セキュリ
ティラウンドアップ, (2014) http://www.trendmicro.c
o.jp/cloud-content/jp/pdfs/security-intelligence/threat-rep
ort/pdf-2013asr-20140217.pdf
[6] Microsoft: A detailed description of the Data Executi
on Prevention (DEP) feature in Windows XP Service
Pack 2, Windows XP Tablet PC Edition 2005, and
Windows Server 2003, (2006) http://support.microsoft.
com/kb/875352/EN-US/
[7] H. Shacham: The geometry of innocent flesh on the
bone: Return-into-libc without function calls (on the
x86), Proceedings of the 14th ACM conference on C
omputer and communications security. ACM, (2007).
[8] J. Li, Z. Wang, X. Jiang, M. Grace, S. Bahram: Def
eating return-oriented rootkits with “Return-Less” kern
els, Proceedings of the 5th European conference on
Computer systems, (2010).
[9] K. Onarlioglu, L. Bilge, A. Lanzi, D. Balzarotti, E.
Kirda: G-Free: defeating return-oriented programming
through gadget-less binaries, Proceedings of the 26th
Annual Computer Security Applications Conference,
(2010).
[10] R. Wartell, V. Mohan, K. -W. Hamlen, Z. Lin: Binar
[20]
[21]
[22]
[23]
[24]
[25]
[26]
[27]
[28]
[29]
43
y stirring: self-randomizing instruction addresses of le
gacy x86 binary code, Proceedings of the 2012 ACM
conference on Computer and communications securit
y, (2012).
V. Pappas, M. Polychronakis, A. -D. Keromytis: Sma
shing the Gadgets: Hindering Return-Oriented Progra
mming Using In-place Code Randomization, Proceedi
ngs of the 2012 IEEE Symposium on Security and P
rivacy, p.601-615, (2012).
P. Chen, H. Xiao, X. Shen, X. Yin, B. Mao, L. Xie:
DROP: Detecting return-oriented programming malici
ous code. Information Systems Security, 163-177, (20
09).
F. Yao, J. Chen, G. Venkataramani: JOP-alarm: Detec
ting jump-oriented programming-based anomalies in a
pplications, Computer Design (ICCD), IEEE 31st Inter
national Conference on IEEE, (2013).
X. Jia, R. Wang, J. Jiang, S. Zhang, P. Liu: Defendi
ng return‐oriented programming based on virtualizati
on techniques, Security and Communication Networks,
6(10), 1236-1249, (2013).
G. Wicherski: Threat Detection for Return Oriented P
rogramming, (2014).
D. Hentunen: Detecting a return-oriented programmin
g exploit, (2010).
R. Jeffrey, N. Christophe: ADVANCED WINDOWS
第 5 版 下, 日経 BP 社, (2008).
L. –H.Michael: Injecting Code Into Privileged Win32
Processes, (2007) http://mnin.blogspot.jp/2007/05/injecti
ng-code-into-privileged-win32.html
SecurityXploded: Remote Thread Execution in System
Process using NtCreateThreadEx for Vista & Windo
ws7, http://securityxploded.com/ntcreatethreadex.php
Metasploit Framework, http://metasploit.com/
PassMark: PerformanceTest8, http://www.passmark.com
e/
Furework: Peacekeeper, http://peacekeeper.futuremark.c
om/
M. Polychronakis, K. –D. Angelos: ROP payload det
ection using speculative code execution, Malicious an
d Unwanted Software (MALWARE), 2011 6th Interna
tional Conference on IEEE, (2011).
S. –A. Fischer, K. –C. Gotze, Y. Bulygin, K. –D. Br
annock: Detection Of Return Oriented Programming
Attacks, (2013).
Y. Xia, Y. Liu, H. Chen, B. Zang: CFIMon: Detectin
g violation of control flow integrity using performanc
e counters, In Dependable Systems and Networks (D
SN), 2012 42nd Annual IEEE/IFIP International Conf
erence on IEEE, 1-12, (2012).
L. Yuan, W. Xing, H. Chen, B. Zang: Security breac
hes as PMU deviation: detecting and identifying secu
rity attacks using performance counters, In Proceeding
s of the Second Asia-Pacific Workshop on Systems,
6, ACM, (2011).
V. Pappas, M. Polychronakis, A. –D. Keromytis: Tran
sparent ROP Exploit Mitigation Using Indirect Branch
Tracing, USENIX Security, (2013).
J. –W. Min, S. –M. Jung, T. –M. Chung: Detecting
Return Oriented Programming by Examining Positions
of Saved Return Addresses, Ubiquitous Information
Technologies and Applications, 791-798, (2013).
F. Yao, J. Chen, G. Venkataramani: JOP-alarm: Detec
ting jump-oriented programming-based anomalies in a
pplications, Computer Design (ICCD), 2013 IEEE 31st
International Conference on IEEE, (2013).
44
神奈川工科大学研究報告 B‐39(2015)
[30] Microsoft: Enhanced Mitigation Experience Toolkit, ht
tp://technet.microsoft.com/ja-jp/security/jj653751
[31] SetThreadContext DLL Injection, (2007) http://nerd.egl
oos.com/2940083
[32] G. Hoglund, J. Butler: Rootkits: Subverting the Wind
ows Kernel, Addison-Wesley Professional (2005).
[33] Microsoft: Detours, Microsoft Research, http://researc
h.microsoft.com/en-us/projects/detours/
[34] G. Hunt, D. Brubacher: Detours: Binary Interception
of Win32 Functions, in Third USENIX Windows NT
Symposium, USENIX, (1999).
[35] M. Anka: Mhook, http://codefromthe70s.org/mhook24.a
spx
[36] M. E. Russinovich, D. A. Solomon, A. Ionescu: イン
サイド Windows 第 6 版 上, 日経 BP, (2012).