Microsoft Windowsを使う上で,あるいはアプリケーションを作成する上で 「DLL (Dynamic Loadable Library)」 は不可欠の機能になっている。そのDLLを呼び出す仕様がセキュリティ・ホールとなり,大きな話題となっている。

 DLLはUNIXプラットフォームの「Shared Library」に相当する機能であり,以下の機能を提供している。

・関数を複数のアプリケーションから共有できる

・データやリソースを複数のアプリケーションから共有できる

・アプリケーションの機能追加を行う場合,あるいは機能修正を行う場合,アプリケーションの再ビルドを行わず,DLLのみの交換を行うことで保守が可能になる

 これらの機能が目の前に示されたならば,だれでも一度は使ってみたくなる機能ではないだろうか?

 ところが,Win 32環境のDLLがOSによって探索される順序には好ましくない仕様があるのだ。

 ソース・ファイルからビルドされた実行型モジュール (*.exe) が DLL (*.dll) を呼び出す場合,以下の順序で指定されたDLLを呼び出している(注1)。

(注1)http://support.microsoft.com/support/kb/articles/Q151/6/46.asp

 例えば,「c:\Program Files\clickme.exe」が「dogood.dll」というDLLを呼び出すことを仮定しよう。この場合には,以下の順序で検索の問い合せが行われる。

(1)c:\Program Files\ に dogood.dll はあるか?

(2)カレントディレクトリに dogood.dll はあるか?

(3)Windows のシステムが格納されているディレクトリに dogood.dll はあるか?

(4)PATH 環境変数で指定されたディレクトリ内に dogood.dll はあるか?

 この仕様を利用することで,「不正なDLLと,それを呼び出す手段を攻撃先にメールで送り,ユーザーに分からないようにそのDLLを呼び出させて,悪意ある行為につなげる」という攻撃の可能性があると報告されている。

 Bugtraqでは,「BugTraq ID: 1699(注2)」として,この問題が報告されている。まず,Microsoft Office 2000形式の文書と,Officeアプリケーションが必ず読み込むDLLの名前をかたったDLL(以下,「偽DLL」)を同一ディレクトリに格納しておく。ユーザーがそのOffice文書を開くと,その時点のカレント・ディレクトリはその文書が格納されているディレクトリになるので,本来読み込まれるべきDLLの代わりに,偽DLLが呼び出されて実行してしまう。

(注2)http://www.securityfocus.com/bid/1699

 OfficeアプリケーションとOffice製品が用いるDLL名の組み合わせ以外に,問題を起こす可能性がある組合わせは他にも考えられる。例えば,

・WinZIP形式のアーカイブ・ファイル,WinZIPとRICHED20.DLL

・LZH形式のアーカイブ・ファイル,LhMelt等のアプリケーションとUNLHA32.DLL

・電子メール,EudoraとRICHED20.DLL

が身近な例だろう。

 この問題はUNC(Universal Naming Convention)を利用した環境,つまりファイル共有を利用している環境でも有効である。Office製品の例を示すならば,ファイル・サーバーで共有しているOffice形式の文書と同一の場所に偽DLLが保存されている場合,それが本来のDLLに代って呼び出されてしまう可能性があるのだ。

 この方法を使えば,リモートの攻撃者が任意のファイルを自由に操作できる可能性がある。例えば,ある攻撃者が,攻撃先の「boot.ini」ファイルを削除する場合を想定しよう。

 攻撃者は,Microsoft Officeアプリケーションには「RICHED20.DLL」あるいは「MSI.DLL」というDLLが必要であることを知っている(乱暴な検証方法だが,これらの DLLを削除すれば,Office製品が動作しなくなる事から確認可能)。

 そこで攻撃者は,攻撃先のboot.iniを削除する機能を持つDLLを作成し,RICHED.DLLあるいMSI.DLLと名前を変えて共有フォルダへ格納する。これで攻撃の準備は整った。その後,ユーザーが偽DLLと同じディレクトリにあるOffice 文書を開くと,攻撃先のboot.iniは削除されてしまう。

 この攻撃手段は,Windowsのシステムが格納されているDLLや,DLLを呼び出す実行型ファイルと同じディレクトリよりも先に,カレント・ディレクトリにあるDLLが呼び出されてしまう点を突いたものである。攻撃者はターゲットとなるコンピュータの,その時点でのカレント・ディレクトリに,悪意あるDLLを保存させ,何かのタイミングを用いてそれを呼び出させればよい。

 この問題はUNIXでは起こり得ないのであろうか。具体的な報告は公開されていないものの,UNIXがShared Libraryを探す順序を利用して,同様の攻撃が考えられる。

 UNIXは以下の順序でShared Libraryを探す。

