新型 PlugX の出現

UAC ダイアログの出現を抑制するコード

11月18日に IIR vol.21 がリリースされました。その中で PlugX という RAT について記述しています。PlugX は PoisonIvy と同様に標的型攻撃で頻繁に利用が確認されており、一部の攻撃者グループに至ってはその両方を併用して攻撃を行う事実が判明(IIR の同号の記事、1.4.2 連続する標的型メール攻撃を参照のこと)したことから、IIJ ではこの RAT に着目する必要があると考え、調査を継続してきました。その結果、大幅に特徴が変化した検体を発見しました。この記事では IIR 内で記述した検体(以下旧検体)と異なる特徴を持ち、IIR の原稿執筆前後に新たに出現し始めた新型 PlugX (以下新検体)について、IIR の号外として公開します。本稿にあわせて IIR Vol.21 の『1.4.1 標的型攻撃で利用される RAT「PlugX」』をご参照下さい。

新検体 亜種1

新検体 亜種1(以下亜種1)は10月下旬より観測され始めています。同じ RAT である PoisonIvy などと比べてコード量が多いため、全てを詳細に解析できたわけではありませんが、以前までの検体と比べ、少なくとも以下の変更点が存在します。特にこの亜種は大幅に難読化機能が強化されており、コード差分解析ツールを使って旧検体と比較したところ、14%しか一致していないことがわかっています。

また、Kaspersky Lab 社のブログ[1]The rush for CVE-2013-3906 – a hot commodity … Continue readingで11月15日(現地時間11月14日)に報告された検体もこのタイプと同一でした。

変更点

  • デバッグメッセージ出力の抑制
  • PlugX ヘッダを削除し、グローバル変数に移動
  • 通信や設定領域の難読化ルーチンの変更
  • 独自に追加される HTTP ヘッダの文字列や URL の変化
  • bootProc などの処理名が略称に変化
  • 大量の Windows API wrapper 関数追加
  • 重要な文字列の難読化
  • PlugX 本体の DLL ファイルを難読化
  • フォルダパスや mutex 名のユニーク化(Volume Serial Number をベースに xor でエンコード)
  • 設定領域の拡張
  • IE にインジェクションし、Proxy の認証情報を自動的に入手する仕組み
  • ネットワーク盗聴機能
  • 画面キャプチャ機能の強化
  • TCP/UDP ポートの Listen

変更点の補足

ここからは、亜種1についての変更点をピックアップして詳細に見ていきます。

デバッグメッセージ出力の抑制

PlugX は今でも頻繁に開発が行われているためか、長期間に渡ってデバッグメッセージの出力が有効になっていました。これは開発者フレンドリであると同時に解析者フレンドリでもあります。旧検体もこの特徴は存在したままであることから、発見されてから一年以上この機能が有効になっていたことがわかります。しかし、新検体ではこの機能が取り除かれました。PlugX の機能が成熟したため、新規拡張よりも検出させないことを主眼に置いた変更が行われ始めた可能性が高いですが、一部の検体ではすでに2012年の段階でデバッグメッセージの出力が無効化された検体が存在[2]Kaspersky Lab 社の blog では、PlugX is becoming mature … Continue readingしていたことから、どれが真実であるかはまだ推測の域をでない状況です。

PlugX ヘッダを削除し、グローバル変数に移動

“GULP” という “PLUG” を反対にした文字列が PlugX の特徴の一つであると IIR 内で述べ、発見方法の一つとして記載しました。しかし今回の PlugX ペイロード先頭には “GULP” という文字列ばかりか、PlugX ヘッダ自体が存在しません(PlugX ヘッダに相当する先頭の4096バイトはすべて NULL バイトになっている)。”GULP” 以外のテーブル要素は PlugX ペイロード内にグローバル変数として配置されています。

ヘッダの差異

上図は左が旧検体、右が新検体の同一テーブルを表示しています。左は領域の先頭であるのに対し、右は領域の途中に配備されており、”GULP” も存在していません。また、下図は新検体の先頭領域を表示したものです。ヘッダーが全て空になっているのが見てとれます。

新ヘッダ

通信や設定領域の難読化ルーチンの変更

旧検体は複数の研究者によって通信や設定領域および PlugX 本体を難読化するためのルーチンが公開されていました。しかし、今回の検体はそのルーチンがまったく異なるものに入れ替えられています。次の図は、それぞれ新旧検体の通信の難読化を行うルーチンを比較したものです(上が旧検体、下が新検体)。

旧難読化ルーチン
新難読化ルーチン

独自に追加される HTTP ヘッダの文字列や URL の変化

独自に追加される HTTP ヘッダの文字列や URL の変化ヘッダ名、URL のパス部ともに元の特徴からは大きく変化しています。次の画像は上が旧検体、下が新検体の HTTP による通信です。追加されるヘッダや URL のパス部が変化していることが分かります。

旧 HTTP ヘッダ
新 HTTP ヘッダ

