Skip to main content

【イベント】TrendAI™ Spark 2026 開催

AIセキュリティの最前線を探るグローバルイベント「Spark 2026」を全国5都市で開催します。

Return to TrendAI™ セキュリティブログ
サイバー犯罪

SHADOW-WATER-084の内幕:Remcos、LXBASEなどを配信するステガノグラフィ型ローダー・アズ・ア・サービス

TrendAI™ Researchは、まったく異なるおとりアプリケーションと互いに無関係なペイロードを、共通のツールキットで配信する3つのキャンペーンを追跡しました。本稿では、第1段階をピクセルデータに隠す手法から、複数のペイロードを配信できる柔軟な共通ローダーまで、攻撃チェーンの全体像を分析し、攻撃者が配信メカニズムを標準化している実態を明らかにします。

マルウェアサイバー脅威サイバー犯罪フィッシングとBEC一般業種調査・分析

Key Takeaways

  • TrendAI™ Researchは3つのサンプルを調査し、いずれも単一のオペレーションに属し、柔軟な共通ツールキットを使用していることを突き止めました。このオペレーションでは、実行コードが生のピクセルデータとして格納されています。おとりアプリケーションは、通常のビットマップリソース内に次のステージを埋め込みます。各カラーチャネルの全ビットがペイロードであり、従来のステガノグラフィとは異なります。実際の感染環境を使わずに抽出処理を再現し、ローダーバイナリを完全に復元できました。
  • ディスクに触れるのはおとりだけです。キャンペーンのステージ1とステージ2はメモリ内で再構築され、リフレクティブロードされます。最終ペイロードもメモリ内で復号され、インジェクションされます。ファイルスキャナから見えるのは、無害に見える1つの.NETアプリケーションだけです。
  • 製品に相当するのはローダーであり、マルウェアは顧客が選ぶ構成要素です。GraftLoaderとして追跡している3つのステージ2ローダーはすべて、43フィールドの設定形式、ペイロード暗号、永続化テンプレート、さらに個別にビルドされたサンプル間でバイト単位まで同一の残存ビルドアーティファクトを共有しています。
  • 2種類の暗号化処理とすべての鍵を復元しました。各ステージ間の遷移と埋め込みペイロードを静的に復号できるため、ペイロード抽出は机上で完結します。
  • 同じパイプラインを通じて、正体不明のパック済みスタブ、Remcos RAT 7.2.5 Pro、独自開発の.NET RATであるLXBASEなど、複数のペイロードが配信されます。LXBASEは、Chrome、Chrome Beta、Brave、Edge、Avast Secure Browser用にハードコードされたvtableオフセットを利用して、ChromeのApp-Bound Encryptionを回避します。

無関係に見える3つのキャンペーンを支える1つのツールキット

調査の発端となった3つのサンプルは、表面的にはほとんど共通点がありません。1つ目は物理学のチュートリアルを備えた水準器ユーティリティ、2つ目は手の妥当性検証とスコア管理機能を持つターン制カードゲーム、3つ目はセル・オートマトンのシミュレータです。ジャンル、サイズ、リソースの配置、作成者メタデータはすべて異なります。インポートハッシュも手掛かりになりません。3つのおとりのうち2つはCommon Language Runtime(CLR)のエントリポイントしかインポートしないため、コンパイル済みのあらゆるマネージドバイナリと同じimphashになります。残る1つには、インポートディレクトリ自体がありません。

それでも、3つは同じオペレーションです。このツールキットの背後にあるクラスタを「SHADOW-WATER-84」、キャンペーン活動を「Operation LoremDrop」として追跡しています。後者の名称は、オペレーション全体で最も特徴的なアーティファクトとなったLorem ipsumのパディングブロックに由来します。これらのおとりアプリケーションは、ユーザが30秒ほど操作すれば本物だと思わせられる程度には動作します。

その内部では、3つとも図1に示す同一の4段階チェーンを実行します。悪意ある分岐はフォームの初期化時に、おとりをもっともらしく見せるアプリケーションロジックが動き始めるより前に実行されます。「まず無害なコードを実行し、後から悪意を表すおとり」を手掛かりとするヒューリスティックでは検出できません。ユーザにウィンドウが表示される時点で、第1段階はすでにメモリに常駐しているためです。このチェーンで遅延が発生するのは、後述するローダー内部です。

1
図1:分析した3つのキャンペーンに共通するSHADOW-WATER-84の配信チェーン。ディスクに書き込まれるのはステージ0だけです。ペイロード列より左側の各ステージは、3キャンペーンで機能的に同一です。変化するのは右端の列だけです。

ステージ0:おとりアプリケーション

各キャンペーンは、アーカイブ内で配信される正規の.NET WinForms実行ファイルから始まります。そのリソースには、本物のWinFormsビルドが生成するアイコン、レイアウトデータ、画像が含まれています。その中に、実際には画像ではないビットマップが1つ紛れ込んでいます。

おとりは、フォームの初期化時に3つの処理を実行します。まず、ビットマップをピクセル単位で読み取り、色の値をファイルのバイト列として扱い、メモリ内で.NETアセンブリを再構築します。次に、ハードコードされた文字列を区切り文字で分割し、次のステージに必要な引数を取り出します。最後に、再構築したアセンブリをリフレクティブロードし、最初にエクスポートされた型を引数付きでインスタンス化します。ディスクには何も書き込まず、ビットマップが画面に描画されることもありません。

2
図2:3キャンペーンのおとりから次段階へ処理を渡すコード。手順は同じですが、リフレクションAPI、区切り文字、リソース名、バイト数はビルドごとに選ばれています。

図2からは、ソースレベルでビルド間の共通点がほとんどないことも分かります。キャンペーン1は「AppDomain.CurrentDomain.Load」で読み込み、名前をbase64文字列として隠したメソッドを呼び出します。キャンペーン3は、Visual Basicランタイムのヘルパーである「CallByName」を介して同じ処理に到達します。つまり、同じ手法を3通りに実装しているのです。

引き渡し用文字列

各おとりは、ステージ2ローダーのリソース名と排他的論理和(XOR)鍵、およびおとり自身のリソース名前空間を抽出し、ステージ1ローダーに渡します。

Campaign 1 (BubbleLevel) 
  ~hex12~BubbleLevel~hex12~
  4343756D~hex12~6B6777~hex12~ 4343756D -> “CCu” (Stage 2 bitmap resource) 
  6B6777 -> "kgw" (Stage 2 key string)​
  
Campaign 2 (CardGame)
()()48667954()()716B65()()"; 
  48667954 -> "HfyT" (Stage 2 bitmap resource) 
  716B65 -> "qke" (Stage 2 key string)​
  
