2024年4月25日

古いワインのコルクを抜く: 2017年のゼロデイ+『Unholy Alliance』のCobalt Strikeローダー

要旨
  • Deep Instinct の脅威ラボ は、ウクライナに対する標的型攻撃の疑いを発見
  • この作戦は既知の脅威アクターに起因するものではなかった
  • この作戦はCobalt Strike Beaconのカスタムローダーを使用
  • Deep Instinctは攻撃の全段階を検知
  • この作戦は最初のベクターとしてCVE-2017-8570を使用
キャンペーンの概要

fig1-campaign-attack-flow.png
図1:キャンペーンの概要

Deep Instinct脅威ラボは、2023年末にウクライナからVirusTotalにアップロードされた悪意のあるPPSXファイルを観測しました:

fig2_vt_upload.png
図2:VTアップロード情報

ファイル名から、このファイルはSignalアプリケーションを介して共有されたことがわかりますが、必ずしもこのファイルがアプリケーションを介して被害者に送信されたとは限りません。

PPSX(PowerPoint Slideshow)ファイルは、戦車用の地雷除去ブレード(MCB)に関する米陸軍の古い取扱説明書のようです。

fig3_ppsx_image.png
図3:PPSXの内容

PPSXファイルには、外部OLEオブジェクトへのリモートリレーションが含まれています:

fig4_remote_relationship.png
図4:リモートとの関係

httpsのURLの前に 「script: 」という接頭辞が使用されていることから、 CVE-2017-8570が使用されていることがわかりますが、これはより既知のCVE-2017-0199に対するバイパスです。

“widget_iframe.6177666167737264687466726a6834.html”という名前のリモートスクリプトは、CloudFlareによって保護されているドメイン“weavesilk[.]space”でホストされていました。しかし、私たちの分析中に、私たちはロシアのVPSプロバイダであるドメインの背後にある本当のホスティング場所を特定することに成功しました:

fig5_real_ip.png
図5:実際のドメインIP

スクリプトレットのコンテンツは高度に難読化されています:

fig6_scriplet.png
図6:難読化されたスクリプトの内容

難読化の解読後:

fig7-scriptlet_de-obfuscated.jse.png
図7:難読化されたスクリプト

第2段階のドロッパーは、Windowsのcscript.exeを介して実行されるJavaScriptコードを含むHTMLファイルです。

これは、持続化、デコード、および埋め込まれたペイロードのディスクへの保存を担当します。

キーポイント
  • Cisco AnyConnect VPN ファイルとして偽装されたペイロードをパスの下にドロップします:
    • C:\Users\<Username>\AppData\Roaming\Cisco\AnyConnect\vpn.sessings
  • 以下のレジストリキーを変更することで永続化を得ます:
    • HKCU\Software\Microsoft\Command Processor\AutoRun: start regsvr32 /s C:\<path>\vpn.sessings - これでcmd.exeが実行されるたびにマルウェアが実行されます。
    • HKCU\Software\Microsoft\Windows\CurrentVirsion\Run: cmd /Q /C whoami - これは実際の永続化コードです。システムが起動するたびにローダーをトリガーするwhoamiを実行しています。

この永続化手法は異常であり、ペイロードが不必要に複数回実行される可能性があります。しかし、一見良性に見えるため、永続化がインシデントレスポンスなどで発見されにくく、高特権ユーザーまたはプロセスがcmd.exeを実行した場合に特権昇格を引き起こす可能性もあります。

DLL ペイロードの解析

サンプルには、Cobalt Strikeビーコンをメモリにロードし、C&Cサーバーからの指示を待つvpn.sessingsというローダー/パッカーダイナミックリンクライブラリ(DLL)が含まれています。

Cobalt Strikeはすでに何度も 分析 されているので、ここでの詳細説明は省きますが、ローダーには興味深い動作がいくつか含まれていました。

ローダーの分析

サンプルはRegsvr32を使って実行されるDLLです。

重要なロジックのほとんどはDllRegisterServerの中にあります。

