メイン コンテンツへスキップ
サポート
Microsoft アカウントでサインイン
サインインまたはアカウントを作成してください。
こんにちは、
別のアカウントを選択してください。
複数のアカウントがあります
サインインに使用するアカウントを選択してください。

Windows Vista Service Pack 1 (SP1) のサポートは、2011 年 7 月 12 日に終了します。 引き続き Windows のセキュリティ更新プログラムを受け取る場合は、Service Pack 2 (SP2) Windows Vista を実行している必要があります。 詳細については、この Microsoft Web ページを参照してください。サポートは、一部のバージョンのサポートが終了Windows。

アプリケーションが完全修飾パスを指定せずに動的にダイナミック リンク ライブラリ (DLL) を読み込む場合、Windows は、適切に定義された一連のディレクトリを検索して DLL の検索を試みます。 攻撃者がディレクトリの 1 つを制御した場合、想定していた DLL の代わりに DLL の悪意のあるコピーをアプリケーションに強制的に読み込む可能性があります。 これらの攻撃は "DLL プリロード攻撃" と呼ばれる攻撃であり、共有 DLL ライブラリの動的読み込みをサポートしているすべてのオペレーティング システムに共通です。 このような攻撃の影響は、攻撃者がアプリケーションを実行しているユーザーのコンテキストでコードを実行できる可能性があります。 アプリケーションを Administrator として実行すると、ローカルの特権が昇格される可能性があります。 これらの攻撃に対する新たな関心について知っています。 この問題が相互のお客様に与える影響を制限するために、開発者コミュニティにこのドキュメントをリリースして、この問題を知り、アプリケーションで問題に対処するために必要なツールを入手します。

概要

DLL プリロード攻撃の説明

LoadLibrary ベースの攻撃

アプリケーションが完全修飾パスを指定せずに DLL を動的に読み込む場合、Windows は DLL 検索順序と呼ばれる、適切に定義された一連のディレクトリを線形検索することで、この DLL の検索を試みます。 DLL Windows内で DLL が見つからない場合は、その DLL が読み込まれています。 ただし、dll Windowsディレクトリに DLL が見つからない場合は、DLL の読み込み操作にエラーが返されます。 DLL を動的に読み込むのに使用 される LoadLibrary関数と LoadLibraryEx関数の DLL 検索順序を次に示します。

  1. アプリケーションが読み込まれたディレクトリ

  2. システム ディレクトリ

  3. 16 ビット システム ディレクトリ

  4. Windows ディレクトリ

  5. 現在の作業ディレクトリ (CWD)

  6. PATH 環境変数に設定されているディレクトリ



次のシナリオを検討してください。


  • アプリケーションは、アプリケーションの CWD で検索する必要がある完全修飾パスを指定せずに DLL を読み込む。

  • アプリケーションは、DLL が見つからない場合にケースを処理するために完全に準備されています。

  • 攻撃者は、アプリケーションに関するこの情報を知り、CWD を制御します。

  • 攻撃者は、特別に作成された独自のバージョンの DLL を CWD にコピーします。 これは、攻撃者がこれを行うアクセス許可を持つユーザーを想定しています。

  • Windows DLL 検索順序でディレクトリを検索し、アプリケーションの CWD で DLL を検索します。

このシナリオでは、特別に作成された DLL がアプリケーション内で実行され、現在のユーザーの権限を取得します。

推奨事項 この攻撃を防ぐために、アプリケーションは空の文字列 ("") を使用して SetDllDirectory API を呼び出すことによって、DLL 検索パスから現在の作業ディレクトリ

(CWD) を削除できます。 アプリケーションが現在のディレクトリからの DLL の読み込みに依存している場合は、現在の作業ディレクトリを取得し、そのディレクトリを使用して LoadLibrary の完全修飾パスを 渡してください



また、一部の開発者は LoadLibrary を使用して、ユーザーが実行している Windows のバージョンを判断するために、特定の DLL が存在するかどうかを検証します。 これにより、アプリケーションが脆弱になる可能性があります。 影響を受けるライブラリが実際にアプリケーションが実行される Windows リリースに存在しない場合、攻撃者は同じ名前のライブラリを CWD に導入する可能性があります。 この手法を使用することを強く推奨します。 代わりに、MSDN の記事「システム バージョンの取得」で説明されている推奨される手法を使用してください。

サード パーティのプラグインを読み込み、LoadLibrary 呼び出しに修飾されたパスを使用するプラグインを強制できないアプリケーションは、SetDllDirectory("") を呼び出して CWD を削除し、SetDllDirectory("plugin install location") を呼び出してプラグインのインストール ディレクトリを DLL 検索パスに追加する必要があります。