Campaign 3 (CellularAutomaton) 
  &&&&&&&&&&&&&&&50414472&&&&&616C71&&&&&&&&&& 
  50414472 -> "PADr" (Stage 2 bitmap resource) 
  616C71 -> "alq" (Stage 2 key string)

日本語訳:

キャンペーン1(BubbleLevel) 
  ~hex12~BubbleLevel~hex12~
  4343756D~hex12~6B6777~hex12~ 4343756D -> “CCu” (ステージ2のビットマップリソース) 
  6B6777 -> "kgw" (ステージ2の鍵文字列)
  
​キャンペーン2(CardGame)
()()48667954()()716B65()()"; 
  48667954 -> "HfyT" (ステージ2のビットマップリソース) 
  716B65 -> "qke" (ステージ2の鍵文字列)​

キャンペーン3(CellularAutomaton) 
  &&&&&&&&&&&&&&&50414472&&&&&616C71&&&&&&&&&& 
  50414472 -> "PADr" (ステージ2のビットマップリソース) 
  616C71 -> "alq" (ステージ2の鍵文字列)

搬送用ビットマップ

この手法は通常、ステガノグラフィに分類されます。しかし、ここで使われているのは極めて原始的なステガノグラフィです。学術研究や趣味で使われるステガノグラフィは、各チャネルの下位ビットだけを変化させ、画像が写真らしく見え、自然画像の統計的特性も保つようにします。SHADOW-WATER-84は、そのような配慮を一切していません。各チャネルの全ビットがペイロードであり、見た目の自然さは考慮されていません。

その結果、図3のように構造化されたノイズとして表示されます。基になるPortable Executable(PE)にセクション配置用のパディングがある部分は同じ色のブロックが長く続き、コードや文字列の部分は不規則に変化します。図に示したのは、実際に埋め込まれていた画像リソースです。写真の下位ビットチャネルにデータを隠しているわけではなく、全ピクセルの全ビットが実行コードです。解析者が画像を見ても自然に感じる必要はありません。リソース列挙処理が画像として報告し、そのまま見過ごしてくれれば十分なのです。

3
図3:6つの搬送用ビットマップ(各キャンペーンに2つ)を画像として表示したもの。いずれも赤、緑、青の各チャネルからエントロピーを算出しています。

ピクセルをバイト列へ変換する仕組み

おとりとステージ1ローダーは、どちらもピクセルをバイト列に変換しますが、その方法は異なります。図4では2つの処理を並べています。この節で注目するのは上段です。両者を同じ図に示すことで、ピクセルのシリアライズ方法が大きく異なることを明確にしています。

4
図4:2つの抽出処理。おとりは列優先順で1ピクセルから3チャネルを暗号化せずに出力します。ステージ1は画像をクロップして4チャネルを出力し、長さプレフィックスを読み取って復号します。

おとりはビットマップを列優先順で走査します。外側のループをx、内側をyとし、各ピクセルの赤、緑、青のチャネルをこの順番で追加します。アルファチャネルは無視されます。保持するバイト数はハードコードされたパラメータであり、処理では使われない複数のおとり用引数と一緒に渡されるため、呼び出し部分は通常のアプリケーションコードに見えます。

抽出したビットマップリソースを使って、この処理を再現しました。出力の先頭には完全で正しい形式の「IMAGE_DOS_HEADER」があり、ハードコードされたバイト数で切り詰めると、3つのキャンペーンすべてでMD5が一致するステージ1ローダーを再現できました。

Campaign 1 Pun 95 x 94 -> 26,790 bytes emitted, first 26,624 kept 
           MD5 332b4cd85d1b878f5c5bf709b5984644 (SystemSafe.dll)​

Campaign 2 CTR 124 x 123 -> 45,756 bytes emitted, first 45,568 kept 
           MD5 53c39f839fd2efff0cea32307cecdd1c (SystemPuzzle.dll)​

Campaign 3 wck 178 x 178 -> 95,052 bytes emitted, first 94,720 kept 
           MD5 f3f10a350a46d35893c6583dd78e9d16 (SystemPuzzle.dll)

日本語訳:

キャンペーン1 Pun 95 x 94 -> 26,790バイトを出力し、先頭26,624バイトを保持 
            MD5 332b4cd85d1b878f5c5bf709b5984644 (SystemSafe.dll)​
            
キャンペーン2 CTR 124 x 123 -> 45,756バイトを出力し、先頭45,568バイトを保持  
            MD5 53c39f839fd2efff0cea32307cecdd1c (SystemPuzzle.dll)​

キャンペーン3 wck 178 x 178 -> 95,052バイトを出力し、先頭94,720バイトを保持 
            MD5 f3f10a350a46d35893c6583dd78e9d16 (SystemPuzzle.dll)

ステージ1ローダー

ステージ1ローダーは小さな.NET DLLです。キャンペーン1は「SystemSafe.dll」、キャンペーン2と3はどちらも「SystemPuzzle.dll」というファイルを使用します。3つとも名前が難読化されており、しかも異なる方式が使われています。キャンペーン1はメソッド名にUnicodeの紛らわしい文字、キャンペーン2は短い英数字トークン、キャンペーン3は辞書にある単語と制御フロー平坦化を併用しています。キャンペーン3ではメソッド数が380に膨らんでいるのに対し、ほかの2つは55と64です。

キャンペーン3のビルドにはさらに商用プロテクターが適用されており、解析ツールはアンチデバッグを有効にした.NET Reactor 6.xと判定しました。ただし、バージョンと設定はバイナリから直接復元したものではなく、ツールによる推定です。そのため、測定値ではなく帰属情報として扱っています。保護を除いた内部ロジックは3つとも同じです。

この処理は、おとりから3つのコンストラクタ引数を受け取ります。16進数でエンコードされた2つの秘密値と、おとりのルート名前空間です。図5には、引き渡し処理全体が1つのメソッドとして示されています。これらの引数を処理する前に、まずスリープします。

5
図5:キャンペーン2のステージ1ローダー

スリープ時間は「19,004ミリ秒」です。切りの良い19,000でも、一定範囲から選ばれるランダム値でもありません。

スリープ後、ステージ1は2回目のピクセル抽出を行い、得られたアセンブリをリフレクティブロードしてエントリポイントを呼び出し、「Environment.Exit(0)」を実行します。この時点でおとりプロセスは終了し、代わりのプロセスが動作しています。

2つ目の搬送用画像とステージ1による読み取り