エクスポートされたメソッドには、不思議なことに文書化されていない低レベルのWinAPI呼び出しの名前(Nt、Zw、Rt)がありますが、ほとんどは空で未使用でした。.

fig8-loader_export_table.jse.png
図8:ローダー・エクスポート・テーブル

ローダーは親プロセスの終了を試み(アンチデバッグ)、実行中のプロセスを繰り返し実行して、自分自身を探します。その後、親プロセスの終了を試みます:

fig9-terminate_parent.jse.png
図9:親の終了

“コマンド・プロセッサー”レジストリ・キーから実行されると、「存在しないプロセス」の下で実行されることになります。しかし、デバッグ中はデバッガーと一緒に終了するため、解析が遅くなり、リサーチャーを困らせることになります。

figX-annoyed-researcher.png

実行のストール(サンドボックス回避の可能性)

ローダーは、低レベルのNtDelayExecution WinAPIコールを動的にロードし、明確な機能的理由なしに20秒間ストールします。

fig10-delay_execution.jse.png
図10:実行の遅延

考えられる説明としては、デバッグを遅らせるか、サンドボックスを回避するかのいずれかです。

これは、予防検知的な目的で使われているサンドボックスのエミュレーションでは大量のマルウェアに対処する必要があり、短時間(2~5分)しか実行されていないという事実を悪用している可能性があります。

ほとんどのソリューションは長いスリープ/遅延をスキップしますが、ここでは20回実行され、それぞれ1秒ずつ実行されているので、おそらく自動スキップを回避しようとしながら、実行をわずかに遅延させています。

1秒の遅延は短いように思えますが、これらのコールは通常モニタリングのためにフックされるため、各コールに時間がかかり、エミュレーション・ウィンドウから重要な指標が除外される可能性があります。

CPUIDのチェック(アンチVM)

ローダーはインラインASM命令を使用してCPUIDを実行し、マルウェアが仮想マシンで実行されているかどうかを判断します。

CPUID x86命令は、VMで実行された場合、の値を返します(2^31ビットが1に設定され、0x80000000を超える符号付き値は負になります)。

以下の命令では、CPUIDが正の数を返せばTrueを返すことがわかります:

fig11-check_vm.jse.png
図11:マルウェアがVM内部で実行されたかどうかをチェック

この条件がFalseの場合はシンプルに終了しますが、興味深いのは、他の場所でもこのチェックを実行していることです。これには、DllEntryPointDllRegisterServerの前に実行される)でのチェックが含まれていて、後に動作の一部を変更できるグローバル変数が割り当てられています。

NTDLLのアンフック(アンチAM)

ダイナミックリンクライブラリntdll.dllは、ユーザーモードとカーネルモード間で最も下位レベルのWindows API呼び出しインターフェースです。

そのため、マルウェア対策ベンダーは通常、悪意のある動作を監視するために、さまざまな呼び出しの内部にフックを配置します。マルウェアが検知を避けたい場合、これらの防御を回避する方法を見つける必要があります。

発想はいたってシンプルで、メモリ上にあらかじめロードされたntdll.dllは、様々なAPIコール内にインライン・フックを含んでいるので、マルウェアは検知を回避するために、このフックをバイパスするか上書きする必要があります。

以下のスクリーンショットでは、ディスクからのntdll.dllのメモリマッピングと、実行中のプロセスのメモリからのntdll.dllロードされたモジュールのフェッチを見ることができます:

fig12-loading_both_dlls.jse.png
図12:両方のntdllのロード

これらは:

  • DiskNTDLL : ntdll.dllのディスクからのコピー用
  • MemNTDLL : メモリからロードされたモジュール用

これは明らかなフック解除のように見えますが、残りのコードは圧倒的に複雑で、私たちのテストではなぜかフックが解除されませんでした。

ここでの解析には時間がかかり、さらに深く掘り下げた結果、マルウェア作者が解析を遅らせるために行った追加のトリックのいくつかを発見しました。

これらの遅延テクニックをいくつかのポイントに分けてみました:

