セキュリティ技術

マルウェア構成の大規模解析で脅威アクターの秘密をあばく

Clock Icon 3 min read
Related Products

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

概要

マルウェアの展開時、インスタンスごとに構成(configuration)データが異なっていれば、それらの構成情報はアクターらの意図をさぐる宝の山となりえます。問題はマルウェアの構成データというものはえてしてファイルから静的に解析しづらい、という点です。マルウェア作者らはマルウェアへの動作指示におけるインテリジェンスの価値を理解しているのです。

コードの再利用や抽象化からさまざまな恩恵を受けられるという意味で、マルウェアも複雑なソフトウェア システムとそう変わるところはありません。したがって、私たちの解析するさまざまなマルウェア ファミリーに、ソフトウェアの構成という概念が浸透していることは、とくに驚くべきことではありません。ようするに、典型的なサイバー犯罪者が、標的が変わるつど、わざわざコードを再コンパイルしてIPアドレスなどを変更したがるか、と問われれば、それはちょっと考えにくい、というわけです。

よいニュースは、「静的に装甲された構成データは簡単に見つかることが多く、メモリーから直接パースできる」ということです。そこで本稿は、IcedIDというインフォスティーラー(情報窃取型マルウェア)の構成をサンプルとして、その構成の難読化方法や抽出手法を解説します。

パロアルトネットワークスのお客様は、Advanced WildFireを通じ、本稿で解説する回避行為への検出力を高められます。マルウェア ファミリーの解析や情報抽出を大規模にスケールさせ、そこから得た脅威インテリジェンスをためておくことで、多様な組織を狙う多様な脅威アクターらのキャンペーンと戦術への理解を深めるのに役立てばと考えています。

関連するUnit 42のトピック Memory Detection, Malware

マルウェアの構成(configuration)とは

マルウェアの文脈で「設定(configuration)」とは一体何を指しているのでしょうか。マルウェア以外の文脈だと、「構成」は「システムの動作を定義する」という意味で捉えられます。たとえば「どのネットワーク経路をファイアウォールに許可するか」や、本稿を読むさいに「Webブラウザーにどのフォント サイズを使わせるか」を定義するときに使うルールは、「構成可能(configurable)な情報」と見なせます。

マルウェアについてもこれと同じです。マルウェアの構成とは「マルウェアの動作方法を定義する要素の集まり」に過ぎません。これには以下のようなものがあります。

  • コマンド&コントロール(C2)のネットワーク アドレス
  • リモート管理者用のパスワード
  • 永続的なペイロードのドロップ先となるファイル パス

これらの要素をマルウェア コンポーネントに埋め込む方法は、対象マルウェア ファミリーごとに固有なものになる傾向があります。このほか、マルウェアの開発途上で、またはマルウェア作者のビルド プロセスの変更にともない、時間経過とともに進化する可能性もあります。

マルウェアの構成要素は一般に、マルウェアのもつプロパティーのうち、それを簡単に編集できるようにしておくことで、いちいち手でコードを編集しなくても異なるキャンペーンやデプロイに使える、といった要素であることが多いです。またマルウェアの構成要素からは、通りいっぺんの動的解析では観測できないような潜在的動作やマルウェア インフラが明らかになることもあります。

マルウェアの構成は、キャンペーンに対する経時的洞察を提供してくれることから、セキュリティ実務者にとってはインテリジェンスとしての価値があります。場合によっては、このインテリジェンスを実用的アーティファクトとして使い、防御側がネットワークでの検出や感染ホストの特定に役立てることもできます。また、マルウェア構成の抽出・検証が成功すれば、ファイルの悪性判定確度の向上にもつながります。

このようにマルウェア構成は、セキュリティ システムにとっても防御側にとっても等しく価値があることから、現代のマルウェア作者は、さまざまな手法で構成要素を保護することが常識となっています。この保護にはよく、暗号化や難読化、圧縮を組み合わせたものが使われます。これに回避技術を重ねて使うケースもあります。