ステージ1は自身のリソースではなく、おとりのリソースバンドルに戻り、受け取った名前空間と16進数エンコードされたリソース名を使います。この処理は図4の下段に示されています。2つ目の搬送用画像はより大きく、次の4点で処理方法が異なります。

  • 正方形にクロップします。搬送用画像の幅と高さから、それぞれハードコードされた定数177と225を減算してクロップ範囲を決めます。同じ2つの定数が3つのステージ1ローダーすべてにあり、3つの画像ではいずれも減算結果が同じ値になります。
  • 1ピクセルあたり3チャネルではなく4チャネルを使用し、「青、緑、赤、アルファ」の順にシリアライズします。これは、ピクセルカラーを整数として扱い、リトルエンディアンで書き出した際のバイト順であり、.NETでは自然な実装です。
  • 最初のピクセルはペイロードではありません。4チャネルがリトルエンディアンの長さプレフィックスになっており、後続するアセンブリの正確なサイズを示します。
  • 残りのバイト列は、16進数からデコードした鍵文字列と、抽出データ自体から得たマスクを基に生成したキーストリームで復号します。

この処理を再現すると、3つのステージ2ローダーをすべて完全に復元できます。

Campaign 1 CCum 662 x 710 PNG, cropped to 485 x 485 
           length prefix 01 4C 0E 00 = 936,961 bytes 
           MD5 5689f586213c88b9cd9ebb3cf7b9709b (WinTune.dll)​

Campaign 2 HfyT 710 x 758 PNG, cropped to 533 x 533 
           length prefix 01 44 11 00 = 1,131,521 bytes 
           MD5 aebb74ad24253b9cd5fa22787fab6af8 (System Optimizer Ultimate.dll)​

Campaign 3 PADr 685 x 733 PNG, cropped to 508 x 508 
           length prefix 01 AC 0F 00 = 1,027,073 bytes 
           MD5 3d10420f13575318d1d5379ff05edb2e (Edge Optimizer.dll)

日本語訳:

キャンペーン1 CCum 662 x 710 PNG、485 x 485にクロップ 
            長さプレフィックス 01 4C 0E 00 = 936,961バイト 
            MD5 5689f586213c88b9cd9ebb3cf7b9709b (WinTune.dll)​

キャンペーン2 HfyT 710 x 758 PNG、533 x 533にクロップ 
            長さプレフィックス 01 44 11 00 = 1,131,521バイト 
            MD5 aebb74ad24253b9cd5fa22787fab6af8 (System Optimizer Ultimate.dll)​
            
キャンペーン3 PADr 685 x 733 PNG、508 x 508にクロップ 
            長さプレフィックス 01 AC 0F 00 = 1,027,073バイト 
            MD5 3d10420f13575318d1d5379ff05edb2e (Edge Optimizer.dll)

ステージ2:GraftLoader

このコンポーネントをGraftLoaderとして追跡しています。GraftLoaderは、埋め込まれたペイロードを復号し、必要に応じて権限昇格や永続化を行ったうえで、ホストプロセスをホローイングするか、ペイロードを同一プロセス内に読み込む、設定可能な.NETローダーです。3つのビルドはすべて保護され、重要な文字列は個別に暗号化されているため、stringsによる抽出では有用な情報が得られません。以下の分析は、難読化を解除したビルドに基づいています。

図6に処理フローを示します。GraftLoaderの動作はすべて設定によって決まります。以下に示す各分岐は、ロード時に静的コンストラクタが解析する、パイプ区切りの43フィールド設定文字列の各スロットで制御されます。

6
図6:GraftLoaderの実行フロー。各分岐は設定文字列内のスロットによって制御されます。

1つの設定文字列と42個のスロット

すべての機能は、二重パイプで分割される1つのハードコード文字列によって制御されます。図7の静的コンストラクタは、この文字列を一度だけ解析し、各スロットを名前付きフィールドに割り当てます。同時に、ペイロードのリソース名、復号鍵、ウォッチドッグのミューテックス、永続化先のファイル名も設定します。3つのビルドはいずれも同じ形式とスロット対機能の対応関係を使い、値だけが異なります。

7
図7:キャンペーン2のGraftLoader静的コンストラクタ。設定文字列、ペイロードのリソース名、復号鍵、ミューテックス、動的に解決されるプロセスホローイング用API一式を示しています。

サンプルから復元した3つの設定文字列を以下に示します。どれも分割すると正確に43フィールドになります。最後のフィールドは末尾の区切り文字から生じる空の要素であるため、実質的には42個のスロットです。

Campaign 1 WinTune.dll
3||1||0||1||0||||||0||1||1||0||||||||||||||0||0||0||0||0||0||0||0||4.0||2||17752||1||0||||||0||0||0||||0||auto||0||.exe||0||0||​

Campaign 2 System Optimizer Ultimate.dll
0||1||1||0||0||||||1||1||1||0||||||||||||||0||0||0||0||0||0||0||0||4.0||0||11126||1||0||||||0||0||1||3||3||auto||0||.com||1||1||​

Campaign 3 Edge Optimizer.dll
0||1||0||1||0||||||0||0||0||0||||||||||||||0||0||0||0||0||0||0||0||4.0||2||17387||1||0||||||0||0||0||||0||auto||0||.pif||0||0||

日本語訳:

キャンペーン1 WinTune.dll
3||1||0||1||0||||||0||1||1||0||||||||||||||0||0||0||0||0||0||0||0||4.0||2||17752||1||0||||||0||0||0||||0||auto||0||.exe||0||0||​

キャンペーン2 System Optimizer Ultimate.dll
0||1||1||0||0||||||1||1||1||0||||||||||||||0||0||0||0||0||0||0||0||4.0||0||11126||1||0||||||0||0||1||3||3||auto||0||.com||1||1||​

キャンペーン3 Edge Optimizer.dll
0||1||0||1||0||||||0||0||0||0||||||||||||||0||0||0||0||0||0||0||0||4.0||2||17387||1||0||||||0||0||0||||0||auto||0||.pif||0||0||

これらのスロットを対応付ける作業には、本分析の中で最も時間がかかりました。42個のうち17個は、名前付きフィールドと、その背後にあるコードパスまで明確に特定できました。表1に示したのがその一覧です。

t1
表1:用途を確認できた設定スロットの一覧。残りのスロットもすべてのビルドに存在しますが、値とコードパスの対応は確認できませんでした。

ほかにも、3つのビルドで値が共通するスロットがあります。たとえば「4.0」は、ホストするランタイムのバージョンである可能性が高い値です。また、5桁の数値が3つ、すべてのビルドに存在しますが、用途は確認できませんでした。推測を避けるため、表には含めていません。

確認できた差異は、ビルド時のジェネレータが生み出す典型的なものです。3つのローダーは同じ機能セットを備えていますが、有効になっているスイッチが異なります。図8に評価順を示します。

8
図8:GraftLoaderのエントリポイント。処理順は固定され、どの分岐を通るかだけが変わります。

CMSTPによるUACバイパス

権限昇格を行うのはキャンペーン2だけです。スロット40が設定され、プロセスが管理者権限で動作していない場合、GraftLoaderはMicrosoft署名済みのConnection Manager Profile Installerである「cmstp.exe」を利用します。このバイパス手法自体は広く知られています。ここで重要なのは、ハンティングに使えるほど特徴的なINFファイルです。