SearchPath ベースの攻撃

同様の攻撃は、アプリケーションが SearchPath API を使用して DLL を検索し、SearchPath によって返されるパスを動的に読み込む場合 に発生します。 SearchPath API の既定の検索順序を次に示します。

  • アプリケーションが読み込まれたディレクトリ

  • 現在の作業ディレクトリ (CWD)

  • システム ディレクトリ

  • 16 ビット システム ディレクトリ

  • Windows ディレクトリ

  • PATH 環境変数に設定されているディレクトリ

このパターンはセキュリティで保護されていないので、お勧めしません。 出力の目的の使用が LoadLibrary 関数の呼び出しの中にある場合、.dll ファイルを検索するメソッドとして SearchPath 関数はお勧めしません。 これにより、SearchPath 関数の検索順序.dll LoadLibrary 関数で使用される検索順序と異なって、ファイルの検索順序が間違っている可能性があります。 ファイルを見つけて読み込む必要がある.dll、LoadLibrary 関数を使用します。

ShellExecute と CreateProcess


これらの問題のバリエーションは、開発者が ShellExecuteCreateProcessなどの同様の関数を呼び出して外部実行可能ファイルを読み込む場合にも存在する可能性があります。 開発者はバイナリを読み込み、完全修飾パスを指定するときに注意することをお勧めします。 これは、ライブラリではなくバイナリを読み込むときに、複雑さを減らします。

ソフトウェア開発者に推奨される手順

開発者は次の操作を実行することをお勧めします。

  • セキュリティで保護されていないライブラリロードのインスタンスについてアプリケーションを検証します (それぞれの例は、この記事の後半で説明します)。 これには、次のものが含まれます。

    • SearchPath を使用して、ライブラリまたはコンポーネントの場所を特定します。

    • LoadLibrary を使用してオペレーティング システムのバージョンを識別します。

  • 可能な場合は、LoadLibrary、CreateProcess、ShellExecute のすべての呼び出しに完全修飾パスを使用します。

  • 空の文字列 ("") で SetDllDirectory の呼び出しを実装し、必要な既定の DLL 検索順序から現在の作業ディレクトリを削除します。 SetDllDirectory はプロセス全体に影響を与える点に注意してください。 そのため、これは、LoadLibrary の呼び出しの前と後ではなく、プロセスの初期化の早い段階で 1 回行う必要があります。 SetDllDirectory はプロセス全体に影響を与えるので、値が異なる SetDllDirectory を呼び出す複数のスレッドが未定義の動作を引き起こす可能性があります。 さらに、サード パーティの DLL を読み込むプロセスが設計されている場合は、プロセス全体の設定が非互換性の原因になるかどうかを判断するためにテストが必要になります。 既知の問題は、アプリケーションがアプリケーションに依存Visual Basic for Applications、プロセス全体の設定が非互換性を引き起こす可能性がある点です。

  • SetSearchPathMode 関数を使用して、プロセスのセーフ プロセス検索モードを有効にします。 これにより、プロセスの有効期間中、SearchPath 検索リストの最後の場所に現在の作業ディレクトリが移動されます。

  • セーフ サーチ モードが有効になっている場合でも、DLL プリロード攻撃につながる可能性がある場合でも、完全修飾パスを指定せずに、SearchPath を使用して DLL の存在を確認しないようにします。

セキュリティで保護されていないライブラリの読み込み時の識別に関するガイダンス

ソース コードでは、セキュリティで保護されていないライブラリの読み込み例を次に示します。

  • 次のコード例では、アプリケーションは、セキュリティが最も安全な検索パスschannel.dllを使用して "schannel.dll" を検索します。 攻撃者が CWD にschannel.dllできる場合、アプリケーションが Windows ディレクトリで適切なライブラリを検索する前でも読み込まれます。

    DWORD retval = SearchPath(NULL, "schannel", ".dll", err, result, NULL); 
    HMODULE handle = LoadLibrary(result);
  • 次のコード例では、アプリケーションは LoadLibrary() 呼び出しについて、このドキュメントの冒頭で説明されているさまざまなアプリケーションとオペレーティング システムの場所からライブラリを読み込もうとします。 ファイルが存在しないリスクがある場合、アプリケーションは現在の作業ディレクトリからファイルを読み込もうとします。 このシナリオは、前の例よりも少し危険です。 ただし、環境が完全に予測可能ではない場合は、アプリケーション ユーザーがリスクにさらされます。

    HMODULE handle = LoadLibrary("schannel.dll");