こうした保護は、静的解析だけにたよるマルウェア構成抽出器にとっては大きな課題となります。抽出を実行するには、まずこれらの保護機能をすべて検出・解除しなくてはならないからです。そこで、高度な動的解析サンドボックスとインテリジェントなランタイム メモリー解析を組み合わせれば、これらの保護の多くを解除して、抽出実行のチャンスが大きい場面をピンポイントに特定できます。

これらの構成を標準化されたスキーマで表現・保存することで、自動化、機械学習、インタラクティブ分析を通じて最大の価値を引き出せるようになります。DC3-MWCPライブラリーは、もっとも一般的な構成要素タイプの多くについてスキーマを定義しており、JSON形式にシリアライズするためのシンプルなライブラリーを提供してくれます。

MITRE MAECSTIXプロジェクトも、マルウェアの構成要素を表現するためのより一般的な語彙を提供してくれています。これにより、動的解析時に収集した観測対象オブジェクトと構成要素とを関連付けられるようになります。

IcedIDの解析

ではここで、あるIcedIDバイナリーとその構成がどのように暗号化されているかを見ていきましょう。

ハッシュ 05a3a84096bcdc2a5cf87d07ede96aff7fd5037679f9585fee9a227c0d9cbf51

図1に示したこの特定の攻撃チェーンは2022年11月上旬に発見されたものです。このケースでは、最終ペイロードとしてインフォスティーラー(情報窃取型マルウェア)のIcedID (別名Bokbot)が配布されました。この脅威は2019年から人々を攻撃しているよく知られたマルウェアです。

下の図は感染チェーンを示したものです。

画像1はIcedIDの感染チェーンを示す図です。この図は、悪意のあるスパムのユーザーによる実行から始まってIcedIDの第2ステージである永続化用スケジュール タスクの作成で終了します。
図1. IcedIDの感染チェーン

IcedIDの作者たちは苦心して構成を隠していました。最近のIcedIDの第2ステージのサンプルは、被害者のマシンが脅威アクターの要件を満たした場合にのみダウンロードされます。

IcedIDの構成はC2のURLとそのキャンペーンIDで構成されていました。C2のURLには、IcedIDバイナリーの実行中には判明しなかったであろうURLも含まれていました。このキャンペーンIDはIcedIDサンプルを特定の脅威アクターにリンクさせるものです。

ここでは次の手順でIcedIDの第1ステージと第2ステージのバイナリーに含まれる構成を抽出していきます。

  1. IcedIDのバイナリーをアンパックする
  2. 暗号化された構成データのBlobの場所を特定する
  3. 暗号鍵を抽出する
  4. 構成データのBlobを暗号鍵で復号する

IcedIDの第1ステージをアンパックする

IcedIDの第1ステージはまずVirtualAlloc関数でメモリーを確保し、自分自身をアンパックします。続いて図2に示すようにmemset関数を使って割り当てられたメモリーを消去します。最後に、memmove関数を使用して、アンパックされたデータを割り当てられたメモリーにコピーします。

アンパックしたデータをダンプするため、memmoveにブレークポイントを設定しておきます。memmoveの第2引数には、アンパックしたデータのアドレスが格納されています。図2では、16進ダンプの右側に、アンパックされたIcedIDの第1ステージDOS MZのヘッダーも表示しています。

画像2はIcedIDの第1ステージをアンパックしたさいのスクリーンショットです。アンパックはVirtualAlloc関数を使って実現しています。
図2. IcedIDの第1ステージのアンパック

暗号化された構成データのBlobの場所を特定する

次は、アンパックした第1ステージのIcedIDを使って、暗号化された構成データのBlobを探しました。アンパックしたIcedIDの第1ステージ ファイルのデバッグ中は、図3のようにWinHttpConnectを呼び出しているアドレスにブレークポイントを設定しました。レジスタRDIが指すアドレスにはC2のURL文字列が含まれています。