bootProc などの処理名が略称に変化

旧検体には “bootProc” や “DoImpUserProc” など、Thread 生成時に渡される構造体の一部にわかりやすい処理名がつけられていましたが、これらも “BP” や “DIUP” などの略称に変更され、よりわかりにくくなっています。

大量の Windows API wrapper 関数追加

新検体ではほとんどの Windows API 呼び出しが直接 API を呼び出すのではなく、API の名前解決を行った後に呼び出す Wrapper 関数に置き換えられており、コードの差分解析を行った際のコードの一致率が低下する一因となっています。

重要な文字列の難読化

新検体には新たに文字列を難読化するルーチンが加えられています。全ての文字列ではありませんが、マルウェアの特徴となりそうな文字列はほとんど難読化されており、それによって隠蔽されている文字列の数は200を越えます。このような機能は ZeuS や SpyEye などを始めとした多くのマルウェアに搭載されている機能であり、目新しいものではありませんが特徴を隠す上では非常に有用であるため、この RAT の開発者も利用しているものと思われます。以下は難読化されていた文字列の一例です。

  • 特権を示す文字列
    • SeDebugPrivilege
    • SeTcbPrivilege
  • KeyLogger 用の文字列
    • Pause
    • Enter
    • Cls
    • Tab
    • Back
    • Esc
    • Home
    • End
    • PageDn
    • PageUp
    • Left
    • Up
  • IE にインジェクションした際に hook する API
    • HttpSendRequestA
    • HttpSendRequestW
    • HttpSendRequestExA
    • HttpSendRequestExW

PlugX 本体の DLL ファイルを難読化

旧検体は PlugX 本体が一時的にメモリ上に展開されていました(難読化やパックがされていない DLL)。しかし、今回はMZ及びPEヘッダのマジック値が “XV” に変更されています。また、”.text” や “.data” などのセクション名、”This program cannot be run in DOS mode.” といった、コンパイラが出力するお馴染みの文字列は全て消されており、一時的にメモリ上にしか出現しない上に、一見すると PE ファイルにも見えないため、発見するのを困難にしています。以下は旧検体と新検体の PlugX 本体のバイト列を比較したものです。

旧 PE
新 PE

設定領域の拡張

旧検体の設定領域のサイズは 0x150c (5388バイト) や 0x1d18 (7448バイト) などでしたが、新検体は 0x2540 (9536バイト) と、大幅に増加しています。これは主に以下のような領域が追加されたことに起因しています。

  • 一部の通信で送受信が正常に行えたことを示すためのマーカーとして利用される文字列
  • 画面キャプチャ関連の設定(保存先フォルダや保管期限など)
  • 最初にコードインジェクションを行う対象(デフォルトは svchost.exe)のパス名を格納する領域が4箇所に増加

IE にインジェクションし、Proxy の認証情報を自動的に入手する仕組み

新検体はユーザが IE を起動する度に、その Window に対しても PlugX ペイロードをコードインジェクションするようになっています。その際、以下4つの API にフックをかけ、Proxy の設定や Proxy のユーザ名、パスワードを盗み出し、”Proxy-Auth” ヘッダとして HTTP リクエストに追加して C&C サーバに通知するとともに、その認証情報を利用して Proxy 経由で C&C と通信ができるように “Proxy-Authorization” ヘッダを追加します。その結果、認証付きの Proxy が備えられたネットワーク環境であっても、PlugX は自動的にその Proxy を越えて通信ができるようになります。

  • HttpSendRequestA
  • HttpSendRequestW
  • HttpSendRequestExA
  • HttpSendRequestExW

ネットワーク盗聴機能

IE 以外のブラウザから認証付き HTTP Proxy の設定を盗み出すため、この検体はプロミスキャスモードになって通信の盗聴を行います。その処理で HTTP の通信を監視し、Proxy の設定や “Proxy-Authorization: basic” に続く文字列(ユーザ名とパスワードが base64 エンコードされている文字列)をデコードして、ユーザ名やパスワードを取得し、それを PlugX の設定に追加します。これによって IE 以外のブラウザであっても HTTP Proxy の Basic 認証を使用して C&C サーバと通信を行うことができます。この機能以外にも、全パケットをキャプチャするための機能も含まれていました。

画面キャプチャ機能の強化

以前までの画面キャプチャ機能は、攻撃者がトリガしたときだけ画面キャプチャを取得する機能のように見え、定期的にファイル化するようなことはありませんでした。しかしこの亜種は攻撃者が画面キャプチャ機能を有効にすると、マウスのクリックやキーボードなどのイベントと連動するなどして、設定で指定された期間、jpeg ファイルとして指定されたフォルダに保存を行います。

新画面キャプチャ機能

新検体 亜種2

新検体 亜種2(以下亜種2)は9月下旬以降に出現し始めています。IIJ ではまだ入手したばかりで解析中の段階ですが、以下のような変更点が存在します。

