========================================================== セキュリティ勧告 - NTサーバ上におけるJetセキュリティ問題 ========================================================== 発行日: 2000年2月1日 発行者: 塩月 誠人 セントラル・コンピュータ・サービス株式会社 ---------- はじめに ---------- このセキュリティ勧告は、NTサーバ上におけるJetセキュリティ問題の存在を広 く啓蒙するとともに、実際にこの問題の影響を受けているサーバプログラムの利 用者に対してその危険性を警告することを目的として書かれたものである。 この問題自体の指摘は1999年5月に、.rain.forest.puppy.氏によって行なわれて おり[1]、決して新しく発覚した脆弱性ではない。しかし、 - この問題の危険性があまり広く認識されていない - この問題の影響を受けているサーバプログラムが複数確認された ことより、今回このセキュリティ勧告を発行することとした。 本文書中にはこの問題の影響を受けるサーバプログラムに対する、具体的な攻撃 方法の記述も含まれている。これはあくまでも、読者に「どのようなプログラム が危険か」を的確に理解してもらうことを目的としている。くれぐれも管理権限 のないホストに対してテストあるいは攻撃行為を行なわないでいただきたい。ち なみに管理権限のないホストに対して今回の問題を利用した攻撃を行なうこと は、いわゆる不正アクセス禁止法[2]における不正アクセス行為に該当し、処罰 の対象になると考えられる。 ------ 概要 ------ Windows NT上で稼動する、MS Accessデータベース(mdbファイル)にアクセスする ようなサーバプログラムは、Jetセキュリティ問題(いわゆる Office ODBCドライ バ問題)の影響を受ける可能性がある。このセキュリティ問題の影響を受ける サーバプログラムに対し、悪意を持ったユーザが不正な入力を行なうことによ り、サーバマシン上で任意のコマンドが起動する危険性が生じる。 インターネット上で実際に使われているWebベースの掲示板システムなどの中に も、この問題の影響を受けるものがいくつか確認されている。これらを使用して いる場合は、ベンダが提供するパッチを適用するか、あるいは以下に示す対策手 段を講じる必要がある。またサーバプログラム開発者は、この問題を良く理解 し、脆弱性の無いプログラム開発を心がけていただきたい。 --------------------- Jetセキュリティ問題 --------------------- 本文書中で「Jetセキュリティ問題」と呼んでいるのは、「Office ODBCドライバ 問題」としてマイクロソフトがセキュリティ情報[3]およびセキュリティフィッ クスを提供している問題点のうち、Jetデータベースエンジンがクエリ文中に書 かれたVBA関数を実行してしまうという「VBA Shell問題」を指す。 Excelワークシート等のOfficeドキュメントがデータベースクエリを発行する 際、クエリSQL文中にVBA関数が記述されている場合、クエリを受け取ったJet データベースエンジンはそのVBA関数を実行する。VBA関数の中には Shell() の ように任意のOSコマンドを起動するようなものもある。そのため、Shell関数を 使用してシステムに悪影響を与えるコマンド(ファイルの削除等)を実行するよう なクエリ文を含む、Officeドキュメントを作成することが可能となる。これはマ クロを使用したものではないため、Officeのマクロ警告機能によって警告される こともなく、また通常ウィルススキャンでも検出されない。 マイクロソフトはこの問題に対処するため、Jetデータベースエンジンに実行す る機能を制限させるSandboxモードを導入した。セキュリティフィックスを適用 するとSandboxモードが有効となり、Excelワークシート等からのクエリ経由でシ ステムに害を与えるような機能は使用できなくなる。 このように、この問題はOfficeドキュメントを使ったセキュリティ攻撃として一 般的には認知されているが、マイクロソフトのセキュリティ情報にもある通り、 この問題自体はJetデータベースエンジンを使用するすべてのプログラムに関連 するものである。 ----------------------------- サンプルWebアプリケーション ----------------------------- それでは、NTサーバ上のどのようなプログラムがこの問題の影響を受ける危険性 があるのだろうか。Jetセキュリティ問題の影響を受けるサーバプログラムの要 件として、次の項目があげられる。 1. Jetデータベースエンジンを使用している(mdbファイルにアクセスする) 2. ユーザ入力データをSQL文の中に挿入している Jetの使用については、ODBC経由の場合とプログラムから直接Jetにアクセスする 場合があるが、いずれの場合も影響する。またユーザ入力データは、Webアクセ スの際のPOSTデータ(フォーム入力)、GETデータ、クッキー、ヘッダ情報などが 考えられる。 例として、Accessデータベース(mdbファイル)のデータを検索して結果を表示す るWebアプリケーションを考えてみよう(ASPソースコードは本文書の最後に添 付)。このサンプルWebアプリケーション(search.asp)では、ユーザがフォーム入 力したデータ(word)をSQL文の検索条件に挿入して、Accessデータベース (btcustmr.mdb)を検索している。 set db=Server.CreateObject("ADODB.Connection") db.Open "btcustmr" sql="select * from Customers where City='" & word & "'" set rs=db.Execute(sql) (注: btcustmr.mdbはIISのヘルプの一部としてデフォルトでインストールされる ファイルである。ここではこのmdbファイルをサンプルとして利用した。) 問題は、このプログラムではユーザ入力データをそのままSQL文の中に入れてい ることだ。ここで例えば下記のようなデータをフォームに入力したとしよう。 |shell("cmd /c echo aaa > c:\test.txt")| (注: "|" は縦棒文字) このプログラムは以下のSQL文をJetデータベースエンジンに投げる。 select * from Customers where City='|shell("cmd /c echo aaa > c:\test.txt")|' Jetは縦棒文字(|)で囲まれた部分をVBAスクリプトだと解釈するので、VBA Shell ()関数を呼び出す。すなわち、サーバ上で cmd /c echo aaa > c:\test.txt が 実行されることになる。このサンプルプログラムでは単純に City='word' とい う検索条件だが、City like '%word%' というような検索条件であったとしても、 入力文字列を巧妙に工夫することによりJetにShell関数を呼び出させることは 可能である。 起動されるコマンドがどのような実行権限になるかは、サーバプログラムに依存 する。上記の例のようにIISのASPからODBC経由でJetにアクセスする場合は、ロ ーカルシステム権限で任意のコマンドが実行される。 ------------------------------ 影響を受けるサーバプログラム ------------------------------ 筆者が現時点で確認している、この問題の影響を受けているプログラムは、以下 の通りである。 プログラム名: WebBoard for IIS 開発元 : 有限会社インプット (http://www.input.co.jp/) プログラム名: DST BBS 開発元 : 金藤 仁氏 (http://rose.ruru.ne.jp/dst/) プログラム名: インターネット掲示板スクリプト 『けいじ 君』 開発元 : H2O Software (http://www.h2o-soft.com/) プログラム名: ZpayBBS 開発元 : Paul Mayer氏 (http://zpay.com/bbs.htm) プログラム名: WarFTPd 1.70.b 開発元 : Jarle (jgaa) Aase氏 (http://www.jgaa.com/warftpd.htm) (注: ログをmdbファイルに記録するように設定している場合) これらのプログラムを使用しておられるサイト管理者は、フィックスについて開 発元にコンタクトされることをお勧めする。WarFTPdは既にフィックスモジュー ルが提供されている。他の開発元にも今回のセキュリティ問題については通知済 みなので、しかるべき対応策の提示が期待される。 これらのプログラム以外にも、Jet問題の影響を受けるWebアプリケーション等は 少なくないと思われる。比較的小規模なデータベースをWebブラウザからアクセ スさせるようなWebページを構築する場合、mdbファイルを利用するケースは結構 多いだろうし、その際にSQL文の検索条件として格納するユーザ入力文字列をわ ざわざチェックしないことはありがちな話である。インハウス開発のサーバプロ グラムについても、脆弱性の有無を一度確認した方が良いだろう。 ---------- 対策方法 ---------- NTサーバにおけるJetのセキュリティ問題は、アプリケーションプログラム側の 問題とJetデータベースエンジンの問題の二つが絡んでいる。よって基本的な対 策方法としては、次の二通りのいずれかが考えられる。 1. サーバプログラムにおいてユーザ入力データのチェックを行なう 前述のサンプルプログラムに見られるように、ユーザ入力データをそのまま SQL文に挿入している場合、不正な文字列を入力されると問題になる。一般 論としてサーバプログラムは、ユーザ入力文字列の妥当性をチェックし、正 当な文字コードのみを受け入れるべきである。今回の場合、少なくとも縦棒 文字(|)はSQL文に渡すべきではない。どうしても渡したい場合はJetデータ ベースエンジンが解釈しないような形にエスケープしなければならない。マ イクロソフトの技術文書Q147687[4]が参考になるかも知れない。 2. JetデータベースエンジンのSandboxモードを有効にする 前述した通り、マイクロソフトはJetのセキュリティ問題について、Jetに Sandboxモードというセキュアな実行モードを導入することで対応してい る。標準的なIISマシンにインストールされているJet3.5(通常は 3.51.0623.4)はSandboxモードに対応していないので、Jetモジュールのバー ジョンアップが必要である。またJet4.0もバージョンによってはSandbox モードに対応していない。以下のマイクロソフト文書を参考の上、Jetの バージョンアップを行なうことでSandboxモードが使えるようになる。 Jet3.5の場合 --- MS文書番号: J050041 [5] Jet4.0の場合 --- MS文書番号: J050042 [6] Sandboxモードに対応したJetがインストールされると、Jet起動時に次のレジス トリが自動的に設定される[7]。 Key : HKLM\Software\Microsoft\Jet\3.5\Engines ... Jet3.5 HKLM\Software\Microsoft\Jet\4.0\Engines ... Jet4.0 Name : SandboxMode Type : REG_DWORD Value: 0 ... Sandboxモードが常に無効 1 ... SandboxモードがAccessアプリケーションに対してのみ有効 2 ... Sandboxモードが非Accessアプリケーションに対してのみ有効 (デフォルト) 3 ... Sandboxモードが常に有効 デフォルトでは2すなわち、Accessアプリケーション以外からのアクセスについ てSandboxモードが有効になる。通常はこのレベルで十分であろうが、念のため に3(常にSandboxモードが有効)にしておいた方が安全である。ただしJet3.0以前 のバージョンではSandboxモードに対応できないので注意が必要である。 Sandboxモードが有効になると、特定の安全と考えられるVBA関数以外はJetから 使用できず、Shell()関数を使った今回のような攻撃は働かなくなる。そのた め、アプリケーションプログラムの修正でこの問題に対応することが困難な場合 は、JetのSandboxモードを有効にする方法で対処することが推奨される。ただ し、Jetのバージョンアップは場合によっては互換性の問題を引き起こすことも 考えられるので、十分な事前検証が必要であろう。 もう一つの対策方法として、アプリケーションプログラムにユーザの入力が届く 前に、不正な文字をフィルタする(除外する)やり方が考えられる。次に示すIIS のISAPIフィルタを利用する方法である。 3. IISのISAPIフィルタで不正な文字列を排除する IISのISAPIフィルタは、URLやPOSTデータをアプリケーションに渡す前に チェックすることが可能である。つまり今回の場合で言えば、特定のURLに おいて縦棒文字(|)を排除するような機能を持つISAPIフィルタをIISに導入 することで、JetのVBA Shell問題に対処することができる。 例えばJet3.0以前のバージョンでは基本的にSandboxモードに対応できない。そ のような古いJetをアプリケーションが使用しており、さらにそのアプリケー ションに手を入れることが困難な場合(あるいは時間がかかる場合)は、こういっ たISAPIフィルタの導入が有効と考えられる。 今回このセキュリティ勧告を発行するにあたり、長谷川氏(セントラル・コン ピュータ・サービス)が開発したISAPIフィルタ「guard3 [8]」を同時に公開する こととした。このISAPIフィルタは、 - 特定のURLにおいて、特定の文字変換を行なう - 指定長より長いURLによるアクセスを拒否する という機能を持つ。インストール方法や機能の詳細については付属のドキュメン トおよびソースコードを参照願いたい。 ---------- おわりに ---------- 本文書は様々な検証結果および各種技術情報に基づき、細心の注意をはらって作 成したが、もし文書中に誤りがあった場合は筆者までご連絡いただきたい。また 本文書の最新版は以下のURLで参照できる。 http://www.trusnet.com/advisories/jetshell/jetshell.txt 本文書および配布するソフトウェアは無保証である。それらの利用に起因する障 害、動作不良、セキュリティ侵害等、いかなる結果について、筆者、当該ソフト ウェア開発者、およびその雇用者は一切の責任を負わない。また筆者による事前 の許諾なしに本文書を再配布することは禁止する。 なお本文書を作成するにあたり、議論および検証を通じて貴重な意見や助言を下 さったPort139の伊原氏に感謝する。 塩月 誠人 セントラル・コンピュータ・サービス株式会社 ======================================================================== 参考Webサイト: [1] Advisory: NT ODBC Remote Compromise http://www.wiretrip.net/rfp/p/doc.asp?id=3&iface=2 [2] 不正アクセス行為の禁止等に関する法律 http://www.npa.go.jp/seiankis8/main.htm [3] Office ODBC ドライバの問題点 http://officeupdate.microsoft.com/japan/Articles/mdac_typ.htm [4] HOWTO: Query for Literal Special Characters in a Where Clause http://support.microsoft.com/support/kb/articles/q147/6/87.asp [5] [AC97] Microsoft Jet 3.5 のアップデートバージョンがMSLで入手可能 http://www.microsoft.com/japan/support/kb/articles/j050/0/41.htm [6] [ACC2000] アップデート バージョンの Microsoft Jet 4.0 http://www.microsoft.com/japan/support/kb/articles/j050/0/42.htm [7] [odbc]Jet の式が安全でない VBA 関数を実行 http://www.microsoft.com/japan/support/kb/articles/j050/0/45.htm [8] ISAPIフィルタ「guard3.dll」 http://www.trusnet.com/tools/guard3/index.html ======================================================================== 付録: サンプルWebアプリケーションASPソースコード(search.asp) (注: \WINNT\Help\iis\htm\tutorial\btcustmr.mdbをシステムDSN "btcustmr" としてODBCデータソースに登録して使用) ------------------------------------------------------------------------ Search <% if Request.Form="" then %>

Search

Enter word:

<% else word=Request.Form("word") %>

Results

Word: <% = word %>

<% set db=Server.CreateObject("ADODB.Connection") db.Open "btcustmr" sql="select * from Customers where City='" & word & "'" set rs=db.Execute(sql) do while not rs.EOF Response.Write rs("City") & "

" rs.MoveNext loop db.Close %> <% end if %> ========================================================================