ローダーはWindowsの一時ディレクトリにSetup Information(INF)ファイルを作成し、自動インストールスイッチを付けてインストーラに読み込ませます。このINFは「RunPreSetupCommands」セクションを宣言しており、インストール処理が完了する前に、昇格した権限でインストーラがその内容を実行します。プロファイルは「CorpVPN」というサービスを名乗り、最初のコマンドとして「cmstp.exe」自身に対する「taskkill」を実行します。これにより、事前セットアップコマンドが動いた後にインストーラのウィンドウが閉じられます。

確認プロンプトもユーザ操作なしで処理されます。ローダーは5秒間待機し、「CorpVPN」というタイトルのウィンドウを名前で探し、Return仮想キーコードを含むキーダウンメッセージを送信します。これにより、ダイアログが自動的に承認されます。図9に処理とテンプレートを示します。

9
図9:CMSTPバイパスと、書き込まれるINFテンプレート。下段は復号したテンプレート文字列の全文です。

INFテンプレートは本オペレーションで最も特徴的なアーティファクトであり、「Operation LoremDrop」という名称の由来でもあります。「CorpVPN」というサービス名に加え、ファイルサイズを増やす目的をコメントとして明記したパディングセクションが含まれています。追加コメントはINFの機能に影響しないという説明に続き、番号付きの3つのLorem ipsumコメントブロックが配置されています。

この分岐を有効にしているのはキャンペーン2だけです。この3つのサンプルだけを見れば、テンプレートは1回しか確認できず、それだけでは共有性の根拠になりません。バイト単位の一致は、同じ調査に含まれる隣接事例の別ローダーから確認しました。異なるペイロードを配信する個別ビルドのローダーが、同じLorem ipsumブロックを一字一句共有していることから、共通ビルダーが静的テンプレートを出力していると判断できます。

[version]
Signature=$chicago$
AdvancedINF=2.5​

[DefaultInstall]
CustomDestination=CustInstDestSectionAllUsers
RunPreSetupCommands=RunPreSetupCommandsSection​

[RunPreSetupCommandsSection]
<attacker command line>
taskkill /IM cmstp.exe /F​

[CustInstDestSectionAllUsers]
49000,49001=AllUSer_LDIDSection, 7​

[AllUSer_LDIDSection]
“HKLM”, “SOFTWARE\Microsoft\Windows\CurrentVersion\App 
Paths\CMMGR32.EXE”,
“ProfileInstallPath”, "%UnexpectedError%", ""​

[Strings]
ServiceName="CorpVPN"
ShortSvcName="CorpVPN"​

; ============================================
; Padding Section - Extra Comments for File Size
; ============================================
; This section contains additional comments to increase file size
; These comments do not affect the functionality of the INF file
; Comment block 1
; Lorem ipsum dolor sit amet, consectetur adipiscing elit.
; Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
; ...

日本語訳:

[version]
Signature=$chicago$
AdvancedINF=2.5​

[DefaultInstall]
CustomDestination=CustInstDestSectionAllUsers
RunPreSetupCommands=RunPreSetupCommandsSection​

[RunPreSetupCommandsSection]
<攻撃者のコマンドライン>
taskkill /IM cmstp.exe /F​

[CustInstDestSectionAllUsers]
49000,49001=AllUSer_LDIDSection, 7​

[AllUSer_LDIDSection]
“HKLM”, “SOFTWARE\Microsoft\Windows\CurrentVersion\App 
Paths\CMMGR32.EXE”,
“ProfileInstallPath”, "%UnexpectedError%", ""​

[Strings]
ServiceName="CorpVPN"
ShortSvcName="CorpVPN"​

; ============================================
; パディングセクション - ファイルサイズを増やす追加コメント
; ============================================
; このセクションにはファイルサイズを増やすための追加コメントが含まれる
; これらのコメントはINFファイルの機能に影響しない
; コメントブロック1
; Lorem ipsum dolor sit amet, consectetur adipiscing elit.
; Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
; ...

プロセス監視と再起動を担うウォッチドッグスレッド

3つのビルドはすべてウォッチドッグを実行します。スリープと権限昇格の分岐後、GraftLoaderは名前付きミューテックスを開きます。すでに存在する場合は新しいインスタンスを終了し、ホストごとに1つのコピーだけを維持します。存在しない場合はミューテックスを作成し、バックグラウンドスレッドを開始します。

このスレッドは、図10に示す2秒間隔のポーリングループです。実行中のプロセスを列挙して特定の識別子を探し、該当プロセスがなくなると、保存済みパスから再起動して現在のインスタンスを終了します。インジェクション先のプロセスを終了しても感染は止まらず、ウォッチドッグが永続化用コピーから再起動します。ミューテックス名はビルド固有で暗号化されているため、キャンペーン単位のインジケータになります。

10
図10:ミューテックスの初期化とウォッチドッグのポーリングループ

Defenderの除外設定

キャンペーン1と2は、ほかの処理を行う前に自身をMicrosoft Defenderの除外対象へ追加します。キャンペーン3は追加しません。ビルド間で確認できた防御回避上の差異は、この1点だけです。ローダーは非表示のPowerShellウィンドウを起動し、実行中のおとりのパスを指定して「Add-MpPreference -ExclusionPath」を実行します。このパスは後で永続化用にコピーされるパスと同じであるため、コピーの作成前に除外設定が適用されます。

休眠中の2つの機能

すべてのビルドには、スイッチがオフの機能が2つ組み込まれています。図11のダウンロード・実行分岐は、設定からURLとファイル名を読み取り、一時ディレクトリへダウンロードして実行します。呼び出し全体が例外を握りつぶすcatchで囲まれているため、失敗しても主要ペイロードの処理は中断されません。図12の偽ダイアログ分岐は、タイトル、本文、ボタン形式、アイコンのすべてを設定から取得してメッセージボックスを構築します。ペイロードを背後で動作させながら、もっともらしいエラーやライセンス確認を表示する用途が考えられます。

11
図11:すべての分析対象ビルドに存在するものの、無効化されていた追加ペイロードのダウンロード分岐

3つのビルドすべてで両機能はオフになっており、引数スロットも空です。ビルダーは機能を提供していますが、このオペレータは使用していません。

12
図12:設定可能な偽ダイアログ。タイトル、本文、ボタン、アイコンはすべて設定スロットから取得されます。

永続化と配置されるランチャー

