Backdoor.Prioxer!inf: 偶然ながらこれまでにないステルス性を備えた感染型マルウェア
Trojan.Koredos のインシデントに続いて、バックドアを利用するきわめて興味深いトロイの木馬が見つかりました。Backdoor.Prioxer です。シマンテックが Backdoor.Prioxer を入手したソースは、Trojan.Koredos にも感染していました。この 2 つの間に直接の関連は立証できていませんが、どちらも同じ場所に由来している可能性は高いとシマンテックは考えています。
Trojan.Koredos について詳しくは、以前のブログ記事を参照してください。簡単に言うと、Koredos は韓国の複数の Web サイトに対する標的型攻撃に使われた脅威です。このトロイの木馬はモジュール式のアーキテクチャを持ち、ある程度高度なものであることから、この攻撃はかなり態勢の整ったマルウェア作成者の手によるものと推測されます。
では、Prioxer は何が独特なのでしょうか。一見しただけでは、バックドアを利用する普通のトロイの木馬と同じで、実際そのとおりです。インストーラは、ボットネットのコンポーネントである .dll を投下します。このボットは、IRC 経由で動作し、コマンド& コントロール(C&C)サーバーとの間でコマンドやデータをやり取りします。脅威のファイルは、暗号化も不明瞭化もされていません。また、コンピュータの再起動後にも存続するように、Windows のシステム .dll ファイルに感染します。感染した .dll は、Windows を起動するたびにロードされ、脅威のペイロードがボットネットの .dll ファイルを再ロードします。目新しい点はありませんが、感染したファイルが完全に不可視である点だけは特筆に値します。
まったく目に見えない感染 - これは偶然か
Prioxer はルートキットを使っているわけでも、カーネルモードのコードを使っているわけでもありません。単純なアプリケーションで、どうすればこのような不可視性を達成することができるのでしょうか。Prioxer は、多くのセキュリティツールをすり抜けることに成功しているのです(あるルートキット対策ツールだけは例外的に、独自のファイルブラウザユーティリティを使って、感染した .dll ファイルを抽出することができます)。
感染コードを詳しく調べると、この謎を解くことができます。
図 1: ディスクボリュームが FAT32 か NTFS かを判定し、独自のファイルシステムインタープリタを実行するコード
.dll を投下するメインのコードには、FAT32 と NTFS のファイルシステムに対する独自のパーサーが組み込まれています。このコードが C ボリュームを RAW モードで開き、ディスクセクタの手動読み込みを実行したうえでディスクデータを手動で解析し、ファイルシステム構造を認識して、感染の標的とする .dll ファイルがディスクのどこにあるかを検出します(また、RAW 書き込み操作を実行してファイルを感染させます)。このような機能はすべて、カーネルのファイルシステム層に存在するのが普通です。アプリケーションでファイルパスが指定されると、ファイルシステムドライバ(Windows コンピュータではほとんどの場合 NTFS)がディスク上でファイルデータの場所を特定します。Prioxer には、ファイルシステム層を完全にすり抜けて直接ディスクにアクセスすることで、独自にこれらを行う機能があります。
.dll ファイルに RAW モードで感染することによって、Prioxer はファイル自体に対するフィルタや制限もすり抜けることができます。ハードウェアリソースに対する RAW アクセスが可能な脅威はごく一般的なものなので、Prioxer はその点で新しくもなく、また画期的でもありません。
ところが、ここで問題になるもうひとつの特徴があります。それはキャッシングです。NTFS ファイルシステムドライバは、パフォーマンスの向上を図るために、読み込み頻度の高いファイル(Windows の .dll ファイルも多くの場合これに該当します)のキャッシュを維持します。キャッシュされているファイルに変更を加えるたびに、NTFS はファイルの変更を反映するためにメモリキャッシュを更新する必要があります。しかし、Prioxer はファイルシステム層を完全にすり抜けて直接ディスクに書き込みを行うため、キャッシュに存在するシステム .dll ファイルに変更があったことを NTFS が認識できず、そのファイルのキャッシュは更新されません。
図 2: 感染した .dll がディスク上に存在しても、NTFS のキャッシュは未感染の .dll が残るので、結果的に感染が見えなくなる。
このことから矛盾した状況が生まれます。キャッシュされた .dll ファイルは未感染の状態ですが、ディスク上には感染したファイルが実際に存在します。つまり、感染したファイルにアプリケーションから、あるいはカーネルモードドライバからアクセスを試みた場合には、NTFS 層を介してアクセスすることになり、NTFS は未感染状態の .dll ファイルのデータを返します。そのため、実際に感染した .dll ファイルはディスク上に存在しながら不可視の状態になるのです。
この動作はバグではなく、NTFS の設計上の欠陥でもないことに注意してください。キャッシュは本来の機能を果たしているに過ぎません。もちろん、NTFS ファイルシステムより物理的なレベルで動作するユーティリティであれば、感染したファイルにアクセスが可能です。また、キャッシュは永続的なものではないので、キャッシュされた感染ファイルが最終的には更新され、再び見える状態になる可能性もあります(たとえば、メモリが高負荷の状態になった後や、単に再起動した後など)。
図 3: 標的となった DLL における感染コード
実際には Prioxer が自発的に自身の隠蔽を図っているわけではないことを考えると、この不可視化の機能はマルウェア作成者が意図したものではなく、副作用として都合よくシステムの機能を悪用できただけという可能性があります。ただし、この例からわかるように、悪用された場合にはこの手口は非常に効果的です。(ルートキットが通常必要とする)カーネルモードドライバを使わずに、ユーザーモードから実行することも可能です。
ボット
ペイロードは単純なボットで、IRC プロトコルを介して動作します。このボットは、他の標準的な IRC バックドアと同じように、チャットメッセージの形式で C&C サーバーとデータをやり取りします。そこで C&C サーバーにアクセスすると、興味深い情報を得ることができました。
PASS [削除済み] NICK [ニックネーム] USER nobody unknown unknown :noname :MyWebServer 375 [ニックネーム] :- MyWebServer Message of the Day - :MyWebServer 372 [ニックネーム] :- This is ircd-hybrid MOTD replace it with something better :MyWebServer 376 [ニックネーム] :End of /MOTD command. VERSION :MyWebServer 351 [ニックネーム] hybrid-7.2.3(SVN). MyWebServer :egIKMZ6 TS6ow USERS :MyWebServer 265 [ニックネーム] :Current local users: 46 Max: 53 :MyWebServer 266 [ニックネーム] :Current global users: 46 Max: 53 LIST :MyWebServer 321 [ニックネーム] Channel :Users Name :MyWebServer 322 [ニックネーム] #mail01 5 : :MyWebServer 322 [ニックネーム] #god8 1 : :MyWebServer 322 [ニックネーム] #god2 8 : :MyWebServer 322 [ニックネーム] #god3 1 : :MyWebServer 322 [ニックネーム] #god1 2 : :MyWebServer 322 [ニックネーム] #god4 1 : :MyWebServer 322 [ニックネーム] #kkk3 4 : :MyWebServer 322 [ニックネーム] #kkk2 19 : :MyWebServer 322 [ニックネーム] #kkk1 8 : :MyWebServer 323 [ニックネーム] :End of /LIST LUSERS :MyWebServer 251 [ニックネーム] :There are 0 users and 47 invisible on 1 servers :MyWebServer 254 [ニックネーム] 9 :channels formed :MyWebServer 255 [ニックネーム] :I have 47 clients and 0 servers :MyWebServer 265 [ニックネーム] :Current local users: 47 Max: 53 :MyWebServer 266 [ニックネーム] :Current global users: 47 Max: 53 :MyWebServer 250 [ニックネーム] :Highest connection count: 48 (48 clients) (265 connections recei ved) STATS :MyWebServer :MyWebServer 212 [ニックネーム] JOIN 313 1589 :0 :MyWebServer 212 [ニックネーム] NICK 270 4658 :0 :MyWebServer 212 [ニックネーム] PASS 271 3794 :0 :MyWebServer 212 [ニックネーム] PRIVMSG 4238 2345746 :0 :MyWebServer 212 [ニックネーム] USER 269 8070 :0 :MyWebServer 212 [ニックネーム] WHOIS 234 8520 :0
図 4: IRC C&C サーバーのデータログの一部。USERS コマンドで、一定期間におけるユーザー数を表示する。LIST コマンドで、利用可能なチャネルと、そのチャネルを使っているユーザー数を表示する。STATS コマンドで、サーバーで各コマンドが使われた回数を表示する。
標準的な IRC コマンドを発行して、統計のリストとユーザー数を取得してみたのが上の図です。STATS コマンドを使うと、各コマンドが実行された回数(コマンド名に続く 2 番目の数字)を示すグローバルなカウンタを表示できます。JOIN、NICK、PASS、USER の各コマンド(通常は、ボットが自身の認証とチャネルへの参加に利用する)はおおむね一定であり、数千の桁であることがわかります。言うまでもなく、これはボット以外も含めた合計なので、このボットネットのサイズは全体で約 100 と推定してよく、比較的小規模です。すでに述べたように Koredos との関連性も考えられる以上、この規模も意外ではありません。標的型攻撃である以上、拡散する恐れは高くないと言えます。
ここでは不可視化の機能を中心に説明しましたが、上述したとおり Prioxer がそれを意図的に行っているわけではなく、自発的な隠蔽の処理も見られません。そのため、キャッシュを使った手口が機能するのも限られた時間だけです。防御策としては、コンピュータを再起動しさえすれば悪質な感染が見えるようになるので、セキュリティ製品で検出されます。感染してから長時間コンピュータが実行されている場合には、キャッシュの更新によって感染が見えるようになっている可能性も十分あります。
意図された結果ではないにしても巧妙な手口と言えますが、最新のウイルス定義に更新済みであれば、この脅威の心配はありません。
* 日本語版セキュリティレスポンスブログの RSS フィードを購読するには、http://www.symantec.com/connect/ja/item-feeds/blog/2261/feed/all/ja にアクセスしてください。