エグゼクティブ サマリー
ドメイン ネーム システム(DNS)は、企業ネットワークで最もよく使用されているインターネット アプリケーション プロトコルの 1 つとして挙げられます。DNS の役割は、ユーザが IP アドレスを記憶しなくても目的のネットワーク リソースにアクセスできるよう、名前解決を行うことです。多くの組織では、Web トラフィックやファイアウォール ルールなどに関連する出力に対しては厳格なフィルタリングを実装している一方、DNS ベースの脅威に対して取っている保護対策はそれほど厳重ではありません。攻撃者はこの点を踏まえ、セキュリティ デバイスを回避する常套手段として、DNS 内に別のネットワーク プロトコルをカプセル化するという方法を使っています。
通常、このように DNS を利用する場合、その最終目的は情報を引き出すことにあります。Talos で最近分析した興味深いマルウェア サンプルのうちの 1 つに、DNS TXT レコードのクエリと応答を利用して双方向のコマンド & コントロール(C2)チャネルを作り出すというものがあります。これにより、攻撃者は DNS 通信を使って、新しいコマンドを感染したマシンに送信し、その実行結果を取得することが可能になります。この方法は極めてまれで、RAT を管理する際に簡単に捉えることができません。攻撃者にとって検出を免れる重要な手段となるのは、ファイルを一切使用せずに段階的に PowerShell を使用するというものです。
皮肉なことに、組織を DNS や Web をベースとした脅威から守るための製品として特別に設計した Cisco Umbrella をリリースした直後に、マルウェアの作成者はマルウェア コード自体の中で SourceFire の名前を出しました(Cisco Umbrella については、こちらをご覧ください。
詳細
私たちがこの特定のマルウェア サンプルに興味を持った最初のきっかけは、セキュリティ研究者が Twitter で公開したツイートで(simpo に感謝します!)、base64 でエンコードされた文字列「SourceFireSux」が含まれる PowerShell スクリプトについてのものでした。大変興味深いことに、PowerShell スクリプトで直接参照されていたセキュリティ ベンダーは Sourcefire だけでした。私たちは、ツイートで言及されていた base64 でエンコードされた値「UwBvAHUAcgBjAGUARgBpAHIAZQBTAHUAeAA=」を検索した結果、一般公開されているマルウェア分析サンドボックス Hybrid Analysis にアップロードされたサンプルを見つけることができました。さらに、復号された文字列値を検索すると、検索エンジンから唯一の検索結果として、Pastebin のページが返されました。Pastebin にリストされていたハッシュを手掛かりに辿り着いたのが、同じく公開サンドボックスにアップロードされていた悪意のある Word ドキュメントです。この Word ドキュメントが開始する感染プロセスは、Hybrid Analysis でレポートされていたファイルと同じマルチステージの感染プロセスであったため、私たちはさらに具体的な感染プロセスを再現することができました。テレメトリ データを分析した結果、他にもサンプルが特定できました。これらのサンプルは、この投稿の「侵害の兆候」セクションにリストされています。
マルウェアの作成者たちがマルウェアの中で具体的に私たちを名指しするようになったということは、私たちがセキュリティ ベンダーとして正しい対策を取っているということに他なりません。私たちは当然、この特定のサンプルを詳しく調査することにしました。
今回の事例では、まず、公開サンドボックスに VBScript ファイルとして誤って送信された PowerShell ファイル(ここでは、このファイルを「Stage 3」と呼びます)を分析するところから始めました。この分析によって判明したのは、図 1 に示す難読化解除された PowerShell に示されているように、前述の文字列がミューテックスとして使用されていることです。
図 1:ミューテックスの作成
ステージ 1:悪意のある Word ドキュメント
前述したように、私たちがこの感染チェーンの感染源として突き止めたのは、悪意のある Microsoft Word ドキュメントです。この Word ドキュメントはフィッシング電子メールを介して被害者に配信されます。興味深いことに、この Word ドキュメントは McAfee で保護されたセキュアな電子メール サービスに関連するドキュメントであるかのように見せていました。McAfee は有名なセキュリティ ベンダーであるため、被害者がこのファイルをそのまま信頼して開く可能性を高めるのに効果的な方法です。このドキュメントはユーザに対して、このドキュメント自身がセキュリティで保護されていると伝え、コンテンツを有効化するよう指示します。
図 2:悪意のある Word ドキュメント
このドキュメントは Document_Open() 関数を使用して別の VBA 関数を呼び出します。呼び出された関数は、PowerShell コマンドを定義して実行するコードを組み込んだ長い文字列を設定します。定義された PowerShell コマンドは、Windows 管理インターフェイス(WMI)の Win32_Process オブジェクトで Create メソッドを使用して実行されます。
コマンド ラインから PowerShell に渡されるコードの大部分は、Base64 でエンコードされて gzip によって圧縮されています。コード末尾のエンコードされていない部分によってコードが展開され、Invoke-Expression Powershell コマンドレット(IEX)に渡されて実行されます。これにより、コードは感染したシステムのファイルシステムに書き込まれることなく実行することができます。これは概して、世間に出回っている悪意のある Word ドキュメントとしてはかなり典型的なしくみですが、Pastebin からのダウンロードを参照する VBA ストリームが存在するにも関わらず、私たちが分析したサンプルはこのしくみを利用していないようでした。
さらに、この特定のサンプルに対する AV 検出率は極めて低い(6/54)一方、ClamAV では正常に検出できることも観測結果としてわかりました。
図 3:ウィルス合計結果
ステージ 2:PowerShell
ステージ 1 の Word ドキュメントから IEX に渡された PowerShell が実行された時点から、感染したシステム上でいくつかの興味深いアクティビティが開始されます。ステージ 1 で説明した PowerShell スクリプトの末尾にある関数は、ステージ 2 でのアクションに加え、ステージ 3 に関連する特性も定義します。ステージ 2 のコードは難読化されています。ステージ 3 で使用するメイン関数は、「logic」と呼ばれているため、このステージで使用するメイン関数を「pre_logic」と呼びます。
このステージで存在する「pre_logic」関数がサポートするスイッチは 2 つあります。1 つは、ターゲット システム上の感染プロセスの次のステージに向けてパーシスタンスを確立するかどうかを判断するために使用されます。パーシスタンスが選択されると、もう 1 つのスイッチが、ステージ 3 のコードをそのステージに移った時点で実行するかどうかを定義します。
図 4:難読化解除された「pre-logic」関数
以上の 2 つのスイッチに加え、「pre_logic」関数は 4 つのパラメータをサポートしています。これらのパラメータは感染プロセスの次のステージで「logic」関数に渡されるものです。これら 4 つのパラメータを使用して、感染プロセスの次のステージで DNS TXT レコード クエリを送信する際に使用するサブドメインが決定されます。
「pre_logic」関数は、PowerShell スクリプト自体に含まれる base64 でエンコードされた blob から PowerShell を抽出し、次のステージ(ステージ 3)で使用できるようにします。この関数はまた、感染の次のステージを実行する際に使用する関数呼び出しとパラメータを含め、後で使用されるコードもいくつか定義します。
「pre_logic」の呼び出し時にパーシスタンスを確立するオプションが選択された場合、この関数は感染したシステムをクエリすることで、パーシスタンスを確立する最善の方法を決定します。パーシスタンスを確立する方法が決まると、マルウェアはパーシスタンスを確立するために最もよく使用されているレジストリ パスをクエリします。クエリ対象のレジストリ パスは、マルウェアが動作しているユーザ アカウントのアクセス権限によって異なります。
システムに対する管理者アクセス権限が割り当てられたアカウントで動作している場合、スクリプトは以下のレジストリ パスをクエリして設定します。
- $reg_win_path: “HKLM:Software\Microsoft\Windows\CurrentVersion”
- $reg_run_path: “HKLM:Software\Microsoft\Windows\CurrentVersion\Run\”
一般ユーザ アカウントで動作している場合、スクリプトは以下のレジストリ パスをクエリして設定します。
- $reg_win_path: “HKCU:Software\Microsoft\Windows”
- $reg_run_path: “HKCU:Software\Microsoft\Windows\CurrentVersion\Run\”
図 5:レジストリ アクティビティ
スクリプトは次に、感染したシステム上で使用されている PowerShell のバージョンを判別します。感染したシステムが PowerShell 3.0 以降を使用している場合、復号されたステージ 3 のペイロードが、「%PROGRAMDATA%\Windows\」にある代替データ ストリーム(ADS)に「kernel32.dll」という名前で書き込まれます。
システムがそれより前のバージョンの PowerShell を実行している場合、ステージ 3 のペイロードはエンコードされた上で、前に $reg_win_path の代入によって指定されたレジストリ ロケーションに「kernel32」というキー名で書き込まれます。$reg_win_path のレジストリ ロケーションには、ステージ 3 のペイロードを展開および実行するためのコードも後から 「Part」というキー名で書き込まれます。
図 6:PS チェックとパーシスタンス
以上の処理が完了すると、スクリプトはマルウェアを実行しているユーザのアクセス レベルを再度チェックして判別します。マルウェアが管理者権限で実行されている場合は、「_eventFilter」、「CommandLineEventConsumer」、「_filtertoconsumerbinding」に対する WMI イベント サブスクリプションが感染したシステムから削除されます。その上で、マルウェアは独自の永続 WMI イベント サブスクリプションとして、「Win32_LogonSession」イベントにフィルタリングして「CommandLineEventConsumer」に関連付けたサブスクリプションを設定します。これが、感染したシステムが新しいログオン セッションを作成する度に、前に ADS に格納されたステージ 3 のペイロードを読み取って実行するために使用され、パーシスタンスの観点からすると、基本的にはレジストリ ベースの実行キーに相当する WMI と言えます。ステージ 3 のマルウェアはデフォルトで、30 分後に「onidle」を実行するように設定されます。ステージ 2 の開始時に、ステージ 3 の実行に関連付けられたスイッチが「pre_logic」関数に渡された場合、ステージ 3 のペイロードは直ちに実行されます。
図 7:パーシスタンスのしくみ
上記の図を見るとわかるように、マルウェアは感染したシステム上でスケジュールされたタスクも作成します。「kernel32」という名前のこのタスクは、ADS またはレジストリのいずれか(感染したシステム上で実行されている PowerShell のバージョンによる)に格納されているステージ 3 のペイロードに関連します。このキャンペーンに関連する他のサンプルを分析するなかで、サンプルによってスケジュールされるタスクが異なる場合があることも観測されました。
ステージ 3:PowerShell
この感染プロセスのステージ 2 で実行される、ステージ 3 の PowerShell の難読化に使用される主な手段は、難読化関数と変数名です(たとえば、$domains ではなく ${script:/==\/\/\/==\__/==} を使用します)。Base64 による文字列のエンコードもスクリプト全体にわたって行われています。難読化を解除すると、ハードコーディングされたドメイン名からなる大きな配列がスクリプトに含まれていて、この配列から 1 つのドメイン名がランダムに選択されて以降の DNS クエリに使用されることがわかりました。重要な点は、ステージ 3 とステージ 4 の PowerShell スクリプトにはドメインの配列が 2 つ含まれていることです。一方の配列は障害状態が発生した場合にだけに使用されるもので、サンプルはもう一方の配列を使用します。
図 8:ステージ 3 のドメイン リスト
PowerShell スクリプトに含まれる「logic」関数は、スクリプトに含まれる 2 番目の配列から C2 ドメインをランダムに選択し、そのドメインを使用して初期ルックアップを行います。DNS TXT レコードの最初の要求結果が空の場合、またはルックアップが失敗した場合は、「do_lookup」関数が呼び出されて、スクリプト内の最初の配列からランダムにドメインが選択されます。興味深いことに、「do_lookup」関数で使用するドメインは、アクティブな「www」または「mail」TXT レコードがないドメインのようでした。
スクリプトはサブドメインをドメインと組み合わせて、マルウェアによる初期 DNS TXT レコード クエリに使用します。マルウェアは初期 DNS TXT レコード クエリに対する応答に含まれる TXT レコードの内容を使用して、次に実行するアクションを決定します。たとえば、最初のサブドメインが「www」だとすると、「www」が含まれる TXT レコードでのクエリ応答が、スクリプトに感染プロセスの続行を指示します。実行される可能性のある他のアクションには、「アイドル」、「停止」があります。
図 9:ステージ 3 のコマンド処理
マルウェアは初期 DNS 応答を受信すると、次のサブドメイン「mail」で処理を繰り返します。マルウェアはこのドメインを別の DNS TXT レコード クエリで使用して、この感染プロセスと関連付けられたステージ 4 のペイロードを取得しようと試みます。この DNS 要求に対する応答により、第 4 ステージ マルウェアが送信されます。図 10 と図 11 に、TXT レコード内に含まれる応答を示します。ステージ 4 のペイロードのサイズにより、DNS はこのトランザクションに TCP を利用します。
図 10:ステージ 4 のペイロードが格納された応答
別の視点として、以下の図に Wireshark によるDNS プロトコルとパケット ペイロードの解析を示します。
図 11:別の視点でのステージ 4 のペイロード
この第 4 ステージに関連するコードは、浄化されてから Invoke-Expression Powershell コマンドレット(IEX)に渡され、第 3 ステージのコンテキスト内で実行されます。第 4 ステージのペイロードは自律的なものではなく、第 3 ステージの PowerShell スクリプトに含まれる復号関数に依存するため、単に 4 番目のペイロード自体を実行しようとすると失敗します。
図 12:ステージ 3 の復号関数
上記の関数は、いくつかの異なる処理を行います。まず、DNS クエリ応答で受信したコードをから、コードを格納する文字列変数を定義します。次に、第 3 ステージの復号関数を呼び出し、復号された文字列を IEX に渡して PowerShell 環境をさらに拡張します。これが完了すると、新しく拡張された環境内で特定のパラメータと共に第 4 ステージ のコードを実行するための関数を呼び出します。これらのパラメータには、第 4 ステージで使用する C2 ドメインならびにプログラムがあります。この例でプログラムに該当するのは Windows コマンド ライン プロセッサ(cmd.exe)です。以上のしくみが興味深い理由は、感染したシステムのファイル システムに実際に第 4 ステージのペイロードが書き込まれることはないという点にあります。
ステージ 4:PowerShell
前述のとおり、ステージ 4 のPowerShell ペイロードはステージ 3 内の「dec」関数によって復号されます。ステージ 4 のペイロードの末尾で、復号後のステージ 4 のコードに含まれる「cotte」関数が呼び出され、使用する C2 ドメインならびに実行するプログラム(cmd.exe)を含む追加パラメータが渡されます。この関数が cmd.exe を実行すると、STDIN、STDOUT、および STDERR がリダイレクトされて、コマンド ライン プロセッサに対するペイロードの読み取り/書き込みが可能になります。
関数呼び出しに渡されたドメインは、メインの C2 処理に使用される DNS クエリを作成する際に使用されます。ステージ 3 の PowerShell スクリプトと同じく、ステージ 4 のペイロードにもハードコーディグされたドメインからなる 2 つの配列が含まれますが、このステージで利用されるのは 2 番目の配列だけのようです。
図 13:ステージ 4 のドメイン リスト
メイン C2 サーバからの 301 番目の DNS 応答ごとに、サンプルは Get-Random コマンドレットを使用して上述の配列からドメインを取得し、そのドメインに別途 DNS TXT 解決要求を送信します。このセカンダリ C2 要求の目的は、感染したシステムでマルウェアの実行を続行するかどうかを判断することです。ステージ 3 の PowerShell スクリプトの場合と同じよように、この要求はセカンダリ C2 ドメインの Web サブドメインに対して行われます。
図 14:ステージ 4 のセカンダリ C2 ドメインの生成
セカンダリ C2 サーバから文字列「stop」が含まれる TXT レコードが返された場合、マルウェアは動作を停止します。
図 15:ステージ 4 の停止コマンド
メイン C2 チャネル自体は、感染したシステムからメイン C2 サーバに「SYN」メッセージを送信することによって確立されます。
図 16:ステージ 4 の「SYN」メッセージ応答の例
メイン C2 チャネルが確立されると、「MSG」メッセージを使用して、ステージ 4 で Windows コマンド ライン プロセッサからキャプチャされた STDOUT および STDERR 出力が送信されます。したがって、攻撃者は DNS TXT 要求および応答だけを使用して、コマンド プロセッサで実行するコマンドを直接送信し、それらのコマンドの出力を受信することができます。この通信については、次のセクションで詳しく説明します。以下に、感染したシステムから C2 サーバに送信されたクエリ要求の DNS 分析および内容を示します。
図 17:「MSG」メッセージの例
クエリのドメイン構造は難読化されます。DNS 要求クエリを取得し、そのクエリを復号関数を使用して実行すると、クエリが C2 サーバに送信されている Windows コマンド ライン プロセッサの出力であることが明白にわかります。
図 18:復号された TXT 要求
上記の図から明らかに、システム コマンドの実行、そして実行したコマンドの出力を受信する目的で使用できるインタラクティブ C2 チャネルが確立されていることがわかります。
コマンド & コントロール(C2)通信
悪意のある Word ドキュメントによる感染チェーンに関連する C2 ドメインが最初に登録されたのは、2017 年 2 月 8 日でした。続く 2017 年 2 月 18 日に、私たちが分析した Hybrid Analysis の PowerShell サンプルに関連するドメインが初めて登録されました。登録者のアカウントで登録されているドメインの一部は、以下の電子メール アドレスを使用して登録されています。
valeriy[.]pagosyan[@]yandex[.]com
他のドメインは、NameCheap 登録サービスによって登録されたものです。
Umbrella 内で入手できるデータによると、PowerShell サンプルで使用されているドメインに関連する DNS アクティビティの大半は、2017 年 2 月 22 日から 2017 年 2 月 25 日の間に発生しているようです。これに比べ、特定されている他のサンプルに関連するアクティビティの数は少なく、そのほとんどは 2017 年 2 月 11 日に発生しています。
図 19:サンプル DNS トラフィックのグラフ
このマルウェアに関連するすべての C2 通信は、DNS TXT クエリおよび応答を使用して行われます。インタラクティブな「MSG」クエリには、前提条件となる「SYN」クエリを使用して C2 通信チャネルの確立を成功させることが必要となります。これらのメッセージを構成する要素は以下のとおりです。
$session_id:感染したマシンによって最初に生成される 4 桁の番号。
この番号が変更されることは決してありません。以降の DNS クエリおよび応答には、常にこの番号が組み込まれます。
$sequence_num:感染したマシンによって最初に生成される 4 桁の番号。この番号は C2 通信期間中に定期的に変更され、クエリごとに新しい値が使用されます。
$acknowledgement_num:「SYN」メッセージに対する応答によって設定される 4 桁の番号。この番号は変更されないようです。以降の「MSG」クエリおよび応答には、常にこの番号が組み込まれます。
メッセージのタイプは、DNS クエリおよび応答のバイト 5 と 6 によって決まります。これらのバイトは以下のいずれかの値になります。
00:「SYN」メッセージ
01:「MSG」メッセージ
02:「FIN」メッセージ
実行するコマンドを送信し、実行したコマンドの出力を返すために使用される「MSG」クエリは、16 進数でエンコードされ、ドットを区切り文字として 30 バイトごとに区切られます。
以下の図に、C2 通信フローの概要を示します。攻撃者が感染したホストで実行しようとしている操作によっては、C2 通信が行われている間、複数の「MSG」クエリおよび応答が行われる場合もあります。
図 20:C2 トラフィック フロー
以下の図に、各種のメッセージと各メッセージに関連する応答の構造を示します。
図 21:C2 メッセージの構造
まとめ
このマルウェア サンプルは、攻撃者がターゲットとする環境内で検出されることなく長期間留まろうとする理由を説明する好例です。さらに、HTTP/HTTPS や SMTP/POP3 などのネットワーク プロトコルを検査してフィルタリングするだけでなく、攻撃者が完全に機能する双方向の C2 インフラストラクチャを実装するために利用できるチャネルとして、企業ネットワーク内の DNS トラフィックも考慮することが重要であることも、このマルウェア サンプルから明らかにわかります。Umbrellaは、DNS トラフィックの監視およびフィルタリングを具体的な目的として利用できる製品です。DNS を監視してフィルタリングすることで、DNS トラフィックを利用する攻撃を阻止できるだけでなく、マルウェア感染の大部分を食い止めることができます。それは、マルウェアの 90% 以上が感染プロセスの何らかのステージ、あるいは感染後のプロセスで DNS ネットワーク プロトコルを利用するからに他なりません。
カバレッジ
お客様がこの脅威を検出してブロックできる別の方法を以下に記載します。
Advanced Malware Protection(AMP)は、これらの攻撃者によるマルウェアの実行の阻止に最適です。
CWS や WSA の Web スキャンは、悪意のある Web サイトへのアクセスを阻止し、それらの攻撃に使用されるマルウェアを検出します。
E メール セキュリティ は、攻撃の一環として攻撃者が送りつける、悪意のある電子メールをブロックします。
IPS や NGFW のネットワーク セキュリティ保護機能は、攻撃者による不正なネットワーク アクティビティを検出できる最新のシグネチャを備えています。
AMP Threat Grid は、悪意のあるバイナリを特定し、すべてのシスコ セキュリティ製品に保護機能を組み込みます。
Umbrella は悪意のあるアクティビティに関連付けられているドメインの DNS 解決を防止します。
侵害の兆候(IOC)
この投稿で説明されている攻撃を特定するには、以下の侵害の兆候が手掛かりになります。
ハッシュ:
f9e54609f1f4136da71dbab8f57c2e68e84bcdc32a58cc12ad5f86334ac0eacf (SHA256)
f82baa39ba44d9b356eb5d904917ad36446083f29dced8c5b34454955da89174 (SHA256)
340795d1f2c2bdab1f2382188a7b5c838e0a79d3f059d2db9eb274b0205f6981 (SHA256)
7f0a314f15a6f20ca6dced545fbc9ef8c1634f9ff8eb736deab73e46ae131458 (SHA256)
be5f4bfa35fc1b350d38d8ddc8e88d2dd357b84f254318b1f3b07160c3900750 (SHA256)
9b955d9d7f62d405da9cf05425c9b6dd3738ce09160c8a75d396a6de229d9dd7 (SHA256)
fd6e7fc11a325c498d73cf683ecbe90ddbf0e1ae1d540b811012bd6980eed882 (SHA256)
6bf9d311ed16e059f9538b4c24c836cf421cf5c0c1f756fdfdeb9e1792ada8ba (SHA256)
C2 ドメイン:
algew[.]me
aloqd[.]pw
bpee[.]pw
bvyv[.]club
bwuk[.]club
cgqy[.]us
cihr[.]site
ckwl[.]pw
cnmah[.]pw
coec[.]club
cuuo[.]us
daskd[.]me
dbxa[.]pw
dlex[.]pw
doof[.]pw
dtxf[.]pw
dvso[.]pw
dyiud[.]com
eady[.]club
enuv[.]club
eter[.]pw
fbjz[.]pw
fhyi[.]club
futh[.]pw
gjcu[.]pw
gjuc[.]pw
gnoa[.]pw
grij[.]us
gxhp[.]top
hvzr[.]info
idjb[.]us
ihrs[.]pw
jimw[.]club
jomp[.]site
jxhv[.]site
kjke[.]pw
kshv[.]site
kwoe[.]us
ldzp[.]pw
lhlv[.]club
lnoy[.]site
lvrm[.]pw
lvxf[.]pw
mewt[.]us
mfka[.]pw
mjet[.]pw
mjut[.]pw
mvze[.]pw
mxfg[.]pw
nroq[.]pw
nwrr[.]pw
nxpu[.]site
oaax[.]site
odwf[.]pw
odyr[.]us
okiq[.]pw
oknz[.]club
ooep[.]pw
ooyh[.]us
otzd[.]pw
oxrp[.]info
oyaw[.]club
pafk[.]us
palj[.]us
pbbk[.]us
ppdx[.]pw
pvze[.]club
qefg[.]info
qlpa[.]club
qznm[.]pw
reld[.]info
rnkj[.]pw
rzzc[.]pw
sgvt[.]pw
soru[.]pw
swio[.]pw
tijm[.]pw
tsrs[.]pw
turp[.]pw
ueox[.]club
ufyb[.]club
utca[.]site
vdfe[.]site
vjro[.]club
vkpo[.]us
vpua[.]pw
vqba[.]info
vwcq[.]us
vxqt[.]us
vxwy[.]pw
wfsv[.]us
wqiy[.]info
wvzu[.]pw
xhqd[.]pw
yamd[.]pw
yedq[.]pw
yqox[.]pw
ysxy[.]pw
zcnt[.]pw
zdqp[.]pw
zjav[.]us
zjvz[.]pw
zmyo[.]club
zody[.]pw
zugh[.]us
cspg[.]pw
本稿は 2017年3月2日に Talos Group のブログに投稿された「Covert Channels and Poor Decisions: The Tale of DNSMessenger」の抄訳です。