永続化が有効な場合、GraftLoaderはビルド固有の名前を使って、ローミングアプリケーションデータディレクトリ内に保存先パスを作成します。図13にその手順を示します。ファイルがまだ存在しなければ、ローダーは保存先のアクセス制御リスト(ACL)を制限し、実行中のおとりファイルをコピーします。続いて、コピーに隠し、システム、読み取り専用、コンテンツインデックス対象外の属性を設定します。この時点で別のACLも適用し、読み取りと実行を許可する一方で、削除、書き込み、権限変更、所有権変更を拒否します。これらの保護処理全体は例外を握りつぶすcatch内にあります。チェーンにとって重要なのは、保護処理の成功ではなく、ファイルが存在することだからです。

13
図13:永続化の分岐。保存先の保護、コピー、属性設定を行った後、ランチャーを作成します。

この処理順はクリーンアップ時に重要です。コピーと保護は存在確認の後にあり、1回だけ実行されます。一方、ランチャースクリプトとレジストリ値は確認処理の外にあり、実行のたびに書き直されます。ローミングディレクトリ内のコピーを残したままRun値だけを削除すると、次にペイロードが動作した際にRun値が再作成されます。

レジストリエントリは最後に書き込まれます。格納されるのはコピー済み実行ファイルへのパスではなく、ローダーが一時ディレクトリへランダムな名前で配置したスクリプトを起動する、完全なPowerShellコマンドラインです。正常な環境で、Run値に「powershell.exe」の完全な起動コマンドが入るケースはほとんどありません。

配置されるスクリプト

ランチャースクリプトが行う実質的な処理は1つだけです。ローミングディレクトリ内の隠しコピーを起動します。ファイル内のほかの記述は、その1行を見つけにくくするために存在します。複数の難読化手法が重ねられ、個別にビルドされた3つのローダーが配置するスクリプトに、同じ組み合わせが見られます。図14では、取得したスクリプトとデコード後の内容を並べています。

14
図14:取得時のランチャーとデコード後の内容。15行の処理は、1回のStart-Process呼び出しに集約されます。

確認した手法は次のとおりです。

  • 文字コードからの再構築: コマンドレットのパラメータ名などの短い文字列を、個々の文字キャストの加算で組み立てます。ファイルパスは10進整数の配列を文字へキャストし、結合して作ります。どちらもbase64や16進数ではないため、エンコードされたblobを探すスキャナには見つからず、ペイロードのファイル名を平文検索しても一致しません。
  • 間接呼び出し: コマンドレット名さえ直接記述されません。「Start-Process」を変数内で組み立て、呼び出し演算子を介して実行するため、コマンドレット名のリテラル検索も失敗します。
  • 非決定的なジャンク: 変数に新しいGUIDを2〜3回代入しますが、その値は読み取られません。丸め処理で定数を計算する式もありますが、同様に未使用です。GUIDはファイルに埋め込まれず実行時に生成されるため、それ自体はスクリプトのハッシュを変えません。ハッシュを変化させるのは、ランダム化された変数名と対象ファイル名、およびユーザパスです。3つのサンプルでユーザパスが同じなのは、同じ解析ホストから取得したためです。

表2に、配置された3つのランチャーを示します。変数名、冒頭のコメントマーカー、ジャンク文の組み合わせ、対象ファイル名は異なります。しかし構造は同じで、いずれも15行からなり、同じ手法を使い、末尾で呼び出し演算子を1回実行します。3つのうち2つは同じマーカーで始まります。ビルドごとに完全なランダム文字列を生成するのではなく、小さな候補群から選んでいる可能性がありますが、3サンプルだけでは根拠として十分ではありません。

t2
表2:独自の動的解析で取得した3つのランチャー。10進配列は環境変数展開ではなく絶対パスにデコードされるため、表示されるアカウント名は被害者ではなく解析ホストのものです。

復元したペイロード暗号

最終ペイロードが復号された状態でディスクに置かれることはありません。GraftLoaderアセンブリ内の名前付き.NETリソースにバイト配列として格納され、インジェクションの直前にメモリ内で復号されます。図15に処理を示します。

15
図15:ペイロードの復号処理

この仕組みは、繰り返し使用するASCII鍵とのXORを行った後、次の暗号文バイトを減算するオートキー型ストリーム暗号です。一見しただけでは再実装しにくい点が4つあります。

  • 変換はインプレースで行われます。各位置で減算されるのは、まだ処理されていない暗号文バイトであり、その背後にある平文バイトではありません。
  • インデックスはバッファ長を法として折り返すため、最後の反復では位置0を再び読み取ります。
  • ループの上限値が包含されるため、バッファ長より1回多く反復します。
  • 最後にバッファを1バイト縮小するため、保存リソースは復号後のペイロードより常に1バイト長くなります。

各位置で行われる処理は、暗号文バイトと循環インデックス位置の鍵バイトとのXORから、後続する暗号文バイトを減算し、256を法として値を求めるものです。

for (int i = 0; i <= buf.Length; i++)
{ 
    buf[i % buf.Length] = (byte)(((buf[i % buf.Length] ^ key[i % key.Length])
                - buf[(i + 1) % buf.Length] + 256) % 
256);
}
Array.Resize(ref buf, buf.Length - 1);

格納リソースは裸の配列ではなくコンテナです。そのため、抽出処理では型コードと長さの内側にあるバイト配列まで到達する必要があります。リソース全体を暗号処理に渡しても、ノイズしか得られません。

ペイロードのダンプがあれば、同じ関係を逆にたどって鍵を求められます。循環インデックス位置の鍵バイトは、暗号文バイトと、「平文バイトに次の暗号文バイトを加えて256を法とした値」とのXORに等しくなります。鍵長は探索が必要です。1〜40を総当たりし、ファイル全体で一貫性を保つ最短の長さを採用したところ、1秒以内に3つすべてを特定できました。

復元した各鍵でリソースを最初から復号すると、ペイロードがバイト単位まで一致しました。キャンペーン2の鍵は、難読化を解除したコンストラクタ内の値とも独立して一致しています。この結果から、残る2つの鍵にも確信を得ました。

t3
表3:ペイロードリソースと復号鍵。サイズはバイト単位です。鍵長が7、9、14バイトであることは、ビルドごとにランダムな英数字鍵を生成するジェネレータの存在と整合します。

インジェクション:5つのモードと、実際に使われた2つ

スロット0は、復号したペイロードの実行方法を選択します。モード4は現在のプロセス内にリフレクティブロードします。モード0〜3は従来型のプロセスホローイングを行い、その値によってホストを選びます。モード0はローダー自身のイメージ、モード1は「MSBuild.exe」、モード2は「vbc.exe」、モード3は「RegSvcs.exe」です。

図16にモード選択と対象解決処理を示します。3つの.NET Frameworkバイナリはフルパスをハードコードせず、実行時にランタイムディレクトリから解決します。

16
図16:配信モードの選択とホローイング対象の解決処理