変更点

  • コードやデータがパッカーでパックされておらず(PlugX Loader が存在しない)、難読化のみ
  • 実行すると自己書き換えし、exe を DLL に変化させてからインストール
  • 2012年8月20日以降でしか動作しない
  • 亜種1とは異なるパターンの文字列の難読化と可読化した文字列の使用後の消去
  • 大量のジャンクコード挿入によるコードの難読化
  • 設定領域の難読化ルーチンの変更
  • 設定領域のサイズが shrink (0x76c、1900バイト) し、一部はグローバル変数に配置される
  • PlugX ヘッダが存在せず、付随するテーブルも完全に消去
  • 複数の C&C からのコマンド処理ルーチンが追加

変更点の補足

亜種2についての変更点を補足します。

亜種1とは異なるパターンの文字列の難読化と可読化した文字列の使用後の消去

亜種2も亜種1と同様、ほとんどの文字列が難読化されていますが、亜種2の場合、以下の図のように、文字列の難読化を解除してその文字列を使用した後に、それを消去する仕組みが備わっています。これにより、感染有無を判断する為にマシンのメモリをダンプして PlugX の特徴的な文字列を検索したとしても、見つけることができなくなります。

難読化

大量のジャンクコード挿入によるコードの難読化

亜種2のコードには大量のジャンクコードが挿入されており、解析をより困難にしています。たとえば以下のルーチンでは、一見意味のある計算をしている命令がありますが、実際にはその結果は使われません。

ジャンクコード挿入

検出方法

新検体 亜種1

独自に追加される HTTP ヘッダは、ヘッダ名こそ変更されているものの、旧検体と比較して値に変化はありませんでした。1つ目は常に0、2つ目は0, 1, 2, 4のいずれかの値を取ります。3つ目は通信時の受信用バッファの値であり、コード内に即値としてハードコーディングされており、特徴的であるため、これも手がかりになります。4つ目は管理者権限が取得できたかを示すためのフラグであり、0か1のみしか入らないなど、値を限定できるため、通常ブラウザが使う以外のヘッダ文字列かつ、この数字の並びが見えた場合はアラートをあげるように IDS や IPS などのカスタムシグネチャを記述することで検出することが可能です。また、通信方式が POST かつ URL のパス部が24桁の16進数であることも特徴の1つです。

旧亜種 HTTP ヘッダ
新亜種 HTTP ヘッダ

新検体 亜種2

HTTP の通信は旧検体と同一であるため、IIR で示したヘッダ名での検出が可能です。万が一ヘッダの文字列が修正されたとしても、値はそのままの可能性が高いため、亜種1で示したようなルールを記述することで、IDS や IPS で検出することができるでしょう。また、ダンプしたメモリから検出したい場合には、先ほど述べたとおりこちらの亜種は可読化した文字列をすぐに消去するため、コードのバイナリパターンや特徴的な即値を組み合わせて定義するのが有効です。たとえば、UAC ダイアログの出現を抑制するコードは、旧検体・亜種1・亜種2で共通して使われているため、該当する部分のコードのバイナリパターンや、そこで使われる CLSID/IID 等は IOC[3]ここでの IOC とは広義の意味での “Indicator Of Compromise” として使っており、特定の仕様や製品を指すものではない。 の indicator (検出条件の一要素) として使えるでしょう。

UAC ダイアログの出現を抑制するコード

雑感

今回は PlugX の進化について、解析結果を交えてお伝えしました。この様な亜種が次々に出現している状況から、今も頻繁に更新がされ続けており、攻撃者が新たな機能の追加とともに、特に特徴の隠蔽に力を入れているのが2つ新検体から見てとれます。

また調査の結果から、開発者から攻撃者に PlugX のパッケージを配布する際、ソースコードを同梱し、攻撃者がソースコードを修正してリビルドできるようになっている可能性が高いと判断できます。このことから、特徴的な文字列や値を利用した検出は難しくなっており、今回提示した検出方法も迂回される可能性があるため、今後も注意して調査を継続する必要があります。

現状では同時期に新旧検体が出現しています[4]亜種1が出現する2日前にも IIJ では旧検体と同一の特徴を持つ PlugX … Continue reading。どの検体も攻撃に使われる可能性があるため、柔軟に対応できるようにしておくことが重要です。

脚注

脚注
1 The rush for CVE-2013-3906 – a hot commodity で紹介されている検体を入手し、調査したところ、すでに発見していた同検体と同様の特徴を持つことが判明した。
2 Kaspersky Lab 社の blog では、PlugX is becoming mature で、すでに2012年11月の段階でデバッグメッセージ出力が抑制された検体が存在することを報告している。
3 ここでの IOC とは広義の意味での “Indicator Of Compromise” として使っており、特定の仕様や製品を指すものではない。
4 亜種1が出現する2日前にも IIJ では旧検体と同一の特徴を持つ PlugX を入手しており、亜種2に至っては出現後から数週間後に旧検体を使った攻撃者グループがいることを確認している。

シェアする