動的なポート割り当てがマッパーの役目

 以上のように,エンドポイント・マッパーからは攻撃者にとって有用な情報が簡単に手に入る。では,何のためにこれらの情報が取得できるようになっているのだろうか。

 これを理解するためには,RPCの仕組みを知る必要がある。RPCとは,異なるプロセス間でデータをやり取りしたり,相手のプロセスが持つ機能の呼び出し/実行を実現するために考えられたメカニズムである。個々のプロセスはローカルにあっても,異なるコンピュータ上にあってもかまわない。基本的にサーバー-クライアント方式なので,サーバーアプリケーションが提供する機能をクライアント・アプリケーションが呼び出す,という形になる。

図2●RPCの呼び出し手順(スタティック・バインディングの場合)
RPCでは,インタフェースという形で,複数の関数を一まとまりにして公開している。インタフェースは一意の識別子UUIDを使って呼び出す。関数を利用する場合は,インタフェースを呼び出した後,関数に処理を依頼する。関数への処理依頼はオペレーションという。ちなみに,サービスは複数のインタフェースを持つことができる。図のように,Windows XP以降ではタスクスケジュール・サービスは三つのRPCインタフェースを持っている(Windows 2000では二つ)。
図3●RPCのダイナミック・バインディング
目的とするRPCサーバーを呼び出せるプロトコルやインタフェースへの接続場所(例えばTCPのポート)など,いわゆるエンドポイントがあらかじめ分からないと,RPCサーバーを利用できない。そこで,RPCの仕様では,RPCサーバーのインタフェースとそのエンドポイントを対応付けたエンドポイント・マップを提供するインタフェース/オペレーションが定められている。

 RPCの仕様に登場する概念としてオペレーションと,インタフェースというものがある。オペレーションはプロシジャに相当するもので,インタフェースはプロシジャの集まりを代表するものである。エンドポイント・マッパー・データベースに登場するUUIDはこのインタフェースごとに付与されたIDである(RPCの仕様で規定されている)。クライアント側はこのUUIDを呼び出し,オペレーションを実行する形態になる(図2[拡大表示])。

 この図では,RPCクライアントがRPCサーバーのTaskScheduler2というインタフェースに接続し,オペレーションTS2-1とTS2-2を呼び出した,という一連の流れを描いている。RPCクライアントはこの一連の要求をRPCサーバーが用意するエンドポイントに送信すればよい。RPCクライアントがRPCサーバーのエンドポイントを知っている場合に通信が成立する。相手のエンドポイントを知り,直接接続する方法をスタティック・バインディングと呼ぶ。

 スタティック・バインディングは(1)利用者がRPCサーバーのエンドポイント(例えば,IPアドレスとTCP/IPのポート番号)を知っている必要がある,(2RPCサーバー開発者が別のアプリケーションと重ならないようにエンドポイントを準備しなければならない,といった制約がある。それを補うため,RPCの仕様ではエンドポイントを動的に割り当てるダイナミック・バインディングという別の方式も用意されている。

 このダイナミック・バインディングを実現するために用意されるのが,先に述べたエンドポイント・マッパーである。インタフェースIDからインタフェースを提供するアプリケーションのエンドポイントを探すためのマップ(対応表)を提供するのがエンドポイント・マッパーの役目なのである。そして,エンドポイント・マッパーに接続するためのエンドポイントはRPCの仕様で定められており,RPCクライアントはそこに接続することになっている(135/udp,135/tcpと定められている)*2図3[拡大表示]にダイナミック・バインディングのRPC呼び出しのシーケンスを示した。

 以上のように,エンドポイント・マッパーがマップを提供するのはRPCの仕様に沿った実装なのである。

135番を閉じても情報は取れる

 ところで,攻撃者にとって都合のよい情報を提供してしまうエンドポイント・マッパーを使わないことはできないのだろうか。実はそれは可能だ。RPCの仕様上は,スタテック・バインディングのみでオペレーションを呼び出しても問題がないからである。

 それでは,悪用されることを避けるためエンドポイント・マップに情報を置かないよう,使い勝手を犠牲にしてスタティック・バインディングを使えばよいのかといえば,実はそうでもない。RPCサーバーのエンドポイント(例えばTCPのポート)では必ずRemote Management Interface(RMI)というインタフェースが公開されている。

 RMIはRPCの仕様で定まっているもので,Windowsでも実装されている。このため,RPCサーバーの開発者が個別に実装する必要はない。RMIに問い合わせることにより,例えばTCPポート1025にRPCサーバーがいるかどうかを判定することができる。公開されている場合はそのRPCサーバーのインタフェースID(UUID)の一覧が取得できる。つまり,特定のポートに限定されるものの,エンドポイント・マッパーのようにそのポートで待ち受けているサーバーの種類を調べることができるのだ。しかも,このオペレーションは,ユーザー名およびパスワードを知らなくても呼び出すことできるので,危険性としてはエンドポイント・マッパーから情報を取得する場合とほとんど変わらない。


関 英信 Hidenobu Seki

セキュリティフライデー 技術企画室長
Windowsのセキュリティについての調査や製品開発を行う一方,啓蒙活動としてSecurityFriday.comで技術文書や無償ツールを公開している。2004年1月に米国シアトルで開催された「Black Hat Windows Security 2004 Briefings」において,Microsoft RPCの知られざる危険性を報告し,注目を集めた。