画像3はIcedIDの第1ステージをデバッグしているスクリーンショットです。
図3. IcedIDの第1ステージのデバッグ

コードをバックトレースし、復号された構成を使っている関数の場所を特定しました(図4)。

画像4はIcedIDの第1ステージのコードをバックトレースしているスクリーンショットです。
図4. IcedIDの第1ステージのコード トレース

さらにコードをバックトレースし、図5に示すように、構成を復号するループを見つけました。

画像5はIcedIDの第1ステージで構成の復号を行うループのスクリーンショットです。
図5. IcedIDの第1ステージの構成復号ループ

0x7FEF33339CDにある命令は、暗号化された構成データのBlob(Encrypted_Config)のアドレスをレジスタRDXにロードしていました。

暗号鍵を抽出する

0x7FEF33339D4にある命令は暗号鍵を読み取ります。この鍵はEncrypted_Configのアドレスから0x40バイト分オフセットされています。またこの構成のサイズは0x20バイトであることもわかりました。この構成はXORループを使って復号されていました。

暗号化された構成データのBlobを暗号鍵で復号する

ここまでで暗号鍵、暗号化されたデータBlob、復号ルーチンが集まったので、以下の図6のスクリプトを使って構成を復号できるようになりました。

画像6はIcedID第1ステージの構成復号スクリプトのスクリーンショットです。
図6. IcedIDの第1ステージの構成復号スクリプト

復号されたIcedIDの第1ステージの構成は次の図7のような形式です。

画像7はIcedID第1ステージの構成の形式のスクリーンショットです。
図7 IcedIDの第1ステージの構成形式

復号された構成からは以下のIoCを抽出できます。

C2のURL bayernbadabum[.]com
キャンペーンID 1139942657

次はIcedIDの第2ステージのバイナリーの構成を復号します。

IcedIDの第2ステージのバイナリーをアンパックする

IcedIDの第2ステージのバイナリーは第1ステージと同じパッカーを使っているのでアンパック手順は割愛します。

暗号化された構成データのBlobの場所を特定する

図8に示すように、Winhttpconnectを呼び出しているアドレスにブレークポイントを設定しました。

画像8はIcedIDの第2ステージのデバッグ中のスクリーンショットです。ブレークポイントが設定されている14行目がハイライトされています。
図8. IcedIDの第2ステージのデバッグ

コードをトレースし、復号された構成を使っている関数の場所を特定しました(図9)。

画像9はIcedIDの第2ステージのコードをトレースしたスクリーンショットです。復号した構成を使っている関数の場所が示されています。
図9. IcedIDの第2ステージのコード トレース

暗号鍵を抽出する

さらにコードをバックトレースし、構成を復号する関数を見つけました。そのはじめの数個の命令から、暗号化された構成のBlobの場所が特定されました。暗号化されたBlobのサイズは0x25cバイトです。暗号化された構成Blobの最後の0x10バイトが暗号鍵でした(図10)。

画像10はIcedIDの第2ステージの暗号鍵のスクリーンショットです。ハイライト表示されているのは暗号鍵のアドレスで、このアドレスは「offset to encryption key」というコメントのある行の下に表示されています。
図10. IcedIDの第2ステージの暗号鍵読み込み

暗号鍵を取得したら次は暗号化されたBlobを復号するループを実行します(図11)。

画像11はIcedIDの第2ステージで構成の復号を行うループのスクリーンショットです。このステップは暗号鍵取得の次に行われます。
図11 IcedIDの第2ステージの構成復号ループ

暗号化された構成データのBlobを暗号鍵で復号する

私たちはPythonを使って復号ループの命令を再現しました。これで暗号鍵、暗号化されたデータBlob、復号ルーチンが集まったので、以下の図12のスクリプトを使って構成を復号できるようになりました。

画像12はIcedID第2ステージの構成復号スクリプトのスクリーンショットです。
図12. IcedIDの第2ステージの構成復号スクリプト(注: Jquinn147氏とmyrtus0x0氏がIcedIDについて同様の構成復号スクリプトを2021年5月に公開済み。スクリプト名は「IcedDecrypt (GitHub)」)