より安全で安全なライブラリ ロードの例を次に示します。

  • 次のコード例では、完全修飾パスを使用してライブラリが直接読み込まれます。 アプリケーションのターゲット ディレクトリへの書き込みアクセス許可が既にある場合を限り、攻撃者が悪意のあるコードを導入するリスクはありません。

    HMODULE handle = LoadLibrary("c:\\windows\\system32\\schannel.dll");



    注意 システム ディレクトリを決定する方法については

    、GetSystemDirectory のリソースを参照してください。

    http://msdn.microsoft.com/en-us/library/ms724373%28VS.85%29.aspxSHGetKnownFolderPath

    http://msdn.microsoft.com/en-us/library/bb762188%28v=VS.85%29.aspx

  • 次のコード例では、LoadLibrary を呼び出す前に、現在の作業ディレクトリが検索パスから削除されます。 これにより、DLL プリロード攻撃を使用するために、攻撃者はアプリケーション ディレクトリ、Windows ディレクトリ、またはユーザーのパスで指定されたディレクトリのいずれかを制御する必要が生じ、リスクが大幅に軽減されます。

    SetDllDirectory ("");
    HMODULE handle = LoadLibrary("schannel.dll");
  • セキュリティ更新プログラム 963027 (MS09-014で説明) をインストールしているすべてのシステムで、次のコードは CWD を検索順序の最後の場所に完全に移動します。 後で、そのプロセス内から検索モードを変更しようとする SetSearchPathMode 関数の呼び出しは失敗します。

    SetDllDirectory ("");
    HMODULE handle = LoadLibrary("schannel.dll");
  • 次のコード例では、LoadLibrary を呼び出す前に、現在の作業ディレクトリが検索パスから削除されます。 これにより、DLL プリロード攻撃を使用するために、攻撃者はアプリケーション ディレクトリ、Windows ディレクトリ、またはユーザーのパスで指定されたディレクトリのいずれかを制御する必要が生じ、リスクが大幅に軽減されます。

    SetSearchPathMode (BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT );
    HMODULE handle = LoadLibrary("schannel.dll");

プロセス モニターを使用してセキュリティで保護されていない負荷を動的に検出する

Microsoft は、Process Monitor という名前のツールを発行します。 このツールを使用すると、開発者と管理者は実行中のプロセスの動作を密接に追跡できます。 プロセス モニターを使用して、アプリケーションの 1 つがこのような問題に対して脆弱であるかどうかを動的に検出できます。

  • プロセス モニターをダウンロードするには、次の Microsoft Web ページを参照してください。

    http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx

  • 特定のディレクトリに設定された CWD を使用して、アプリケーションを起動してみてください。 たとえば、アプリケーションにファイル ハンドラーが割り当てられている拡張子を持つファイルをダブルクリックします。

  • 次のフィルターを使用してプロセス モニターを設定します:



    代替テキスト

  • 脆弱なパスにヒットすると、次のような結果が表示されます: 代替テキストDLL を読み込むリモート ファイル共有の呼び出しは、これが脆弱なプログラムであることを示します。

詳細情報

詳細については、次の Microsoft Web ページ

「Dynamic Link Library Search Order」を参照してください。

http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspxSearchPath 関数に関する MSDN ドキュメント

http://msdn.microsoft.com/en-us/library/aa365527(VS.85).aspxLoadLibrary 関数に関する MSDN ドキュメント

http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspxSetDllDirectory 関数に関する MSDN ドキュメント

http://msdn.microsoft.com/en-us/library/ms686203(VS.85).aspxSetSearchPathMode 関数に関する MSDN ドキュメント

http://msdn.microsoft.com/en-us/library/dd266735(VS.85).aspxプリンシパル セキュリティ エンジニアの David Leblanc 氏によるブログMicrosoft Office

http://blogs.msdn.com/b/david_leblanc/archive/2008/02/20/dll-preloading-attacks.aspxDLL プリロード攻撃に関する MSRC エンジニアリング チーム、Andrew Roths 氏のブログ投稿

http://blogs.technet.com/b/srd/archive/2009/04/14/ms09-014-addressing-the-safari-carpet-bomb-vulnerability.aspx

その他のリソース

ヘルプを表示

その他のオプションが必要ですか?

サブスクリプションの特典の参照、トレーニング コースの閲覧、デバイスのセキュリティ保護方法などについて説明します。

コミュニティは、質問をしたり質問の答えを得たり、フィードバックを提供したり、豊富な知識を持つ専門家の意見を聞いたりするのに役立ちます。

この情報は役に立ちましたか?

言語の品質にどの程度満足していますか?
どのような要因がお客様の操作性に影響しましたか?
[送信] を押すと、Microsoft の製品とサービスの改善にフィードバックが使用されます。 IT 管理者はこのデータを収集できます。 プライバシーに関する声明。

フィードバックをいただき、ありがとうございます。

×