(1) 環境変数 LD_LIBRARY_PATH で指定されたディレクトリ

(2) 各UNIXでデフォルトで参照されるディレクトリ。通常OSが提供するShared Libraryが格納される。(/usr/lib, /usr/share/lib 等)

(3) 実行ファイルのビルド時に参照する用指定されたディレクトリ。 (/usr/local/lib, /usr/X11R6/lib 等)

 この順序を利用して,悪意あるShared Libraryを実行型ファイルへ読み込ませることで同様の攻撃が可能だ。ただし,この攻撃を成立されるためには以下の条件がそろっていることが必要であり,この攻撃が実際に行われたという報告は,今のところ公にはされていない。また,実行ファイルのビルド時に環境変数 LD_LIBRARY_PATH の値を無視するように設定することも可能であるため(そのようにビルドが行われる場合が多いだろう),この場合にはShared Libraryを探す順序を利用した攻撃の成立可能性はより低くなる。

(1) 攻撃対象のユーザの環境変数 LD_LIBRARY_PATH へ値を代入できる

(2) 環境変数 LD_LIBRARY_PATH で指定されたディレクトリに Shared Library を追加できる

(3) 追加されたライブラリが攻撃対象のユーザ権限で読み出し,実行可能なパーミッションが与えられている

 さて,この問題については対策は有り得るだろうか。システム管理者側からの対策を考えると,対策をメールに限れば「配送されてくるメールの内容にDLLファイルが含まれているかどうかを確認し,含まれていれば配送拒否する」という手段が当座の対策として考えられる。しかし,すべてのサイトでこのフィルタリングを導入できるかは議論の余地があるだろう。メールの内容に対してフィルタリングを行った場合,メールの配送処理速度が実用的なものになるかどうかが議論の余地がある。

 また,メールについて対応が行われても,一般ユーザがWebを介してDLLファイルをダウンロードする可能性は残される。Webの場合,HTTP のリクエスト内に「dll」の文字列が指定される可能性があるため,単純な文字列走査によるアクセスコントロールだけでは,かえってWebの利便性を半減させることを引き起こしかねない。この場合,より知的な処理を加えたフィルタリングが必要だろう。

 他方,一般ユーザは何を対策すればよいだろうか。既存の攻撃手段と組み合わせることで,ダウンロードしたDLLを一般ユーザが誤まって実行する可能性はゼロとは言えない。上記で公開されたDLLファイルは特定の何種類かであるが,組み合わせを考えるとありとあらゆるDLLとアプリケーションの組合わせが考えられるため,一般ユーザが対策できる余地は小さい。あえて対策を試みるならば,一般ユーザは以下を心得ておかなければならないと言えよう。

・不必要なファイルを(Webを通じて)ダウンロードしない

・内容が明確ではないメールをむやみに受け取らない

 一番の問題である「DLLの呼出し順序」の改善や「DLLが期待したDLLなのかを判断する手段」が開発され,実用に供されない限り,また,『屋上屋を架す』実装や,無意味に過去の仕様を引きずる限り,この問題への抜本的な対策は施せないだろう。


坂井順行 (SAKAI Yoriyuki)
株式会社ラック 不正アクセス対策事業本部
sakai@lac.co.jp


 IT Proセキュリティ・サイトが提供する「今週のSecurity Check [一般編]」は,その週に起きたUNIX関連およびセキュリティ全般のニュースや動向をまとめた週刊コラムです。セキュリティ・ベンダーである「株式会社ラック」のスタッフの方を執筆陣に迎え,専門家の立場から解説していただきます。