Cisco Japan Blog
Share

Graftor:望まないのにインストールされる迷惑ソフトウェア


2017年9月12日


執筆者:Holger Unterbrinkpopup_icon および Matthew Molyettpopup_icon

概要

インターネットのメリットの 1 つはフリーウェアです。それらは大規模なフリーウェア配布サイトから多くダウンロードされており、(これまでは利用できなかった機能を)ユーザに提供しています。そのため、別のソフトウェアがバンドルされている場合でも、無料であるが故にライセンス規約でそれについての言及を見過ごしてしまうことが多くあります。
Graftor(「LoadMoney」とも呼ばれる)は、フリーウェアにバンドルされていることが多い不必要なアドウェアの Dropper です。Talos では、この Dropper がシステムに及ぼす影響を調査することにしました。サンドボックス上で実行させて解析したところ、Graftor および Graftor によってダウンロードされる関連ファイルは、次のような挙動を示すことが判明しました。

  • ユーザのブラウザを支配し、バナー広告を挿入する
  • ru などのパートナーから、別の迷惑アプリケーションをダウンロードしてインストールする
  • これらのプログラムをユーザに通知せずインストールする
  • Web ページのテキストを勝手にリンクへと変える
  • デスクトップとブラウザにクイック起動リンクを追加する
  • ブラウザのホームページを変更する
  • ユーザの検索プロバイダーを変更する
  • パートナーのアドウェアを実行し、ソーシャル エンジニアリングの手口により他のソフトウェアをインストールするよう仕向ける
  • アンチウイルスがインストールされているか確認する
  • サンドボックス環境の有無をチェックする
  • 解析対策
  • サンドボックス環境をオーバーフローさせるための不要な API 呼び出し
  • システム証明書の作成/変更

機能

アドウェアが最初に行う動作の 1 つは、デスクトップに追加のソフトウェアをインストールし、サード パーティの Web サイトを参照するようにブラウザの設定を変更することです(図 1)。

図 1

キャンペーンで使用される CnC ドメインについて Cisco Umbrella の DNS データを確認したところ、キャンペーンの期間がわずか数日であったにも関わらず、多数の人々が影響を受けたことが判明しました(図 2a)。図 2b と図 2c は、サンドボックスの実行中に Graftor がインストールした 2 つの関連アプリケーションのドメインを示しています。このうち多くのユーザは、これらの関連アプリケーションを意図せずインストールしたと考えられます。

Regularfood [..]gdn(コマンド アンド コントロール サーバのドメイン)

図 2a

Graftor によってインストールされる関連プログラム

図 2b

図 2c

技術的な詳細

元々の Graftor の Dropper(2263387661.exe)を実行すると、数分後にソフトウェアがダウンロードされ、一連の実行ファイルが追加でインストールされます。その結果、次のようなプロセス ツリーが生成されます(図 3)。

図 3

Graftor の Dropper とダウンローダ(2263387661.exe)を解析すると、何重にも難読化されていることがわかりました。まず、最初の段階(実行ファイルの解凍時)で複雑な難読化が施されています。ただし解凍アルゴリズムは、後のセクションで説明するように、幾分シンプルです。

このアルゴリズムは、WinMain 関数をいくつかのサブ関数に分散することで、難読化されています。図 4 は、WinMain 関数の複雑さを IDA で示したものです。関数を構成する複数のブロックがサブ関数と複雑に組み合わされており、解析を相当難しくしています。

図 4

まず、新しいバッファを割り当てます(図 5 の 00401395)。

図 5

次に、WinMain 関数内で、00416B6A のバイト列を別のサブ関数でデコードします(下の図 9 参照)。例として、図 6 の loc_4013EC をご覧ください。
このコードでは、関数をアドレス値で呼び出すのではなく、レジスタや変数に格納された値で呼び出しています。たとえば、図 5 の 00401395 では、call ebx の命令の結果、VirtualAlloc が呼び出されます。これでは、コードを静的に解析することが困難です。図 5 の 00401395 の例は、詳細にコードを解析せずに call の呼び出し先を識別するのは困難です。