キャンペーン1はモード3を選択し、新たに起動した「RegSvcs.exe」をホローイングします。キャンペーン2と3はモード0を選択し、自身のプロセスの新しいコピーをホローイングします。モード1、2、4はすべてのビルドに実装されていますが、どのサンプルでも選択されていません。インプロセス分岐にはフォールバックもあり、リフレクティブロードで例外が発生すると、モード0のホローイングに移行します。したがって、モード4に設定されたビルドでも、最終的にホローイングを行う場合があります。

ホローイング自体は典型的ですが、APIの解決方法は異例です。GraftLoaderは関数をインポートせず、静的コンストラクタ内のデリゲートファクトリを介して名前で解決します。対象は「CreateProcessA」「ZwUnmapViewOfSection」「VirtualAllocEx」「WriteProcessMemory」「ReadProcessMemory」、WOW64版を含むスレッドコンテキストの取得・設定関数、「ResumeThread」です。すべてを汎用ヘルパー経由にすることで、「まさにこれらの関数をインポートするマネージドアセンブリ」という典型的な静的特徴を消しています。

3つのペイロード

これがローダーの最後の処理です。ローダーが引き渡す先だけは、ビルド間に共通点がありません。パックされたネイティブスタブ、市販のリモートアクセス型トロイの木馬(RAT)、独自開発の.NET RATです。

キャンペーン1:正体不明のパック済みスタブ

キャンペーン1のペイロードは286,208バイトの32ビットPEで、実行可能セクションは1つだけです。データディレクトリはすべて空で、インポートも再配置情報もありません。そのため、通常の意味では位置独立コードではなく、優先イメージベースを前提とした絶対呼び出し先を使います。コンパイルタイムスタンプは2017年12月を示していますが、ほかのツールセットと整合せず、偽装された可能性が高いと考えられます。

セクション全体が均一に暗号化されているわけではありません。スライディングウィンドウでエントロピーを測定すると、先頭8KBは1バイトあたり5.9〜6.8ビットで、エントリポイントもこの範囲にあります。それ以降は7.95です。低エントロピーの先頭部分が復号処理、高エントロピーの残りが展開される本体です。復号処理はAPIをインポートせず、プロセス環境ブロック(PEB)をたどってアドレスを解決します。インポートディレクトリが空なのはこのためです。

公開サンドボックスの判定では、この構造をFormbookまたはXLoaderと分類している例がありますが、本分析では裏付けを得られませんでした。「Formbookと整合する特徴がある」と説明するにとどめ、Formbookとは断定しません。

キャンペーン2:Remcos RAT 7.2.5 Pro

キャンペーン2のペイロードは、Breaking Securityが販売する市販のリモート管理ツールRemcosです。復元した鍵で「tSkc3nzxY」リソースを復号すると実行ファイルが直接得られ、設定リソースから製品名とオペレータの設定を確認できます。Remcosは、RCDATAリソース内に設定を格納し、同じリソースの1バイト長フィールドの後ろに置かれた鍵を使ってRC4で暗号化します。

RT_RCDATA / SETTINGS 659 bytes, RC4 key length 140​ 

  C2 primary     84.38.129.31:9095:0 
  C2 secondary   84.38.129.31:8085:0 
  Campaign tag   Rmc-T423KN 
  Bot label      RemoteHost 
  Install name   remcos.exe 
  Keylog file    logs.dat 
  Max log size   100000

日本語訳:

RT_RCDATA / SETTINGS 659バイト、RC4鍵長140​ 

  プライマリC&C    84.38.129.31:9095:0 
  セカンダリC&C    84.38.129.31:8085:0 
  キャンペーンタグ  Rmc-T423KN 
  ボットラベル     RemoteHost 
  インストール名   remcos.exe 
  キーログファイル  logs.dat 
  最大ログサイズ   100000

インポートテーブルは、製品が掲げる機能と一致しています。キーボードフックやクリップボード関連APIから、GDIによる画面キャプチャ、マイク録音用の「waveIn」関数まで含まれます。平文文字列には製品名、ベンダーのドメイン、ウォッチドッグモジュール名が残っています。分析時、C&Cエンドポイントには接続できませんでした。ただし、これだけではキャンペーンが実行された時期は分かりません。3つの分岐の時系列を判断できるテレメトリがないため、どれが古いかについても断定していません。

Remcosは既知の製品であるため、検証の基準になりました。復号したリソースから設定を読み出せたことで、抽出チェーンが最初から最後まで正しく機能することを確認できました。

キャンペーン3:LXBASE

キャンペーン3のペイロードには、特に多くの開発工数が投じられています。これは「LX_PYLD_FED77E72」という名前の422,912バイトの.NETアセンブリで、バージョンは1.0.0.17、267個の型と1,563個のメソッドを含みます。

配信に使われるローダーとは、保護方法が大きく異なります。型名のおよそ4分の3、メソッド名とフィールド名の約半分がランダムなトークンに置き換えられていますが、文字列はすべて平文のままです。ログメッセージ、コマンド名、ブラウザパス、定数がそのまま残っています。名前は読める一方で文字列を暗号化していたローダーとは正反対です。残存メタデータには、ルート名前空間として「LxClient」も残っています。このため、ペイロードの解析に必要な労力はローダーよりはるかに少なく、ペイロードと配信チェーンが別々の開発パイプラインから生まれたという見方と一致します。

このビルドにはC&Cサーバが設定されていません。復元できたネットワークエンドポイントは、ループバックの既定値とローカルフォールバック用のプライベートアドレスだけです。オペレータが未特定の経路を介して展開時にエンドポイントを設定するか、保有するサンプルが実戦投入されなかった可能性があります。このファイルだけを根拠に、キャンペーン3を実際に観測された侵入として扱うべきではありません。

内部ログから判断すると、機能は広範で、活発に保守されています。

  • connect、data、disconnectの各メッセージ形式を持つリバースプロキシチャネル。被害者ネットワークを経由するトンネルをオペレータに提供します。
  • ZIPベースのプラグインローダー。コマンドチャネル経由で分割送信されたアセンブリを実行時に受け取り、再展開せずに感染後の機能を追加できます。
  • Chrome、Edge、Brave、Opera、Opera GX、360 Browser、Discord、Telegram向けの専用起動プロファイルを備えた隠しデスクトップセッション。新しいプロファイルから起動する派生設定もあります。
  • HTML形式で出力するキーロガー。
  • 4つのChromeリリースチャネルからVivaldi、CocCoc、Sogou、2345まで、23種類のChromium派生ブラウザを対象とする認証情報窃取とCookie窃取。さらに「nss3.dll」を介してFirefoxプロファイルを読み取るGecko向けの別経路もあります。

