はじめに
ランサムウェアである Maze は、実行環境にあるファイルを暗号化し、ファイルを復号するために身代金を要求します。データが窃取された場合、窃取したデータは公開され、身代金の支払いをマルウェア感染者に促します。 2019 年には、100 以上の組織に侵入し、データを暗号化したという報告があります。マルウェアのターゲットとなっている企業は、日本企業も含まれている可能性があります。 今回、 FFRIセキュリティ は Maze の検体を解析し、その挙動や暗号化の過程を調査しました。本記事を通じてランサムウェア Maze の詳細に迫ります。
ファイル情報
- SHA-256
- dee863ffa251717b8e56a96e2f9f0b41b09897d3c7cb2e8159fcb0ac0783611b
- ファイルタイプ
- 32bit EXE
動作条件
厳密な動作条件は不明ですが、 xmm レジスタ等を使う処理が含まれているため、 SSE 命令セットをサポートしていないアーキテクチャでは動作しない可能性があります。
なお、ファイルの暗号化自体の動作条件としては、プロセスの管理者権限の保持やインターネットへの接続を条件としていません。
検証環境
- Windows7
- Windows10
- Windows Server 2016(Active Directory ドメインコントローラの場合)
耐解析機能
検体は複数のテクニックにより、解析を妨害します。
大量のジャンクコード
検体のエントリポイントから間もなく、意味のない定数演算と分岐処理が続きます。40 個程の分岐を含むコードを複数回繰り返し実行します。ほとんどの分岐は実際には使用されませんが、このコードの中に後述する耐解析機能が含まれているため、解析のためにはこれらの動作を全て追跡する必要があります。
PEB を参照したアンチデバッグの無効化
検体は、 Process Environment Block (PEB) から BeingDebugged フィールドの値を取得し、この値により処理を分岐することで解析を妨害します。このフィールドは、ユーザーモードデバッガによりプロセスがデバッグされている場合 1 に設定され、それ以外の場合は 0 に設定されます。
この BeingDebugged の取得は複数回行われ、いずれかの取得の時点でこの値が 1 であった場合、無限ループを実行し続けます。検体の実行中に BeingDebugged の値が更新されることはおそらくないため、 BeingDebugged の取得は本来 1 回で十分です。それにも関わらず検体が複数回に渡って BeingDebugged を参照する理由は、無効化の手間を増やし、解析を遅延させるためと考えられます。
call を使用しないフロー制御
検体の特徴のひとつとして、フロー制御およびサブルーチンの呼び出しの方法が、通常のアプリケーションと異なるという点が挙げられます。検体は call
命令を極限られた少数の場面でしか使用しません。ほとんどのフロー制御は、復帰先アドレスの push
とjmp
命令(あるいはそれに類する je
, jne
等の命令)の組み合わせによって実装されています。
引数を push
した後、復帰先のアドレスを push
し、jmp
により検体自身のサブルーチンあるいは API を呼び出します。jmp
先が ret
を呼び出したときに、事前に push
しておいたアドレスが復帰先として使用され、後続の処理が行われます。この検体において、基本的に外部APIの呼び出しは jmp
命令を格納したテーブルの要素へ jmp
することによって実装されています。
そのため、call
命令でフロー制御を行うことを前提に作成されたデバッガは、その機能の一部であるコールスタックの追跡機能を正常に機能させることができなくなります。そのためこの検体の解析者は、スタックに積まれた値が復帰先アドレスを意味しているということを管理し続ける必要があります。
挙動
検体はそれぞれ固有の処理を持つ複数のスレッドを生成します。スレッドの派生関係を以下の図に示します。
MITRE ATT&CKとの関連
検体における詳細な挙動に関しては、参考資料に記載している記事をご確認下さい。ここでは、観測された挙動の MITRE ATT&CK との対応関係と図 6 における実行されたスレッドを記載します。なお、今回確認された挙動のみを対象としています。
MITRE ATT&CK Tactics | スレッド番号 | 挙動の説明 | MITRE ATT&CK Technique |
---|---|---|---|
Defense Evasion | 1 | Process Environment Block (PEB) を参照して、プロセス自身がデバッグ実行されているか判定し、デバッグ実行されている場合は無限ループに陥る。 | Obfuscated Files or Information |
Defense Evasion | 2 | 取得したプロセスの名前をハッシュ値に変換し、検体の中に事前に定義されたハッシュ値と比較する。一致した場合、そのプロセスを停止させる。x64dbg.exeやprocmon.exeなどの解析ツールが停止の対象となる。 | Impair Defenses: Disable or Modify Tools |
Defense Evasion | 2 | デバッガのリモートアタッチを禁止する。 | Impair Defenses: Disable or Modify Tools |
Discovery | 2 | システム上で実行中のプロセスの一覧を取得する。 | Process Discovery |
Discovery | 2 | コンピュータ名、ユーザ名、 Active Directory ドメインの中での侵入対象 PC の役割、 Windows バージョン名、 RID 、ユーザの言語情報等を取得する。 | Account Discovery |
Discovery | 2 | 特定のドライブのファイルを探索する。 | File and Directory Discovery |
Discovery | 2 | セッション共有済みのファイル共有有無を確認する。 | Network Share Discovery |
Command and Control | 3 | データ流出先との通信に独自の難読化処理を実装している。 | Data Obfuscation |
Impact | 2 | システム内のボリュームシャドーコピーを削除する。 | Inhibit System Recovery |
Impact | 4,5 | 特定の名前のディレクトリやファイルを除き、ファイルを暗号化する。 | Data Encrypted for Impact |
Impact | 6 | 警告を行うスレッドを作成し、身代金を要求するメッセージをデスクトップの壁紙として表示した後、ビープ音を鳴らす。このスレッドは、一定時間毎に警告文を音声で読み上げることを繰り返す。 | Defacement |
また、今回の実行環境として作成した単純なドメインコントローラでは挙動は確認できませんでしたが、実運用されているドメインコントローラ等で実行された場合、検体内部に LsaCreateTrustedDomainEx
の API を使い、新たにドメインを作成する可能性があります。
通信
FFRIセキュリティが解析した際、検体実行時に、暗号化を行う前に何らかのデータを、特定の IP アドレスに送信していることが確認されました。
送信されたデータのサイズは、 0xF1 バイトで、毎回異なるデータが送信されているようでした。
同じ環境で実行すると、同じサイズのデータが送信されるため、付近のヒープメモリで確保されたデータを探した所、以下のデータを送信している可能性が高いことが推察できます。
- ID(16 桁の整数/ミューテックスの名前、
DecryptFiles.txt
に提示されるアクセス先URL内のファイル名と同一) - ユーザ名
- コンピュータ名
- ActiveDirectory 内での役割
- Windows のバージョン
- その他(未判明)
先頭に 0x01 を付け、末尾に 8 バイトを付ける形で、このデータを何らかの形で暗号化し、 0xF1 バイトのでデータとして、送信している可能性が高いです。
また、暗号化ファイルの送信とは別に、0x30バイト程のデータを送信していることが確認されましたが、内容は未判明です。
送信先は、以下の図に示す IP アドレスを巡回して送信しているようです。実行環境では、先頭の 92[.]218.114.4
に上記の情報を送り、後続の IP に 0x30 バイト程のデータを送り、ログインの様な処理を行っている可能性があります。
今回 FFRIセキュリティ が解析に使用した環境においては、暗号化されたデータが流出されることを確認できませんでしたが、通信先や検体によっては、標的型攻撃の場合や一般的な場合でも、暗号化されたデータが流出することが考えられます。
ランサムウェアとしての挙動
暗号化
感染した場合のファイルの暗号化方法を以下に示します。
1. ChaCha と思われるストリーム暗号によりファイルを暗号化します。
この際、鍵(0x20バイト), nonce (0x8バイト) の生成には Crypt32!CryptGenRandom
を使用します。実装は検体内部に存在し、非常に熟慮された実装となっています。ChaCha の実装のうち QuarterRound の計算と思われる箇所を図9に示します。
詳細を観察すると、add, xor, 左シフトのみの単純な QuarterRound の計算になっておらず、右シフトや pshufd 等を用いて、複数のラウンドを統合して処理する最適化と思われる処理が含まれています。なお、赤枠で示した処理はこの後、8 回程繰り返されます。
2. 上記の暗号化鍵と nonce (計 0x28バイト) を RSA 公開鍵で暗号化し、暗号化された内容後に設置します。
この暗号化の計算は、 Crypt32!CryptImportKey
によりマルウェア開発者(もしくは配布者)が保有する秘密鍵に対応した公開鍵を利用し、各値を Crypt32!CryptEncrypt
で暗号化します。
例えば、以下の内容のファイルが存在し、このファイルが暗号化されたと仮定します。
0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61
暗号化後にファイルは以下の図10の様になります。
暗号化されたファイルの後に元のファイルの内容を暗号化した鍵が付いており、その後に固定値が付いています。
なお、ChaCha と思われる暗号化アルゴリズムの鍵と nonce は 0 、 RSA の公開鍵はこの検体に使用された図11のそれと仮定しました。
復号
復号する際は、まず、ファイルの末尾から秘密鍵でセッション鍵を復号し、その鍵でファイルの内容を復号すると考えられます。各検体によって、保有する公開鍵は異なっており、対応する秘密鍵も複数あると思われます。そのため、この際に使用される秘密鍵を特定する情報が最後の固定値(異なる RSA 公開鍵を持つ検体で同一であることは確認しているので可能性は低い)、または、後述するMAZE KEY
である可能性があります。
感染した場合、以下の DECRYPT-FILES.txt
が各フォルダに設置されます。
復号する際に必要となると思われる末尾の MAZE KEY
について、以下の手順で生成されている可能性が高いです。
- 実行時に、
Crypt32!CryptGenKey
、Crypt32!CryptExportKey
により RSA の秘密鍵 (2048bit) を生成し、 PRIVATEKEY_BLOB を出力します(この長さは RSA のパラメータに依存する為、動的に決定されます)。 - 1 の結果を検体内に実装された ChaCha で暗号化します。
- 2 で使用したランダムに生成された鍵(0x20)、 nonce(0x8) を検体内部に含まれているRSAの公開鍵(各ファイルの暗号化に使用する鍵とは異なる鍵)でそれぞれ別途暗号化します。
- 通信内容に含まれると思われる内容と同様のデータである、ミューテックス名(何らかの ID を示すと思われます)、ユーザ名、コンピュータ名、 Active Directory における役割、バージョン名等を情報を 2、3 に付属します。
- 2、3、4の結果を Base64 でエンコードします。
なお、この値(4 を除いた 2、3 に動的に生成された RSA の公開鍵を Base64 エンコードした値)は初回実行時に C:\ProgramData\<data1.tmp(または、ランダムなファイル名)>
の拡張属性(Extended Attributees : ファイルシステムの機能として、ファイルに関連付けることができるデータ)として保存され、二回目以降の実行時に再利用されるようです。
DECRYPT-FILES.txt
に含まれる URL にアクセスすると、このファイルをアップロードするよう要求されます。
このファイルをアップロードすると、 MAZE KEY
の値(但し、後方の一部のバイトのみが照合に使われる)を元にして、以下のタブ付きの画面に遷移します。遷移先のURLに含まれるファイル名は、ミューテックスで示した16進数で16桁の値と一致しており、 MAZE KEY
のフォーマットの内、鍵以外の情報を確認していると思われます。
なお、記事執筆(2020/7/31)時点で、 FFRIセキュリティ が使用した環境、検体で暗号化されたファイルの復号は一時的に行えないようでした。補足として、本来、鍵の照合が行われていれば、データが流出していない場合も復号は行えるはずです。
ファイルが暗号化された場合でも、復号されたデータが流出しない場合もあり、データの流出が同時に発生したか確認する必要があります。
おわりに
今回の記事でランサムウェア Maze の詳細に迫りました。
暗号化の処理をAPIに移譲するマルウェアも多く存在しますが、今回 FFRIセキュリティ が行った調査では、 Maze の内部に独自に実装された ChaCha による暗号化処理を確認することができました。
また、 DECRYPT-FILES.txt
の内部に記載される MAZE KEY
の値がどのように生成されるかを特定することができました。
Maze のように検体の内部に独自に暗号化処理が実装されている場合、暗号化が行われていること自体を検出することは困難ですが、
それを差し引いても、攻撃の過程を詳細に紐解くことは、攻撃の全貌を紐解く上で必要な過程であると考えられます。
今回の解析により得られた情報が、今後の検出、および攻撃者へ身代金を支払わない復号の一助になれば幸いです。