Symantec Security Response Weblog
Inside Trojan.Clampi: Network Communication」より
October 6,2009 Posted by Nicolas Falliere

 「Trojan.Clampi」は最近非常に注目されているマルウエアの一つで,多くの記事や技術解説レポートが出ている。当ブログでも,シリーズでClampiの興味深い点や珍しい側面を紹介していく。今回は,Clampiの重要な機能であるネットワーク通信について説明しよう。

 Clampiをよく知らない読者のために,まず概要を書いておく。Clampiはトロイの木馬の一種で,主に個人情報,例えばパスワードや各種ログイン情報,ソフトウエアのライセンス,クレジットカード番号,銀行口座番号といった情報の不正取得を目的としたものである。Clampiの動作は,中核となる実行ファイルがダウンロードし,Windowsのレジストリに格納する「ヘルパー・モジュール」によって実現される,ということを覚えておいてほしい。

 パソコンに感染したClampiは,レジストリ値「GatesList」に記載されているゲートウエイ・サーバーの一つに接続する。このレジストリ値は,Clampiが感染する処理を実行する際に,「HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Settings」というサブキー内に設ける。

 接続先の「Gate」と呼ばれるゲートウエイ・サーバーは,Webサーバー・ソフトウエア「Nginx」で動いている。Clampiは感染パソコンから情報を得ると,それをGateに送信する。通信にTCPの80番ポートと標準的なプロトコルであるHTTPを使うため,Clampiは企業ネットワークに導入されているファイアウォールその他の関門を易々と通り抜ける。

 Clampiの通信モデルは極めて単純だ。クライアントが,盗んだ情報をPOSTリクエストに埋め込んででゲートウエイ・サーバーに送ったり,ゲートウエイ・サーバーに対して「次に何をすればよいか」と問い合わせたりする。これに対し,ゲートウエイ・サーバーは標準的なHTTP/200を応答する。

 ClampiのPOSTリクエストの内容は単純なASCII文字列であり,以下のような構造をしている。

o=[OPERATION]&s=[CLIENT_ID]&b=[DATA_CHUNK]

 各項目の内容は以下の通り。

・[OPERATION]:「i」「a」「c」「d」「u」のどれか1文字を入れる

・[CLIENT_ID]:16文字分の領域に,感染パソコンを特定するためのセッションごとに変わるランダムなIDを入れる

・[DATA_CHUNK]:Base64系アルゴリズムでエンコードしたペイロードを格納する。さらに,ペイロードは「Blowfish」という電子符号表(ECB)ベースの有名な対称暗号アルゴリズムで暗号化する。暗号鍵は,Blowfishで使える最も長い56バイトの鍵を使っている。我々は,リバース・エンジニアリングでペイロードの解読とデコードに成功した。

 標準的な「起動」パケットのスクリーンショットを以下に掲載しておく。

 クライアントはGateとの接続を確立するために,まず「o=i」(Initiate:起動)と「o=a」という二つのクエリーを送る。Initiateクエリーの長さは256バイトで,たいていの場合,後でBlowfishの暗号化に使うエンコード済みセッション鍵が入っている。「o=a」クエリーは,さらに難読化が施されている。

 面白いことに,この二つの処理は各セッションで1回しか実行されない。(接続タイムアウトが発生するなどして)ゲートウエイ・サーバーとの接続が切れた場合,クライアントが「o=u」(この「u」は「Update(アップデート)」の意味だろう)クエリーを送る。Blowfishは,クライアントの通信するゲートウエイ・サーバーが最初に鍵を決めた時のサーバーと違っていても,改めて鍵交換はしない。Updateクエリーも同様だ。恐らく,ゲートウエイ・サーバー同士がP2P方式でクライアントの情報をやり取りしているか,より上位層に別のサーバーがあって,ゲートウエイ・サーバーとクライアント間で実行中のセッションを管理しているかのどちらかだろう。

 InitiateクエリーとUpdateクエリーの処理が終わると,暗号化された通信経路が完成する。これ以降,Blowfishはデータを暗号化する。幸いなことに,我々はトラフィックの内容を復号する鍵を入手できた。データを復号してみたところ,やり取りするペイロードのMD5ハッシュ値が入っていたのだ。これは,第三者によるパケット改ざんを防ぐための対策である。

 Blowfishは,通常この後で「o=c」(Contact:コンタクト)と「o=d」(Data:データ)というクエリーをやり取りする。Contactクエリーはデータ部を持たず,クライアントIDしか入っていない。つまり,ゲートウエイ・サーバーに「クライアントは機能中。命令を送れ」と伝えるためだけのクエリーである。Contactクエリーを受け取ったゲートウエイ・サーバーは,クライアントに実行させようとしている処理の識別用ID(4バイト長)と命令コードを返す。