1. 複雑すぎる肥大化コード

正確な目的を理解するのは難しいですが、以下のコード例に見られるように、脅威アナリストの時間を浪費させるために意図的に行われたものと思われます:

fig13-nonsense_code.jse.png
図13:無意味なコード

このコードは、ntdll.dll のフックを解除する関数から呼び出され、変数 lp_text_base_DiskNTDLL/MemNTDLL は、メモリ上の両方の DLL の LONG_PTR アドレスです。

MemNTDLLは常に、ASLRによる多少の変動はあるものの、最も高いユーザースペースモジュールアドレスである0x77000000(32ビット)上でオペレーティングシステムによってロードされることを望んでいるため、lp_text_base_DiskNTDLL > lp_text_base_MemNTDLLという条件がTrueになることはありません。

少なくともここにあるコンテキストからは。

この関数は、フック解除とは関係ない、肥大化したコードでいっぱいの他の場所からも呼び出されています。

2. 隠れた追加VMチェック(前述の通り)

fig14-DllEntryPoint_CPUID.jse.png
図14:DllEntryPointチェックVM

チェックがFlaseの場合、フックは解除されず、代わりに実行フローが迂回されます。

さらに肥大化したコード:

fig15-unhook_and_bloat_code.jse.png
図15:フックの解除とコードの肥大化

マルウェア開発者は、分析を遅らせるためにダミーの動作を作成することが知られています。

これは効果的なトリックであり、それを知っていれば、目的が明確でない過度に複雑なコード、特に通常の状態では実行されないようなコードは無視して、先に進んだ方が得策です。

3. 手動オフセットを持つ構造体

作成者はまた、再構築をより困難にするために、様々なPE構造体を手動でロードする際に任意のオフセットを使用しています:

fig16-arbitrary_offsets.jse.png
図16:任意のオフセット

再構築後、(すべての関数実装を含む).textセクションを探し、パーミッションをPAGE_EXECUTE_READWRITEに変更し、オリジナルのntdll.dll:IOCで上書きされるように送信していることがわかります:

fig17-after_reconstruction.jse.png
図 17: 再構築後

ペイロードの復号化(Cobalt Strike)ネットワーク

標準的な復号ルーチンを使用 復号:

  • base_data/key_seedをハッシュ
  • ハッシュから鍵を導出
  • 復号:

fig18-decrypt_payload.jse.png
図 18: ペイロードの復号化 (Beacon)

自己DLLによる Cobalt Strikeのインジェクション

これは、ペイロードを隠すこと、ファイルをディスクに保存しないこと(ファイルレス)、リモート・インジェクションのヒューリスティックを回避すること、そしていつものように分析を複雑にすることを意図しています。

手順は以下の通りです::

  • OpenProcess
  • その内部でAllocateMemory
  • ペイロードでWriteProcessMemory
  • 自身の内部でCreateRemoteThread
  • そのスレッドが終了するまでWaitForSingleObject

fig19-self_dll_injection.jse.png
図 19: 自己 DLL インジェクション

抽出されたCobalt Strikeコンフィグ:

Cobalt Strikeコンフィグには、C&Cとの暗号化通信のための非対称鍵交換用の公開鍵が含まれています。

licence_id : 0 は、これがクラックされたバージョンの Cobalt Strike であることを示しています。

fig20-ExtractedConfig.png
図20:抽出されたコンフィグ

Cobalt Beaconは、C&Cアドレス/ドメイン名、URI、公開鍵、そして注入先のプロセス(dllhost.exe)まで詳細に設定されています。

C&Cサーバーはpetapixel[.]fun(人気の写真サイトを装っている)にあり、Cloudflareの背後に隠されています。

ポーランドのワルシャワで登録されていることは言及されています。

fig21-location.png
図21:登録場所

結論

Deep Instinct脅威ラボでは、これらの攻撃を既知の攻撃グループに結びつけることも、これがレッドチームの演習の一部であった可能性を排除することもできませんでした。

