悪意のあるVIB(E) Part-1:ESXiハイパーバイザー内の新しいマルウェアの持続性に関する調査
Mandiant
※この投稿は米国時間 2022 年 9 月 29 日に、Google Cloud blog に投稿されたものの抄訳です。
EDR(エンドポイント検出・対応)ソリューションがWindowsシステムにおけるマルウェア検知の有効性を高めるにつれ、国家の支援を背景とする一部の攻撃者は、ネットワーク機器、SANアレイ、VMware ESXiサーバなど、一般的にEDRがサポートされていないシステムに対するマルウェアの開発・配備にシフトしています。
今年初め、Mandiantは、VMware ESXi、Linux vCenterサーバ、およびWindows仮想マシンに影響を与える新たなマルウェアエコシステムを特定しました。攻撃者は、これによって以下を行えるようになります。
1. ハイパーバイザーへの持続的な管理アクセスを保持
2. ゲストVMに転送されるコマンドをハイパーバイザーに送信し、実行
3. ESXiハイパーバイザとその配下で動作するゲストマシン間でファイルを転送
4. ハイパーバイザー上のログサービスを改ざん
5. 同一ハイパーバイザー上で動作しているゲストマシンから別のゲストマシンへの任意のコマンドを実行
このマルウェアエコシステムは、Mandiantがある侵入調査の際に、VMware ESXiハイパーバイザーをホストとするWindows仮想マシン上で正規のVMware Toolsプロセスであるvmtoolsd.exeをソースとする攻撃者のコマンドを確認したことから、最初に検出されました。Mandiantは、ESXiハイパーバイザのブートプロファイルを分析し、攻撃者が悪意のあるvSphere Installation Bundles(以下、VIB)を利用して、ESXiハイパーバイザに複数のバックドアをインストールするという、これまでにない手法を特定しました。これらのバックドアを「VIRTUALPITA」および「VIRTUALPIE」と呼んでいます(図1)。
図1:ESXiの攻撃経路のイメージ
ここで重要なのは、これが外部からのリモートコード実行の脆弱性ではなく、攻撃者がマルウェアを展開する前に、ESXiハイパーバイザーの管理者レベルの特権を必要とするという点です。この記事を書いている時点では、ゼロデイ脆弱性が悪意のあるVIBの初期アクセスまたは展開に使用されたという証拠はありません。
ESXi環境に悪意のあるVIBや異常なVIBが現在インストールされているかどうかを手動で検出する方法の詳細については、当社のハードニングに関するブログポストに概略を説明しています。またVMwareは、vSphereの保護に関する追加情報を公開しています。
vSphere Installation Bundles (VIB)
Mandiantは、悪意のあるvSphere Installation Bundles(VIB)を介してインストールされる2つの新しいマルウェアファミリーを特定し、VIRTUALPITAおよびVIRTUALPIEと名付けました。
VMware VIBは、ソフトウェアの配布と仮想システムの管理を容易にするために設計されたファイルの集合体です。ESXiはインメモリファイルシステムを利用しているため、ファイルの編集内容は再起動しても保存されません。VIB パッケージを使用して、スタートアップ タスク、カスタム ファイアウォール ルールを作成したり、ESXi マシンの再起動時にカスタム バイナリを展開したりすることができます。これらのパッケージは、一般的に管理者がアップデートを展開し、システムを維持するために利用されますが、この攻撃者は、ESXiハイパーバイザ間でアクセスを維持するための永続化メカニズムとしてパッケージを活用していることが確認されました。
VIBは、次の3つの要素に分解することができます。
- XMLディスクリプタファイル
- VIB ”ペイロード” (.vgz アーカイブ)
- 署名ファイル - VIB のホストのアクセプタンスレベルを確認するために使用されるデジタル署名
XML 記述子ファイルは、以下への参照を含む設定:
- インストールされるペイロード
- VIB メタデータ(名前、インストール日など
- VIB に属する署名ファイル
VIBペイロードは.vgzアーカイブで、VIBを通じてESXiマシン上に作成されるディレクトリとファイルが含まれています。これらのファイルは、VIBがロードされると、ブート時に実行するように呼び出すことができます。
署名ファイルは、VIBのホストのアクセプタンスレベルを確認するために使用されます。アクセプタンスレベルは、VMware が使用するデジタル署名システムで、VIB が公開される前に VMware またはパートナーによって行われたテストを指定するために使用されます。アクセプタンスレベルは、ホスト、イメージプロファイル、および個々の VIB に対して設定されます。4つのアクセプタンスレベルとXMLディスクリプタのショートネームを以下に示します。
- VMWareCertified (certified)
- VMwareAccepted (accepted)
- PartnerSupported (partner)
- CommunitySupported (community)
VMwareのドキュメントによると、VIBをESXiホストにインストールするために必要なデフォルトの最低限のアクセプタンスレベルは、PartnerSupportedです。このアクセプタンスレベルは、VMwareが信頼するパートナーによってVIBが公開されていることを示します。これはデフォルトのアクセプタンスレベルですが、ESXiの管理アカウントによって手動で変更することができます。VIB のインストールに使用されるコマンド esxcli software vib install は、通常、最低アクセプタンスレベル未満のインストールを許可しませんが、-force フラグを使用すると、VIB のインストール時にシステムのアクセプタンスレベル要件をすべて無視することができます。
観測された悪意のあるVIBには、PartnerSupportedというラベルが貼られていました。Mandiantが署名ファイルを確認したところ、それらは空であり、攻撃者がXMLディスクリプタファイルを修正し、アクセプタンスレベルのフィールドをCommunityからPartnerに変更したことが判明しました。CommunitySupportedのアクセプタンスレベルは、VIBがサードパーティによって作成されたことを示し、VMwareやその信頼できるパートナーによってレビューも署名もされていないことを意味します。これは、攻撃者が、これらの VIB ファイルが CommunitySupported VIB の要件しか満たしていないにもかかわらず、PartnerSupported として偽装していることを示しています。また、この VIB は、VMware のパートナー プログラム以外の個人または企業によって作成され、VMware が承認したテスト プログラムを通過していないことも示しています。Figure 2 は、確認された修正された XML ディスクリプタ・ファイルの抜粋を含んでいます。
図2:修正されたディスクリプタXML
攻撃者によって ディスクリプタXML のアクセプタンスレベルフィールドが変更さ れたものの、ESXi システムでは、最低限設定されたアクセプタンスレベル以下では、改ざんされた VIB ファイルをインストールすることができませんでした。これを回避するため、攻撃者は --force フラグを悪用して、悪意のある CommunitySupported VIB をインストールしました。
テストでは、XMLディスクリプタファイルの変更されたフィールドが、VIBのリストと検証に使用されるコマンドの出力で行われた変更を反映していることが確認されました。これには、<acceptance-level>フィールドの変更が含まれ、esxcli software vib listコマンドに、インストールされたVIBの不正なアクセプタンスレベルを表示させるように細工されています。VMware コマンドである esxcli software vib signature verify は、インストールされた VIB パッケージの署名を検証し、次のフィールドを表示します。
- VIB名
- バージョン
- ベンダー
- アクセプタンスレベル
- VIBの署名照明の結果
Mandiant は、このコマンドがこれらのアクセプタンスレベルが改ざんされた場合に検知し、悪意のある VIB を特定することを確認しました。このコマンドは、XMLディスクリプタファイルによって指定されたアクセプタンスレベルを表示しますが、Signature Verification(署名証明)列は、署名ファイルがそれぞれのディスクリプタXMLと一致しなかった場合に明示されます。署名が確認できない場合、[Signature Verification]列には「Signature Not Available」という値が表示されます。ホストが古いESXiバージョンからアップグレードされた可能性があります。この例は、図3に示されています。
図 3:esxcli software vib signature verify で確認される VIB アクセプタンスレベルの偽造の例
VIRTUALPITA (VMware ESXi)
VIRTUALPITAは、VMware ESXiサーバ上のハードコードされたポート番号にリスナーを作成する64ビットパッシブバックドアです。このバックドアは、しばしばVMwareのサービス名とポートを利用して、正当なサービスに見せかけます。任意のコマンドの実行、ファイルのアップロードとダウンロード、およびvmsyslogdの起動と停止をサポートしています。また、任意のコマンドを実行する際に、環境変数HISTFILEを0に設定し、マシン上で発生したアクティビティをさらに隠蔽します。このマルウェアの亜種は、仮想マシン通信インタフェース(VMCI)をリッスンし、この活動をファイルsysclogに記録することが確認されました。
VIRTUALPIE (VMware ESXi)
VIRTUALPIEはPythonで書かれたライトウェイトなバックドアで、VMware ESXiサーバ上のハードコードされたポートにデーモン化されたIPv6リスナーを生成します。任意のコマンドライン実行、ファイル転送機能、リバースシェル機能をサポートしています。通信はカスタムプロトコルを使用し、RC4で暗号化されます。
lsu-lsi-lsi-mrarpid-plugin という名前の最初の悪意のある VIB は、ペイロード lsu_lsi_.v05 (MD5: 2716c60c28cf7f7568f55ac33313468b) を参照しており、表 1 にあるように、以下の 3 つのファイルの詳細が含まれていました。
- /etc/rc.local.d/vmware_local.sh (MD5: bd6e38b6ff85ab02c1a4325e8af29ce4)
- /bin/rdt (MD5: 8e80b40b1298f022c7f3a96599806c43)
- /bin/vmsyslog.py (MD5: 61ab3f6401d60ec36cd3ac980a8deb75)
表1: Lsu-lsi-lsi-mrarpid-plugin Malicious VIB contents
2つ目の悪意のあるVIBであるata-pata-pdc20211は、ペイロードpayload1.v00 (MD5: 9ea86dccd5bbde47f8641b62a1eeff07) を参照しており、表2に示すように、その詳細は以下の2ファイルであることがわかります。
- /etc/rc.local.d/vmware_rhttpio.sh (MD5: 9d5cc1ee99ccb1ec4d20be1cee10173e)
- /usr/lib/vmware/weasel/consoleui/rhttpproxy-io (MD5: 2c28ec2d541f555b2838099ca849f965)
表2: Lsu-lsi-lsi-mrarpid-plugin Malicious VIB contents
VIRTUALPITA (LINUX)
Mandiantは、Linux vCenterシステム上のinit.dスタートアップサービスとして持続する、TCPポート7475を利用する2つのVIRTUALPITAサンプルを追加で発見しました。これらのバイナリは、自身を偽装するために、正規のバイナリであるksmdの名前を共有していました。KSMD (Kernel Same-Page Merging Daemon) は、通常、Linux上でメモリを節約する重複排除を担当しており、このポートで待機することはありません。サンプルは以下のディレクトリの下で見つかりました。
- /usr/libexec/setconf/ksmd (MD5: 744e2a4c1da48869776827d461c2b2ec)
- /usr/bin/ksmd (MD5: 93d50025b81d3dbcb2e25d15cae03428)
これらのバックドアからは、任意のコマンドの実行、ファイル転送機能、vmsyslogdの起動/停止が可能でした。
VIRTUALGATE (Windows)
感染したハイパーバイザーにホストされていたWindowsゲスト仮想マシンには、C:³³.exeにある固有のマルウェアサンプルも含まれていました。このマルウェアは、C言語で記述されたユーティリティ・プログラムで、ドロッパーとペイロードの2つの部分から構成されており、私たちはこれを「VIRTUALGATE」と呼んでいます。メモリのみのドロッパーは、VMwareの仮想マシン通信インタフェース(VMCI)ソケットを使用して、ハイパーバイザーのホストからゲスト仮想マシン上、または同じホスト上のゲスト仮想マシン間でコマンドを実行する第2段階のDLLペイロードの暗号化を解除しています。
vmtoolsd.exeによるコマンド実行
攻撃者の活動中のESXiハイパーバイザーを検証したところ、攻撃者はプロセス/bin/rdt(VIRTUALPITA)を通じてゲストマシンに対してコマンドを実行していることが確認されました。親プロセスである /bin/rdt は bash シェルを生成し、図 4 に示すように、ターゲットとなるゲストマシンと実行するコマンドを指定した python スクリプトを呼び出しています。
図4:攻撃者がESXiハイパーバイザー上で実行したコマンド
-> /bin/rdt -i
....-> sh -c /bin/sh
........-> /bin/sh
...........-> python e.py 127.0.0.1 vpxuser <password> <target guest machine> C:\Windows\system32\cmd.exe /c dir /od /s /a c:\ > C:\Windows\Temp\TS_<REDACTED>.tmp 2>nul
e.pyに引数として渡されたコマンドは、対象のWindowsゲストマシンでも実行され、vmtoolsd.exeの下で子プロセスとして実行されていることが確認されました。この実行チェーンは、図5に示すとおりです。親バイナリである/bin/rdtはディスク上に存在しませんでしたが、ESXiハイパーバイザーのプロセスメモリをダンプすることで復元することができました。ゲストマシンにコマンドを送信するPythonスクリプトe.pyは復旧できませんでした。
図5:ESXiから渡されたコマンドを実行するvmtoolsd.exe
攻撃者がゲスト仮想マシン上でvmtoolsd.exeを介して実行したコマンドは、主にネイティブツールの「dir」と「makecab」を使用して、システムと接続されたファイル共有の両方でファイルの列挙と圧縮に重点を置いています。これらの編集されたコマンドのサンプルは、図6に示されています。
図6:攻撃者がゲスト仮想マシン上で利用したファイル列挙・圧縮コマンド
C:\Windows\system32\cmd.exe" /c dir /od /s /a s:\ > C:\Windows\Temp\ts_<REDACTED>.tmp 2>null
C:\Windows\System32\cmd.exe makecab /F C:\Windows\Temp\TS_<REDACTED>.txt /D compressiontype=lzx /D compressionmemory=21 /D maxdisksize=1024000000 /D diskdirectorytemplate=C:\Windows\Temp\ /D cabinetnametemplate=TS_<REDACTED>.cab
Mandiantはまた、攻撃者が認証情報の取得のために仮想化されたシステムを標的にしていることも確認しました。この攻撃者は、MiniDumpを使用してプロセスのメモリをダンプし、平文のクレデンシャルを検索していました。図7は、これらのコマンドの抜粋を示したものです。
図7:ゲストマシンでのクレデンシャルダンプリング
-- “ C:\Program Files\VMware\Vmware Tools\vmtoolsd.exe”
---- “C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe”
------ rundll32.exe C:\windows\System32\comsvcs.dll MiniDump <Process ID> C:\Windows\Temp\TS_<REDACTED>.tmp full
プロセスメモリがダンプされると、powershellスクリプトを使用して結果ファイルを解析し、平文のクレデンシャルを取得しました。図8は、クレデンシャル・ハーベスティングに使用されたスクリプトの内容を示しています。攻撃者は、KeyPassパスワードデータベース・ファイルも標的にしていました。
図8:PowerShellパスワード検索スクリプト
$b = New-Object System.IO.streamReader("C:\windows\Temp\<REDACTED>.tmp",[Text.Encoding]::UTF8)
$n = 0
while (($b1 =$b.ReadLine()) -ne $null)
{
if($b1 -like '*&password=*'){
$n++
Write-Host "YES $n"
Write-Host $b1
}
}
if($n -eq 0){Write-Host "NO!"}
$b.Dispose()
攻撃者は、ほとんどの活動の後、C: \WindowsTemp ディレクトリをクリアしましたが、わずかなミスがあり、トレースアーチファクトを残しました。図9に示すように、攻撃者はdir listの出力を.tmpファイルに送信しています。この攻撃者は、Windowsの構文(2>nul)ではなく、Linuxの構文(2>null)を使用してエラーを回避したため、すべてのエラーは、作業ディレクトリC: \WindowsSystem32null の null ファイルに転送されました。このファイルは、dirコマンドで列挙されたファイルのディレクトリパスが長すぎて表示できない場合のみ作成されます。
図9:WindowsコマンドのNullへの書き込み失敗エラー
C:\Windows\system32\cmd.exe" /c dir /od /s /a s:\ > C:\Windows\Temp\TS_<REDACTED>.tmp 2>null
アトリビューション
Mandiant は、この活動を UNC3886 として追跡を開始しました。この侵入の高度な標的型かつ巧妙な回避行動から、UNC3886 の動機はサイバースパイ関連であると思われます。さらに、UNC3886 には中国との関連性があると低信頼性で評価しています。Mandiant が実施する各調査には、Mandiant が対応する数千の調査で観測された活動を関連付けるために、当社のアドバンスト・プラクティス・チームのアナリストが参加しています。時には、侵入活動を既知のグループと直接関連付けるためのデータがないこともあります。このような場合、私たちは新しいUNCグループを作成し、観測された活動を追跡します。UNCグループは、関連するサイバー侵入活動のクラスターで、敵のインフラ、ツール、技術などの観察可能なアーティファクトを含みますが、APTやFINなどの分類を与えるにはまだ準備が整っていません。Mandiant が UNC グループをどのように使用しているかの詳細については、Mandiantのブログ「DebUNCing Attribution: Mandiantによる未分類の攻撃者の追跡方法」をご覧ください。
まとめ
UNC3886が使用した手法は、ESXiオペレーティングシステムとVMWareの仮想化プラットフォームをより深く理解する必要があると指摘しましたが、この調査で明らかになった情報を使用して、他のさまざまな攻撃者が同様の攻撃を開始することが予想されます。Mandiantは、ESXiおよびVMwareのインフラストラクチャ製品を使用している企業に対し、このブログ記事で説明したハードニングの手順に従って、ESXiホストの攻撃対象領域を最小限に抑えることを推奨しています。
MITRE ATT&CK テクニック
Collection
- T1560: Archive Collected Data
- T1560.001: Archive via Utility
Execution
- T1059: Command and Scripting Interpreter
- T1059.001: PowerShell
- T1059.003: Windows Command Shell
- T1059.004: Unix Shell
- T1059.006: Python
- T1129: Shared Modules
Command and Control
- T1105: Ingress Tool Transfer
- T1573.001: Symmetric Cryptography
Defense Evasion
- T1027: Obfuscated Files or Information
- T1070: Indicator Removal on Host
- T1070.003: Clear Command History
- T1070.004: File Deletion
- T1140: Deobfuscate/Decode Files or Information
- T1202: Indirect Command Execution
- T1218.011: Rundll32
- T1497: Virtualization/Sandbox Evasion
- T1497.001: System Checks
- T1620: Reflective Code Loading
Discovery
- T1016: System Network Configuration Discovery
- T1083: File and Directory Discovery
Lateral Movement
- T1021: Remote Services
- T1021.004: SSH
Credential Access
- T1003: OS Credential Dumping
- T1003.001: LSASS Memory
Persistence
- T1547: Boot or Logon Autostart Execution
侵害インジケーター(Indicators of Compromise)
Yara Detections
rule M_APT_VIRTUALPITA_1
{
meta:
author = "Mandiant"
md5 = "fe34b7c071d96dac498b72a4a07cb246"
description = "Finds opcodes to set a port to bind on 2233, encompassing the setsockopt(), htons(), and bind() from 40973d to 409791 in fe34b7c071d96dac498b72a4a07cb246"
strings:
$x = {8b ?? ?? 4? b8 04 00 00 00 [0 - 4] ba 02 00 00 00 be 01 00 00 00 [0 - 2] e8 ?? ?? ?? ?? 89 4? ?? 83 7? ?? 00 79 [0 - 50] ba 10 00 00 00 [0 - 10] e8}
condition:
uint32(0) == 0x464c457f and all of them
}
rule M_APT_VIRTUALPITA_2
{
meta:
author = "Mandiant"
md5 = "fe34b7c071d96dac498b72a4a07cb246"
description = "Finds opcodes to decode and parse the recieved data in the socket buffer in fe34b7c071d96dac498b72a4a07cb246. Opcodes from 401a36 to 401adc"
strings:
$x = {85 c0 74 ?? c7 05 ?? ?? ?? ?? fb ff ff ff c7 8? ?? ?? ?? ?? 00 00 00 00 e9 ?? ?? ?? ?? 4? 8b 05 ?? ?? ?? ?? 4? 83 c0 01 4? 89 05 ?? ?? ?? ?? c7 4? ?? 00 00 00 00 e9 ?? ?? ?? ?? 8b 4? ?? 4? 98 4? 8d 9? ?? ?? ?? ?? 4? 8d ?? e0 4? 8b 0? 4? 89 0? 4? 8b 4? ?? 4? 89 4? ?? 8b 4? ?? 4? 98 4? 8d b? ?? ?? ?? ?? b? ?? ?? ?? ?? e8 ?? ?? ?? ?? c7 4? ?? 00 00 00 00 eb ?? 8b 4? ?? 8b 4? ?? 01 c1 8b 4? ?? 03 4? ?? 4? 98 0f b6 9? ?? ?? ?? ?? 8b 4? ?? 4? 98 0f b6 8? ?? ?? ?? ?? 31 c2 4? 63 c1 88 9? ?? ?? ?? ?? 83 4? ?? 01}
condition:
uint32(0) == 0x464c457f and all of them
}
rule M_APT_VIRTUALPITA_3
{
meta:
author = "Mandiant"
md5 = "fe34b7c071d96dac498b72a4a07cb246"
description = "Finds opcodes from 409dd8 to 409e46 in fe34b7c071d96dac498b72a4a07cb246 to set the HISTFILE environment variable to 'F' with a putenv() after loading each character individually."
strings:
$x = {4? 8b 4? ?? c6 00 48 4? 8b 4? ?? 4? 83 c0 05 c6 00 49 4? 8b 4? ?? 4? 83 c0 01 c6 00 49 4? 8b 4? ?? 4? 83 c0 06 c6 00 4c 4? 8b 4? ?? 4? 83 c0 02 c6 00 53 4? 8b 4? ?? 4? 83 c0 07 c6 00 45 4? 8b 4? ?? 4? 83 c0 03 c6 00 54 4? 8b 4? ?? 4? 83 c0 08 c6 00 3d 4? 8b 4? ?? 4? 83 c0 04 c6 00 46 4? 8b 4? ?? 4? 83 c0 09 c6 00 00 4? 8b 7? ?? e8}
condition:
uint32(0) == 0x464c457f and all of them
}
rule M_APT_VIRTUALPITA_4
{
meta:
author = "Mandiant"
md5 = "fe34b7c071d96dac498b72a4a07cb246"
description = "Finds opcodes from 401f1c to 401f4f in fe34b7c071d96dac498b72a4a07cb246 to decode text with multiple XORs"
strings:
$x = {4? 8b 4? ?? 4? 83 c1 30 4? 8b 4? ?? 4? 8b 10 8b 4? ?? 4? 98 4? 8b 04 ?? ?? ?? ?? ?? 4? 31 c2 4? 8b 4? ?? 4? 83 c0 28 4? 8b 00 4? c1 e8 10 0f b6 c0 4? 98 4? 8b 04}
condition:
uint32(0) == 0x464c457f and all of them
}
rule M_Hunting_Script_LaunchAndDelete_1
{
meta:
author = "Mandiant"
md5 = "bd6e38b6ff85ab02c1a4325e8af29ce4"
description = "Finds scripts that launch and then delete files, indicative of cleaning up tracks and remaining in-memory only."
strings:
$ss = /setsid[^\n\r]{,250}-i[\r\n]{,5}rm/
condition:
all of them
}
rule M_Hunting_Python_Backdoor_CommandParser_1
{
meta:
author = "Mandiant"
md5 = "61ab3f6401d60ec36cd3ac980a8deb75"
description = "Finds strings indicative of the vmsyslog.py python backdoor."
strings:
$key1 = "readInt8()" ascii wide
$key2 = "upload" ascii wide
$key3 = "download" ascii wide
$key4 = "shell" ascii wide
$key5 = "execute" ascii wide
$re1 = /def\srun.{,20}command\s?=\s?self\.conn\.readInt8\(\).{,75}upload.{,75}download.{,75}shell.{,75}execute/s
condition:
filesize < 200KB and all of them
}
謝辞
Brad Slaybaugh、Joshua Kim、Zachary Smith、Kirstie Failey、Nick Simonian、Charles Carmakalには、調査、技術検討、本ブログ記事で取り上げたマルウェア群の検出結果の作成にご協力いただき、特に感謝しています。また、この調査に協力していただいたVMware社に感謝します。
※本ブログは、2022年9月29日に公開されたブログ「Bad VIB(E)s Part One: Investigating Novel Malware Persistence Within ESXi Hypervisors」の日本語抄訳版です。
-Mandiant, 作成者: Alexander Marvi, Jeremy Koppen, Tufail Ahmed, Jonathan Lepore