復号されたIcedIDの第2ステージの構成は次の図13のような形式です。

画像13は復号されたIcedIDの第2ステージの構成形式を示したスクリーンショットです。
図13. IcedIDの第2ステージの構成形式

復号された構成からは以下のIoC(侵害指標)を抽出できます。

C2のURL newscommercde[.]com

spkdeutshnewsupp[.]com

germanysupportspk[.]com

nrwmarkettoys[.]com

C2のURI news
キャンペーンID 1139942657

これで、IcedIDの第1ステージ・第2ステージのバイナリー構成の手動による復号が終了しました。

スケールさせる

ここまでは、メモリー上の構成データをどのようにして解析するかという作業について解説してきました。次の課題はこの作業をどうやってスケールさせるか、すなわち大規模に展開(デプロイ)するかを考えることです。マルウェア処理システムの処理量は膨大なので、構成抽出システムの構築にあたる実務家はオーバーヘッドの増加に気をつけねばならない場合が多いでしょう。つまり、各パーサーにとって関心のあるサンプルだけをインテリジェントに識別するメカニズムが必要です。そうすれば、何百万ものサンプルに対して何十ものパーサーを不必要に実行せずにすみます。

この問題に対する合理的なアプローチとして、インテリジェントなランタイム メモリー解析の使用が考えられます。この方法ならマルウェア作者が守りたい秘密に対する高い可視性が得られるからです。マルウェア構成抽出器の典型的ワークフローには以下の内容が含まれます。

  • メモリーなどの動的解析アーティファクトをスキャンする
  • 抽出結果にノイズ フィルターをかけて最適な抽出候補を特定する
  • 最適モジュールで抽出を実行しレポート用・インデックス用に結果を保存する

この典型的ワークフローを汎化することで以下の改良を加えられました。

  • ほとんどのケースで解析データのスキャンを1回に抑えることによる検索フェーズの最適化
  • 多くの共通タスクに対する抽象化と再利用可能なコードの適用
  • 入力内容に問題がある場合やそのほかの不具合からモジュールがこうむる影響の抑制
  • セキュリティ リサーチャーから見たモジュール性能の可視性確保

以下の例は最近のIcedID抽出器のデプロイをスケールさせた後に抽出されたIoCの一部です。構成抽出器をデプロイする優れたフレームワークがある場合、構成抽出スクリプトを作りさえすれば、あとはゆったりくつろいで、何百という構成がマルウェア構成データベースに流れ込むのを待てばよくなります。

画像14はIcedIDサンプルからのIoCのスクリーンショットです。34行目から59行目までIoCが続いています。
図14 IcedIDサンプルから抽出された一連のIoC

結論

マルウェアの構成に関する概要と、私たちがAdvanced WildFireでこうした構成情報の大規模解析に尽力している理由について、ここまでお読みくださりありがとうございます。各マルウェア ファミリーの亜種をリバース エンジニアリングすることで、それらマルウェア全体について意味のある関連データ抽出用パーサーを大規模に構築できます。

マルウェアのペイロードには驚くほど多様性があり、そのすべてをサポートするのはほぼ不可能です。私たちは、それが可能な場面では、メトリクスにもとづくアプローチを使い、お客様との関連性がもっとも高いマルウェア ファミリーや亜種に優先的にフォーカスしています。この継続的な研究領域において、私たちのチームは、新しいマルウェア ファミリーや亜種へのサポートを拡大し続けます。

パロアルトネットワークス製品をご利用中のお客様は本稿で取り上げた脅威からAdvanced WildFireによって保護を受けています。

IoC

05a3a84096bcdc2a5cf87d07ede96aff7fd5037679f9585fee9a227c0d9cbf51

追加リソース

2023-05-18 09:00 JST 英語版更新日 2023-05-17 06:00 PDT の内容を反映

Enlarged Image