証跡によると、このサンプルはウクライナからアップロードされ、セカンドステージ(weavesilk[.]space)はロシアのVPSプロバイダの下でホストされ登録され、CobaltビーコンのC&C(petapixel[.]fun)はポーランドのワルシャワで登録されていました。

バイナリ(vpn.sessings)には、分析を遅らせ、 サイバーセキュリティ・ソリューションをバイパスするための様々なテクニックを備えたCobalt Strike Beacon用のカスタム・ローダー/パッカーが含まれています。テクニックのほとんどは新しいものではないですが、フィンガープリントとして使用できるほどユニークなものである可能性があります。

Cobalt Strike Beacon自体は、レッドチームによるコンピュータ・セキュリティ評価のために設計されたプロフェッショナルなペン・テスト・ツールですが、これはリークされたクラック版であるため、正当なユーザへと紐づけることはできません。

Cobaltは、機密データの窃取、権限の昇格、ネットワーク内の他のコンピューターへの伝播、ツールのダウンロードなど、幅広い機能を備えた高度なツールです。さらなる手がかりがなければ、攻撃の正確な目的を理解することは難しいと考えます。

この攻撃の初期の誘い文句には軍事関連のコンテンツが含まれており、軍関係者をターゲットにしていることがうかがえます。しかし、ドメイン名weavesilk[.]spaceとpetapixel[.]funは、無名のジェネレーティブ・アート・サイト(http://weavesilk.com)と人気の写真サイト(https://petapixel.com)に偽装されています。これらは無関係であり、攻撃者がなぜ軍関係者を騙すためにこれらを特別に使用したのか少し不可解です。

発見された日の時点で、このローダーはほとんどのエンジンで検知されませんでしたが、Deep Instinctはゼロデイ(初見)でこれを阻止することができています。

MITRE

タクティクス

テクニック

概要

オブザーバブル

初期アクセス

T1566

フィッシング

RELSエクスプロイトを含むPowerPoint signal-2023-12-20-160512.ppsx

実行

T1059.007

コマンドとスクリプトのインタープリター: JavaScript

難読化されたJavaScriptを含むwidget_iframe.6177666167737264687466726a6834.html

持続性

T1547.001

レジストリの実行キー

HKCU\Software\Microsoft\Windows\CurrentVirsion\Run: cmd /Q /C whoami

持続性

イベントトリガー実行

HKCU\Software\Microsoft\Command Processor\AutoRun: start regsvr32 /s C:\<path>\vpn.sessings

MITREに新しいサブテクニックを提出

防御的回避

T1218.010

システムバイナリプロキシ実行: Regsvr32

start regsvr32 /s C:\<path>\vpn.sessings

防御的回避

T1055

プロセス インジェクション

obalt Strike Beacon を解凍後、古典的な CreateRemoteThread メソッドで自己注入を実行

防御的回避

T1027.002

ソフトウェアの梱包

CryptDecrypt を使って Cobalt Beacon をアンパック

ディスカバリー

T1057

プロセス ディスカバリー

アンチデバッグのため、実行中のプロセスを繰り返し、親プロセスを終了

防御的回避

T1497

仮想化/サンドボックス回避回避する可能性がある

NtDelayExecution を実行し、時間的制約を悪用して自動サンドボックス・エミュレーションを回避する可能性がある

コマンド&コントロール

T1573

暗号化チャンネル

443ポートのHTTPSを使用したC&C通信

IOCs

weavesilk[.]space
109.107.178[.]241
petapixel[.]fun

SHA256

Description

b0b762106c22e44f7acaa3177baabd64ea28990d16672e1f902b53f49b2027c4

signal-2023-12-20-160512.ppsx

0bc0e9410f4a9703ff0b5af7ec9383a1cc929572ade09fbd2c69ed2ae1486939

widget_iframe.617766616773726468746672726a6834.html

976f57442452cd54cada011c565ada0c01f5b1460e31ee6cea330d210d3e8f50

vpn.sessings (cobalt strike loader DLL)