図 6

デコードされたバイトは、最後に関数に引き渡されます(図 7 write_unpkd_bytes2buf)。この関数により、デコードされたバイト列がバッファに書き込まれます。これは、図 5 の 00401395 で割り当てられていたバッファで、すべてのバイト列がデコードされるまで、このデコードのループが繰り返されるのです。

図 7

図 8 に、write_unpkd_bytes2buf 関数の中身を示します。

図 8

こうした複雑な難読化にも関わらず、解凍アルゴリズム自体は非常にシンプルで、次のような擬似コードに置き換えることができます(図 9 のコメント参照)。

図 9

この 1 段階の解凍処理により、コードがメモリに展開されます。解凍が完了すると、call ecx を通じて、解凍の 2 段階が実行されます(図 10 参照)。

図 10

第 2 段階ではランダムなアドレス空間が使用されます。つまり、OS によってランダムに選択されたアドレス空間に読み込まれます。図 5 で説明した VirtualAlloc 関数は、LPVOID lpAddressNULL に指定した状態で呼び出されます。メモリの割り当て領域がシステムによって決定されることになります。第 2 段階ではコードがスパゲッティ コードと化しており、第 1 段階よりも難読化が進んでいます。第 2 段階の主な役割は、インポート アドレス テーブル(IATを再構築し、特定のライブラリ関数のアドレスを変換することです(図 11)。元の PE ファイルの内容を書き換える役割もあります。

図 11

関数のアドレスを別のローカル変数に格納し、引数として、複数のセットアップ関数に渡されます。たとえば、読み込み/書き込み/ファイル実行のため、メモリ領域 0x400000 ~ 0x59C000 が変更されます(図 12 参照)。つまり、読み込み/書き込み/ファイル実行のため、元の PE ファイルの .text、.rdata、.data、.rsrc セクションの全体が変更されるのです。これにより、それらの領域に格納されたコードを Dropper から修正/実行可能になります。先述したように、難読化により静的解析を防ぐため、ほとんどの呼び出しがレジスタや変数を介して行われます(図 12)。

図 12

次のステップの 002A14F6 では、01DC0000 にバッファを割り当てています。

図 13

このバッファには、元の圧縮 PE ファイルの 0042d049 にあったバイト列がコピーされます。

図 14

図 15

このデータは、エンコードされた PE ファイルです。バイト列がメモリにコピーされた後、デコードされ、01DC0000(図 16b)のバッファ(図 16a)に再度書き込まれます。

図 16a

図 16b

この段階は、アンチ デバッグ手口で保護されています。実行コードは、次のように GetTickCount を 2 回呼び出して、呼び出し間隔を計測します。一定時間を過ぎると、コードの実行を中止します。

図 17a

図 17b

メモリ内で他のライブラリ関数のアドレスを解決し、PE ファイルの IAT を再構築すると、258 ミリ秒スリープした後に 004897D3 へ戻り、 3 段階を呼び出します。

図 18

これまで説明した第 2 段階の解凍処理では、URL もデコードされます。この URL は後でコマンド アンド コントロール サーバに接続する際に使用されます。サーバに接続する際は、たとえば 002B0000 などにバッファを割り当てます(図 19a)。そして、004020c0 にある元のサンプルから暗号化 URL を読み込んでデコードし、割り当てられたバッファ(この場合、002B0000)に再び格納します(図 19b)。

図 19a

 図 19b

第 3 段階(上記参照)は、Visual Studio でコンパイルされる C++ の実行ファイルです。グローバルにオブジェクトを初期化することで、C ランタイムの初期化中に、WinMain エントリ ポイントの前でカスタム クラスを実行できます。こうしたコード構成は分析対策として機能し、WinMain から始まる解析に対して痕跡を隠蔽します。その後、関連するコードが使用されても、メモリのリダイレクトと隠蔽用の関数呼び出しによって、実行の内容は覆い隠されてしまいます。
以下に示すのは、PE ファイルの rdata セグメントに格納されているコールバック関数のアドレス(図 20)と、初期化関数 InitCallbacks です(図21 および図 23)。

図 20

図 21

WinMain 以前に行われる C ランタイム ライブラリ(CRT)の初期化では、コールバック関数のリストが、名前付き文字列(「OS」など)に関連付けられた内容で生成されます。この文字列は後に、CnC トラフィックやシステム情報を収集する複数のコールバック関数で使用されます。たとえば、CnC トラフィックに見られる「systemFS」の文字列は、Graftor_CollectSystemVolumeInformation 関数の呼び出しにつながります。また、「OS」の文字列は、Graftor_CollectWindowsInformation の呼び出しをトリガーします。
図 22 には、このような関数呼び出しの例に加えて、先述したアセンブラ コードと同様の動作を表す疑似コードも示します。

図 22

生成されたリストは、グローバルなアドレス位置に紐付けされており、後で再度ローカルの変数に結び付けられます。

図 23

このようなリダイレクトの仕組みは、ソース コード上ではごく一部ですが、実行すると連鎖的なメモリ アクセスが生じ、オブジェクトの参照が不明瞭になります。

図 24

続いて、文字列が渡されてコールバックが参照され、それが間接的に呼び出されます(図 25)。

図 25

単純な wchar_t 配列を使わずに、std::basic_string<wchar_t> とすることにより、文字列が処理されるたびに関数が 2 つ呼び出され、間接的な処理が追加されます。分析時に目にするのは、1 つの関数に渡される広範囲の文字列ではなく、一連の 3 つの関数です。徹底的にマークアップするか、デバッガから確認しない限り、これらはランダムな関数の呼び出しやメモリ操作の集合に見えます。また、std ライブラリが(動的にリンクされているのではなく)内包されているため DLL の呼び出しをヒントにできないことも、判別をより難しくしています。
さらに、この第 3 段階は、別のアンチ デバッグ手法により保護されています。図 26 および図 27 でわかるように、サンプルでは、FirstChanceExceptions(C0000005)に VectoredExceptionHandler が登録されています。

図 26

図 27

コードのセクションは PAGE_NOACCESS としてマークしています。

図 28a

図 28b

つまり、このセクションの命令が 1 つ実行されるたびに、例外がトリガーされることになります。アクセス権限が PAGE_NOACCESS となっているメモリ位置では例外が発生しますが、この例外を扱うハンドラ関数(上記図 27 参照)は、その権限を PAGE_EXECUTE_READWRITE で上書きします。その結果、実行可能となります。次に、例外ハンドラ関数が最初の命令に戻り、そこで実行可能となりますが、次の命令には PAGE_NOACCESS で保護がかかっているため再び例外が発生します。デバッガを動作させている場合、命令のたびにデバッグのセッションが中断されるのです。例外がそのまま実行ファイルに返される場合でも、実行速度が極端に遅くなります。
004BB3FA から、CnC サーバへのインターネット リクエストの準備が開始され、GET リクエストを実行するために収集された情報が暗号化されます(図 29a、b、c)。

図 29a

図 29b

図 29c

Talos では、CnC サーバに送信される GET リクエストの復号に成功しました。デコードされたコンテンツは JSON ファイルで構成されており、こちらpopup_iconからダウンロードできます。

この実行ファイルは、次の情報を C2 サーバに送信します。

MACSIDHD のシリアル番号、ユーザ名、GUID、ホスト名、HD サイズ、HD デバイス名、ファイル システム、OS バージョン、ブラウザ バージョン、DotNET バージョン、ビデオ ドライバ、言語設定、メモリ、システム BIOS のバージョン、ドメイン名、コンピュータ名、プロセッサ関連の複数のパラメータ、プロセッサの数、他にインストールされているアドウェア/迷惑プログラム、実行中プロセス、キーボード設定、スパイウェア対策ソフト、ファイアウォール、ウイルス対策ソフト、など

これらに対し、サーバは暗号化された設定ファイルを返します。このファイルは次の図のように処理されます。

図 30

GET リクエストを復号する際に使用したアルゴリズムが、CnC サーバの応答を復号する際にも使用されます。その結果、パケットの先頭バイトをシード値に設定した非常にシンプルなストリームが生成され、データ部分と合わせて XOR がとられます。暗号の中身は、単純な gzip ストリームです。
復号化したファイルの全体は、こちらpopup_iconからダウンロードできます。このファイルには、Graftor のダウンローダによってパートナーや顧客のもとにインストールされていると思われるアドウェアや迷惑プログラムが含まれています。図 31 に例を示します。

図 31

「l」のキーにみられる最初の URL が、パートナーの実行ファイルのダウンロードとインストールに使用されます。「a」のキーは、そのコマンド ライン パラメータとして使用されます。すべてのキーの正確な意味はまだ把握できていませんが、それらは、非常に大きな JSON ライブラリにパラメータとして渡されます。また、このライブラリは静的にバイナリへコンパイルされます。JSON ライブラリのほか、静的にコンパイルされた SQLite ライブラリも発見されました。この SQLite ライブラリが実行ファイルでどのように使用されるのかについては、まだ完全に分析できていません。しかし、Graftor を検出して停止させるだけの十分な情報はすでに得られています。
現時点で明らかになっている情報から、このソフトウェアがいかに精巧なものであるかがわかります。デコードされた 2 つのファイルに示されているデータからは、Graftor の機能と感染対象への影響とを知る上で有力な情報が得られます。
Graftor、および Graftor によりダウンロードされるアプリケーションは、ウイルス対策製品を入念にチェックしています。また、サンドボックス環境の検出にも余念がありません。これらは、マルウェアで一般的に観察される手口と酷似しています。

図 32a

図 32b

図 32c

図 32d

図 32e

このソフトウェアは、次の図に示すように、余分な API 呼び出しを数多く発生させます(図 33)。これには、サンドボックスでの解析を妨害する効果があります。

図 33

まとめ

Graftor は、迷惑ソフトウェア ダウンローダの中でも特に悪評があります。フリーウェアのインストーラに Graftor がバンドルされていてもユーザに通知されないため、気付かない危険性があります。
Graftor が実行されると、ユーザや端末の識別可能な情報が大量に抽出され、迷惑アプリケーションが追加でインストールされます。ダウンローダは、ローカル マシンの管理者権限を要求します。このアクセス権限を得れば、ダウンローダはマシン上で自由に動作できるのです。
エンドポイント向け AMP や、ネットワーク デバイス上の AMP などのソリューションを使用すれば、Graftor のようなソフトウェアや、それによってダウンロードされた付随パッケージがデバイスにインストールされたときに、管理者がそれを把握できます。同様に、ネットワーク ベースの検出により CnC の活動を識別してブロックすることもできます(Snort SID 44214)。Graftor のインストーラのダウンロードを防ぐため、フリーウェア Web サイトへのアクセスをブロックするという手段もあります。しかし、Graftor がバンドルされていないフリーウェアも多く、それらは大いにユーザの役に立っている可能性があります。つまるところ、ソフトウェアが無料で手に入る場合は、自分自身が「売り物」になっている可能性もあることを念頭に置いてください。フリーウェアを使用するなら、インストール前に必ず使用許諾契約を綿密に確認するべきです。確認するのは面倒ですが、この手のソフトウェアを削除するには、おそらくもっと面倒な作業が必要になるのです。

カバレッジ

お客様がこの脅威を検出してブロックできる別の方法を以下に記載します。

Advanced Malware Protection(AMP)は、これらの攻撃者によるマルウェアの実行の阻止に最適です。

CWS や WSA の Web スキャンは、悪意のある Web サイトへのアクセスを阻止し、それらの攻撃に使用されるマルウェアを検出します。

E メール セキュリティpopup_icon は、攻撃の一環として攻撃者が送りつける不正な電子メールをブロックします。

IPS のネットワーク セキュリティ保護や NGFW には、攻撃者による不正なネットワーク アクティビティを検出できる最新のシグネチャが備わっています。

AMP Threat Grid は、悪意のあるバイナリを特定し、すべてのシスコ セキュリティ製品に保護機能を組み込みます。

シスコのセキュア インターネット ゲートウェイ(SIG)である Umbrellapopup_icon は、社内ネットワークの内外で悪意のあるドメイン、IP、URL への接続をブロックします。

IOC

代替データ ストリーム(ADS):
C:\Users\dex\AppData\Local\Temp\2263387661.exe:Zone.Identifier
C:\Users\dex\AppData\Local\Temp\QBPO5ppcuhJG.exe:tmp
C:\Users\dex\AppData\Local\Temp\2263387661.exe:tmp
C:\Users\dex\AppData\Local\Temp\AyWdp7tHPIeU.exe:tmp
C:\Windows\System32\regsvr32.exe:Zone.Identifier

ハッシュ
2263387661.exe(Graftor のDropper)
9b9ce661a764d84a4636812e1dfcb03b (MD5)
Fd3ccf65eab21a77d2e440bd23c59d52e96a03a4 (SHA1)
41474cd23ff0a861625ec1304f882891826829ed26ed1662aae2e7ebbe3605f2 (SHA256)

第 2 段階のダンプ ファイル:
40bde09fc059f205f67b181c34de666b (MD5)
99c7627708c4ab1fca3222738c573e7376ab4070 (SHA1)
Eefdbe891e35390b84181eabe0ace6e202f5b2a050e800fb8e82327d5e57336d (SHA256)

第 3 段階のダンプ ファイル:
1e9f40e70ed3ab0ca9a52c216f807eff (MD5)
7c4cd0ff0e004a62c9ab7f8bd991094226eca842 (SHA1)
5eb2333956bebb81da365a26e56fea874797fa003107f95cda21273045d98385 (SHA256)

URL
コマンド アンド コントロール サーバの GET リクエスト:hxxp://kskmasdqsjuzom[.]regularfood[.]gdn/J/ZGF0YV9maWxlcz0yMyZ0eXBlPXN0YXRpYyZuYW1lPVRlbXAlNUMyMjYzMzg3NjYxLmV4ZSZybmQ9ZTY5NjM5ZjJjYTdlNWNiNDU2ZmYwMDUyN2M2ODBlNDMxMTY0YmFhZGJlZWI3MTI5YjIwZGYzM2M3YzIzNTc1YQ…

Set-Cookie:GSID=3746aecf3b94384b9de720158c4e7d88; expires=Sat, 12-Aug-2017 15

コマンド アンド コントロール サーバの POST リクエスト:
hxxp://kskmasdqsjuzom[.]regularfood[.]gdn/J/ZGF0YV9maWxlcz0yMyZ0eXBlPXN0YXRpYyZuYW1lPVRlbXAlNUMyMjYzMzg3NjYxLmV4ZSZybmQ9ZTY5NjM5ZjJjYTdlNWNiNDU2ZmYwMDUyN2M2ODBlNDMxMTY0YmFhZGJlZWI3MTI5YjIwZGYzM2M3YzIzNTc1YSZkZWxheT0zODk…

Set-Cookie:GSID=3746aecf3b94384b9de720158c4e7d88; expires=Sat, 12-Aug-2017 15

サンドボックスでの実行時のドメイン:
arolina[.]torchpound[.]gdn
binupdate[.]mail[.]ru
crl[.]microsoft[.]com
dreple[.]com
gambling577[.]xyz
jvusdtufhlreari[.]twiceprint[.]gdn
kskmasdqsjuzom[.]regularfood[.]gdn
mentalaware[.]gdn
mrds[.]mail[.]ru
nottotrack[.]com
plugpackdownload[.]net
s2[.]symcb[.]com
sputnikmailru[.]cdnmail[.]ru
ss[.]symcd[.]com
xml[.]binupdate[.]mail[.]ru

Snort ルール
SID 44214

 

本稿は 2017年9月5日に Talos Grouppopup_icon のブログに投稿された「Graftor – But I Never Asked for This…popup_icon」の抄訳です。

 

コメントを書く