LXBASEは、ブラウザとElevatorサービスのインターフェースおよびvtableオフセットの対応をコンパクトに保持しています。正規の呼び出し元になりすまし、対応する復号関数を呼び出してCookieを抽出します。復号したCookieは、暗号ライブラリを装ったヘルパーから動的な名前付きパイプを介して中継されます。検出では、通常とは異なるブラウザElevatorのインスタンス化と、ブラウザ更新で破綻しやすいハードコード済みオフセットが主な手掛かりになります。

さらに2つの細部から、作成者の姿勢が見えてきます。このアセンブリには18個の解析ツールのプロセス名があり、それぞれが個別の1バイトXOR鍵で難読化されています。デバッガ、逆アセンブラ、逆コンパイラ、ネットワークプロキシ、.NET難読化解除ツールが対象です。デバッガ接続の有無と並行して実行中のプロセス一覧を調べ、一致すれば終了します。また、「Environment.Exit」の呼び出しが82か所あり、54種類の終了コードが使われています。解析中にサンプルが早期終了した場合、どの確認処理で失敗したかをコードから判別できます。どちらも低コストな仕組みであり、スキャナよりリバースエンジニアを意識しています。

各ビルドを結び付けるもの

ここまでの要素を個別に見ても、共通ツールキットの証拠にはなりません。ローダーが同じ手法に収束することは珍しくないためです。このクラスタを単一のオペレーションと判断できるのは、別々にビルドされ、異なる保護が施され、無関係なペイロードを配信するサンプル間で、表4のアーティファクトが「似ている」のではなく同一だからです。

t4
表4:個別にビルドされたサンプル間で、類似ではなく同一だったアーティファクト

4行目が最も強い証拠です。5,566バイトのリソースは、含まれる4つのアセンブリのどの型とも一致しない、ランダムに見える同じ名前で格納されています。一見するとプロテクターのメタデータのようですが、実際には孤立したWinFormsデザイナーリソースであり、共有ソースリポジトリまたはジェネレータ由来のビルド環境フィンガープリントとして機能しています。アセンブリ名、難読化方式、対象アーキテクチャがキャンペーンごとに異なる一方で、42スロットの構成、鍵インデックスのoff-by-oneエラー、この同一の残存リソースという癖を共有しています。これらのバイナリが、1つの基盤ツールキットから生成されたことを裏付ける特徴です。

検出とハンティングの指針

SHADOW-WATER-84ではビルドごとにペイロードが変わりますが、配信ツールキットは変わりません。そのため、以下の手法は特定ペイロードのハッシュやインフラではなく、ローダーの挙動を対象としています。ペイロードが変わっても有効な検出観点を、おおむねシグナル対ノイズ比が高い順に並べています。

スリープ定数

.NET ILに即値「19004」が現れることを検出するルール、または起動直後に18,900〜19,100ミリ秒待機し、その後リソースを読み取ってアセンブリをリフレクティブロードする挙動を検出するルールが有効です。

CMSTPプロファイル

.inf拡張子のファイル内で、「This section contains additional comments to increase file size」という文言、または「CorpVPN」というサービス名のいずれかを照合します。特に、一時ディレクトリへ書き込まれた後、「cmstp.exe」が自動インストールスイッチ付きで読み込む場合は有力です。2つの文字列を組み合わせると、さらに確度が高まります。どちらも正規の用途で競合するシグナルはほぼありません。

PowerShellコマンドラインを格納するRun値

レジストリのRun値に実行ファイルのパスではなく、ユーザの一時ディレクトリ内のスクリプトを指す完全な「powershell.exe」コマンドが入っているかを確認します。さらに、ローミングアプリケーションデータディレクトリ内に、直近で実行されたバイナリの隠し、システム、読み取り専用コピーがあれば、確度が高まります。

ランチャースクリプトの構造

一時ディレクトリ内のPowerShellスクリプトについて、実行文が間接的な呼び出し演算子だけである、文字列を連結した[char]キャストと10進配列から組み立てている、新しいGUIDを未使用の変数へ代入している、という特徴を確認します。2つが揃うだけでも異例です。Run値から参照される15行のスクリプトに3つすべてがあれば、決定的なシグナルになります。

実体がPEファイルであるビットマップリソース

エントロピーは分かりやすい一次選別方法ですが、見た目ほど強力ではありません。デコード後のピクセルから赤、緑、青の各チャネルを測定すると、SHADOW-WATER-84の6つの搬送用画像は1バイトあたり4.76〜5.83ビットでした。同じおとりに含まれる正規のアイコンは4.11です。3分の2ビット程度の差だけでしきい値を決めるのは困難です。また、デコード後のピクセルではなく保存されたリソースを測ると、内容にかかわらずPNG搬送用画像はすべて8近くになります。

より低コストな検査で、誤検出なく搬送用画像の半数を検出できます。マネージドアセンブリ内のBitmapリソースを列優先順で走査し、各ピクセルの赤、緑、青チャネルを出力します。先頭2バイトがMZシグネチャであり、かつ「e_lfanew」フィールドが有効なPEヘッダオフセットを指すかを確認します。正規画像が両条件を満たすことはありません。第1段階の3つの搬送用画像は暗号化されていないため、この方法ですべて検出できます。

第2段階の搬送用画像は、この方法では見つかりません。クロップ、4チャネル化、長さプレフィックス付与、暗号化が行われ、先頭バイトはシグネチャではなく長さフィールドになっているためです。こちらでは、長さプレフィックス自体が特徴になります。先頭ピクセルをリトルエンディアン整数として読み取り、残りのピクセルデータに収まる妥当なアセンブリサイズかを確認します。2つの検査を組み合わせれば、6つすべてをカバーできます。エントロピーは、どのリソースを詳細に走査するかの判断に使い、悪意の判定そのものには使わないでください。

外部プロセスからのブラウザElevatorインスタンス化

Chrome、Chrome Beta、Edge、Brave、Avast Secure BrowserのElevator COMオブジェクトを、対応するブラウザ以外のプロセスが作成する挙動を検出します。この観点は本オペレーション以外にも適用でき、無関係なマルウェアファミリによるApp-Bound Encryption回避も検出できます。

静的なペイロード抽出

GraftLoaderのサンプルを保有するインシデント対応担当者は、図15の処理と表3の鍵を使い、動的解析なしでペイロードを復元できます。マネージドリソースを列挙し、短いランダムトークンを名前に持つバイト配列を取り出し、コンストラクタから復元した鍵を使って処理を実行します。サンプルを動作させずに最終ペイロードを取得できます。

まとめ

INFは一時ディレクトリに置かれるテキストファイルです。ランチャーもテキストファイルであり、エンドポイントエージェントがすでに監視しているレジストリ値から参照されます。スリープ定数はマネージドIL内の平文の即値です。LXBASEのインターフェースオフセットも、辞書初期化処理内の定数です。ファイルを読むだけのスキャナには隠れていても、これらの情報自体が見えなくなっているわけではありません。

ローダー・アズ・ア・サービスという見方は分析上の解釈であり、直接測定できた事実ではありません。確認できたのは、1つのツールキット、3つのビルド、3つの無関係なペイロードです。1人の攻撃者が3つのキャンペーンを運用している可能性も、流出したビルダーを使っている可能性もあります。執筆時点では、マーケットプレイスでの掲載、価格、キャンペーンごとに分離されたインフラは確認しておらず、設定済みのC&Cサーバを持つサンプルも3つのうち1つだけです。

どの解釈でも、非対称性は変わりません。このツールキットの所有者は、開発リソースを配信部分に集中させています。ビルドごとにペイロードは変わりますが、ローダーは変わりません。

SHADOW-WATER-084とOperation LoremDropからは、今後の展開も読み取れます。追加ペイロードのダウンローダーと設定可能な偽ダイアログがすべてのビルドにすでに組み込まれ、スイッチだけがオフになっています。新しいコードは必要なく、設定値を変えるだけで有効化できます。いずれ誰かがスイッチを入れるでしょう。

TrendAI Vision One™によるプロアクティブセキュリティ

TrendAI Vision One™は、サイバーリスクエクスポージャ管理、セキュリティ運用、堅牢な多層防御を一元化する、業界をリードするAIサイバーセキュリティプラットフォームです。

TrendAI Vision One™ Threat Intelligence Hub

TrendAI Vision One™ Threat Intelligence Hubは、新たな脅威と攻撃者に関する最新の知見、TrendAI™ Researchによる独自の戦略レポート、TrendAI Vision One™プラットフォーム内のTrendAI Vision One™ Threat Intelligence Feedを提供します。

新たな脅威:

GraftLoader Loader-as-a-Service Delivers Remcos and LXBASE(GraftLoaderのローダー・アズ・ア・サービスがRemcosとLXBASEを配信)

攻撃者:

SHADOW-WATER-084

TrendAI Vision One™ Intelligence Reports(IoCスイーピング):

GraftLoader Loader-as-a-Service Delivers Remcos and LXBASE(GraftLoaderのローダー・アズ・ア・サービスがRemcosとLXBASEを配信)

TrendAI Vision One™のユーザは、この活動に関連するインジケータを取得し、自組織の環境を遡及的にスイープできます。

ハンティングクエリ

以下は、TrendAI Vision One™ Search Appで利用できる出発点です。ファイルハッシュではなく、前述した持続性のある挙動を対象としており、必要に応じて調整できます。

// Run value data that is a PowerShell command line
eventSubId: TELEMETRY_REGISTRY_SET AND
registryRoot: HKEY_CURRENT_USER AND
registryKey: /CurrentVersion\\Run/ AND
registryValue: /powershell.*\.ps1/​

// cmstp.exe auto install against an INF in a temp directory
processFilePath: /cmstp\.exe/ AND
processCmd: /\/au/ AND
processCmd: /\\(Temp|temp)\\/​

// Defender exclusion added for a user-writable path
processCmd: /Add-MpPreference/ AND
processCmd: /-ExclusionPath/ AND
processCmd: /(AppData|Temp|Downloads)/​

// Hollowing targets spawned by a non-developer parent
processFilePath: /(RegSvcs|MSBuild|vbc)\.exe/ AND
NOT parentFilePath: /(devenv|msbuild|dotnet|cmd|powershell)\.exe/

日本語訳:

// Run値のデータがPowerShellコマンドライン
eventSubId: TELEMETRY_REGISTRY_SET AND
registryRoot: HKEY_CURRENT_USER AND
registryKey: /CurrentVersion\\Run/ AND
registryValue: /powershell.*\.ps1/​

// 一時ディレクトリ内のINFを指定してcmstp.exeを自動インストール実行
processFilePath: /cmstp\.exe/ AND
processCmd: /\/au/ AND
processCmd: /\\(Temp|temp)\\/​

// ユーザが書き込めるパスをDefenderの除外対象へ追加
processCmd: /Add-MpPreference/ AND
processCmd: /-ExclusionPath/ AND
processCmd: /(AppData|Temp|Downloads)/​

// 開発ツール以外の親プロセスがホローイング対象を起動
processFilePath: /(RegSvcs|MSBuild|vbc)\.exe/ AND
NOT parentFilePath: /(devenv|msbuild|dotnet|cmd|powershell)\.exe/

Threat Insightsの利用権限が有効なTrendAI Vision One™ユーザは、さらに多くのハンティングクエリを利用できます。

TrendAI Vision One™ Threat Insights

進化する脅威に先手を打つため、TrendAI™のユーザはTrendAI Vision One™ Threat Insightsを利用できます。新たな脅威や攻撃者について、TrendAI™ Researchによる最新の調査結果を提供する機能です。この活動に関するThreat Insightsの対象には、SHADOW-WATER-84の新たな脅威に関する解説と、関連するOperation LoremDropのインテリジェンスレポートが含まれます。

TrendAI Vision One™は、サイバーリスクエクスポージャ管理、セキュリティ運用、堅牢な多層防御を一元化する、唯一のAI搭載エンタープライズサイバーセキュリティプラットフォームです。この包括的なアプローチにより、脅威の予測と防止を支援し、デジタル資産全体でプロアクティブなセキュリティ成果を加速します。数十年にわたるサイバーセキュリティ分野での実績と、真にプロアクティブなサイバーセキュリティAIであるTrendAI™ Cybertronを基盤とし、ランサムウェアリスクを92%削減、検出時間を99%短縮するという実績を上げています。

MITRE ATT&CKマッピング

29行のうち9行は、GraftLoaderの保護を解除した後にだけ確認できるため、その旨を表内に記載しています。残りは配信時のサンプルから観測できます。

t5
表5:SHADOW-WATER-084のチェーンと3つのペイロードにおけるMITRE ATT&CKの対応

侵入の痕跡(IoC: Indicators Of Compromise)

ローダーの各ステージに付けた名前は、ディスク上のファイル名ではなく、メタデータから読み取ったアセンブリ名です。これらのステージはディスクへ書き込まれないためです。ランチャースクリプトのハッシュは永続的なインジケータではなく、独自の解析で得た値です。ジェネレータは配置のたびに変数名と対象ファイル名をランダム化します。そのため、ハッシュではなくスクリプトの構造をハンティングすることを推奨します。

各キャンペーンに関する侵入の痕跡は、こちらをご参照ください。

参考記事

Inside SHADOW-WATER-084: A Steganographic Loader-as-a-Service Delivering Remcos, LXBASE, and More

By : Ahmed Mohamed Ibrahim , Ashish Verma , Deep Patel

翻訳:与那城 務(Platform Marketing, Trend Micro™ Research)