主なポイント
- プルーフポイントは、パスワード・マネージャーBitwardenの偽のインストール・パッケージを介して配布されているZenRATと呼ばれる新しいマルウェアを確認しました。
- このマルウェアは特にWindowsユーザーを標的としており、他のホストを使用しているユーザーを良性のウェブページにリダイレクトします。
- 現時点では、このマルウェアがどのように配布されているかは不明です。
- このマルウェアは、情報窃取機能を備えたモジュール型のリモート・アクセス型トロイの木馬(RAT)です。
概要
Proofpoint Emerging Threatsは、新種のマルウェアの調査や検出につながるヒントをコミュニティから受け取ることがよくあります。2023年8月10日、Malwarebytesの脅威インテリジェンス担当シニアディレクターであるJérôme Seguraは、Windowsソフトウェアのインストールパッケージの一部として配布されていたマルウェアのサンプルを共有しました。このサンプルは当初、Bitwardenの関連サイトを装ったウェブサイト、bitwariden[.]comで発見されました。Bitwardenの標準インストール・パッケージには、悪意のある.NET実行ファイルが含まれており、私たちはこれを「ZenRAT」と呼んでいます。
現時点では、このマルウェアがどのように配布されているかは不明ですが、偽のソフトウェアインストーラを装った歴史的な活動は、SEOポイズニング、アドウェアバンドル、または電子メール経由で配信されています。
図1:偽のBitwardenウェブサイト、bitwariden[.]com.
bitwarden.comとテーマが驚くほど似ているが、このドメインにどのようにトラフィックが誘導されているかは不明である。
特にWindowsユーザーをターゲットに
悪意のあるウェブサイトは、ユーザーがWindowsホスト経由でアクセスした場合にのみ、偽のBitwardenダウンロードを表示します。Windows以外のユーザーがこのドメインに移動しようとすると、ページはまったく別のものに変わります。
図2:Windows以外のユーザーが悪意のあるウェブサイトを訪問した時に表示されるクローン化されたopensource.comの記事
この画面キャプチャは、Ubuntu 22.04上でMozilla Firefoxを使用して撮影された。
このウェブサイトは、代わりに正規のウェブサイト "opensource.com "を装っており、Bitwardenパスワード・マネージャーに関するScott NesbittによるOpensource.comの記事をクローンして表示しています。さらに、WindowsユーザーがダウンロードページでLinuxやMacOS用にマークされたダウンロードリンクをクリックすると、代わりに正規のBitwardenサイトであるvault.bitwarden.comにリダイレクトされます。ダウンロード ボタンまたはWindows用デスクトップ インストーラの ダウンロード ボタンをクリックすると、Bitwarden-Installer-version-2023-7-1.exeのダウンロードが試みられます。このペイロードはcrazygameis[.]comというドメインでホストされていますが、この記事を書いている時点では、このペイロードは実際にはホストされていないようです。
図3: WindowsユーザーがダウンロードボタンかWindows用デスクトップインストーラーオプションをクリックすると、
悪質なBitwardenインストーラーを取得するためにcrazygameis[.]comへのリクエストが実施される
両ドメインのレジストラはNiceNIC International Groupで、サイト自体はCloudflareでホストされているようです。
インストーラーの詳細
この悪質なインストーラーBitwarden-Installer-version-2023-7-1.exeは、2023年7月28日にVirusTotalでCertificateUpdate-version1-102-90という別の名前で最初に報告されたようです。
図4:これまでのところ、このインストーラー・サンプルは、2つのまったく異なる名前だが、比較的近い時間軸で2度サブミットされている
インストーラーの詳細を見てみると、デジタル署名が無効であることがわかりますが、さらに興味深いことに、このインストーラーはPiriformのSpeccy(システム仕様を収集するためのソフトウェアアプリケーション)であると主張しています。
図5:悪意のあるbitwardenインストーラーのファイルメタデータは、アプリケーションを実行するシステムに関する情報(スペック)を収集するために使用されるアプリケーションであるSpeccyであると主張している
それだけでなく、インストーラーは、Filezilla FTP/SFTPソフトウェアで最も有名なオープンソースソフトウェア開発者であるTim Kosseの署名入りであると主張しています。
図6:疑わしいファイルプロパティに加えて、このインストーラには無効なデジタル署名があり、FileZilla FTP/SFTPソフトウェアで最もよく知られているオープンソース開発者、Tim Kosseによって署名されたと主張している
インストーラーファイルは、自分自身を C:\Users\[username]\Appdata\Local\Tempにコピーし、同じディレクトリに.cmdという隠しファイルを作成し、自分自身とインストーラーファイルの両方で自己削除ループを起動します。
図7:.cmd ファイルという名前のファイルが、インストーラーと一緒に、現在のユーザー の下の AppDataLocal にドロップされている
このファイルは自己削除ループを実行し、インストーラーの実行が終了すると同時に、それ自身とインストーラーを自動的に削除します。
インストーラは実行ファイル ApplicationRuntimeMonitor.exe のコピーを C:∕AppData∕Roaming∕Runtime Monitor∕ に配置して実行します。
ZenRATの詳細
ZenRAT (ApplicationRuntimeMonitor.exe) は、インストーラーファイルとは異なり、まったく別のアプリケーションであると主張する興味深いメタデータを備えています。ファイルのプロパティは、以下の通り、Monitoring Legacy World Ltd.によって作成されたと主張しています。
図8:ドロップされたZenRAT実行ファイルのファイル・メタデータ
実行すると、WMIクエリーやその他のシステムツールを使って以下にあげるホストに関する情報を収集します。
-CPU Name
-GPU Name
-OS Version
-Installed RAM
-IP address and Gateway
-Installed Antivirus
-Installed Applications
ZenRATはこの情報を、盗んだブラウザのデータ/認証情報とともに、Data.zipというzipファイルとInstalledApps.txt、SysInfo.txtというファイル名でコマンド&コントロール(C2)サーバに送り返すことが確認されています。
図9: 実行すると、ZenRATはシステムフィンガープリントデータを収集し、ブラウザ情報窃取などの他のモジュールからの出力とともにC2への流出用にZIPファイルにパッケージ化する
SysInfo.txtには感染したホストに関するフィンガープリンティング データが含まれ、InstalledApps.txtにはインストールされたアプリケーションのリストが含まれます。
コマンド&コントロール
最初に実行されると、ZenRAT は C2 サーバーとの通信を確立します。この例では、プルーフポイントが観測した唯一のアクティブなC2サーバーは185[.]186.72.14です。C2プロトコルは一意です。
クライアントサイド コミュニケーション
クライアントは C2 との通信を開始します。コマンドや送信される追加データにかかわらず、最初のパケットは常に73バイトである。以下は、クライアントチェックインのパケット構造です:
図10:ZenRATクライアント通信の一般的な構造
コマンドIDによってはクライアントからの送信データが多くなる場合がありますが、最初のパケットは常に合計73バイトになります。
追加データはこのパケットに追加されず、同じTCPストリーム内の別のパケットとして送信されます。
Command ID – クライアントパケットの最初のバイトは、C2サーバーに送信されるコマンド用に予約されています。以下は、観測されたクライアントコマンドIDの表です:
Value |
Command |
0x01 |
Tasking Request |
0x02 |
Request Module |
0x05 |
Update |
0x06 |
Sending Module Results |
0x07 |
Change Module Status |
0x08 |
Send Activity Logs |
0x09 |
Ping |
0x0A |
Get Module Status |
Data Size – クライアントパケットの2バイト目から始まる8バイト。クライアントから期待されるバイト数。コマンドIDとデータサイズ値を含む。例えば、図10の0x49は、クライアントが合計73バイトを送信することを示します。
Hardware ID – この値は、現在のユーザーのユーザー名、マシン名、Windowsバージョン文字列、Windowsディレクトリのタイムスタンプのミリ秒値をSha-256ハッシュで連結したものです。
Bot ID – HWIDの直後には、ハードコードされたGUIDから生成された16バイトのボットIDがあります。
Version – 次の8バイトはインプラントバージョン用に予約されています。
Build – 最後の7バイトは、インプラントのビルドバージョン用に予約されています。
サーバーサイド コミュニケーション
サーバー側の通信はクライアントよりもずっとシンプルです。クライアントの通信と同じように、サーバーがクライアントに送り返す最初のパケットは固定長で、この場合は9バイトのサイズになっています。サーバーのレスポンスのパケット構造は、クライアント側の通信の最初の9バイトの構造と同じで、1バイトのレスポンスコードと、感染したホストに送り返されるデータ量の合計から予約された8バイトが続きます。
図11: C2応答のパケット構造
最初のパケットは常に固定サイズ(9バイト)で、そのパケットの構造はクライアントパケットの最初の9バイトと同じです。
Response ID – クライアントがサーバーに送信したコマンドに対する応答を示す1バイトのフィールド。以下は、観測されたサーバーのレスポンドIDの表です:
Value |
Response |
0x00 |
Successful Acknowledgement |
0x04 |
No Tasking |
0x0A |
Client is Fully Updated |
Data Size – 8バイトの値で、レスポンスIDとデータ・サイズ・フィールドを含め、クライアントがサーバーに期待するデータ量を定義します。
興味深いコマンドの数々
ZenRATはいくつかのコマンドIDを観測しているが、ここではより興味深いものをいくつか紹介する:
ログの送信
カスタムC2プロトコルの確立には細心の注意が払われているようですが、ZenRATはログをクリアな状態でC2サーバーに送信するように設定されています。前述のように、クライアントがログを送信するためのコマンドIDは0x08です。クライアントは最初の73バイトのパケットを送信し、その後にその時点までに実行したさまざまなタスクの完全なASCIIログを送信します。
図12:send logsコマンドの画面キャプチャ
C2サーバーに平文で送信される様々なコマンドIDの目的を判断するのに役立ちます。
図12のログによると、C2サーバーとの通信を確立する前に、ZenRATはいくつかのシステム・チェックを実行しています:
- IsBlockedRegion: マルウェアがこれらの地域で動作していないことを確認するためのジオフェンシングチェック:
- ru-BY
- ru-KG
- ru-KZ
- ru-MD
- ru-RU
- ru-UA
- IsMutex: できるようにします。これは、一度にシステム上で動作するマルウェアのコピーが1つだけであることを保証するためです。
- IsSmallDisk: マルウェアが実行されているシステムディスクのサイズが95GB以上であることを確認するシステムチェックで、サンドボックス対策機能ともいえます。
- IsDetectVM: 実行中のプロセスを、仮想化製品に関連するプロセス名のブラックリストと照合するアンチ仮想化チェック:
- Vmtoolsd
- vboxservice
- Vmwareuser
- Vmwaretray
- VMware
- VMware Tools
- vmtoolsd
[CONFIRMED ]というテキストは、チェックが成功したことを意味し、チェックが失敗した場合は、代わりにログに[ ERROR ]と表示されます。チェックを通過すると、クライアントは接続性を確認するためにpingコマンドIDを送信し、クライアントへの更新をチェックします。その後、この例では、クライアントがタスクを要求し、C2サーバーがクライアントのタスクとモジュール番号を応答します。クライアントがこのモジュールを要求した直後に、SHA256ハッシュと照合して検証し、PID 2680(私たちの分析では、これはregasm.exeプロセスでした)に引数とともにインジェクションします:
uZxIDqImAABkdGqXUbYcQqojy5S9DIKtioa0zReZTJK+MVGP4yuvtUIuq8JUGQM7z+3XyneLWjgDAAAAAAAAAAIAAAAAAAAABQAAAHIEAAAAAAAA
デコードすると、この値の16進ダンプは次のようになります:
図13:クライアントのログ送信コマンドIDに見られるbase64データ引数の構造
この構造の値のほとんどは、73バイトのクライアント通信パケットの値と同じです。
このデータ構造体のほとんどの値(ボットID、ハードウェアID、バージョン、ビルド)は、クライアント通信パケット構造と同様です:
- IP Address – C2サーバーのIPアドレス。先に確立したものと同様の185[.]186.72.14。
- Port Number – C2 サーバーとの通信に使用する TCP ポート番号。この場合、インプラントはポート 9890/TCP
- Module ID – クライアントが実行しようとしているモジュールに関連するモジュール番号 (0x05)
- Task ID – このモジュールをアクティブにするためにサーバーから割り当てられたタスクID。ヘックス値 (0x0472 == 1138)
モジュール結果の送信
クライアント・コマンド ID 0x06 は、モジュールからの結果の送信に使用されます。別のサンプルでは、ZenRAT がモジュール 0x09 の結果をタスク ID 0x0829 で C2 サーバに送信していることが確認されています:
図 14:モジュール結果(0x06)と共に送信されるデータの構造 コマンド ID
図14で転送されるデータは、AES-256-CBCを使用して50000バイトのチャンクで暗号化されています。このデータを復号化するには、50016バイト(50000バイト+16バイトのCBCパディング)のチャンクで処理する必要があります。32バイトの鍵は、タスクIDのSHA256ハッシュから生成されます。例えば、0x29080000000000は、SHA256ハッシュ799b9288579cac5dc19f6b7cb84636f07ea52ecfa151bc71f00e8b8dbf980869を生成します。一方、16バイトのIVは、ハードウェアIDの最初の16バイトです(それ自体、システム固有データの組み合わせからなるSHA256ハッシュ。このハードウェアIDは、上記のクライアント側通信セクションのハードウェアIDと同一)。次のパケットの先頭から0x29080000000000(8バイトのTaskIDと0x00の合計9バイト)を切り落とし、上記のKeyとIVの値を使用すると、モジュールがシステムから収集したデータを含むData.zipファイルができあがります。
図15:タスクIDのSHA256値を鍵として、ハードウェアID値の最初の16バイトをIVとして使用することで、コマンドID 0x06とともに送信されたデータを復号化できる
タスク・フィールドとモジュール ID フィールドがあることから、ZenRAT はモジュール式で拡張可能なインプラントとして設計されていることがわかります。現時点では、他のモジュールが使用されているのを確認していません。
結論
マルウェアは、正規のアプリケーションのインストーラーを装ったファイルを介して配信されることがよくあります。エンドユーザーは、信頼できるソースから直接ソフトウェアをダウンロードすることだけを心がけ、ソフトウェアのダウンロードをホストしているドメインと公式ウェブサイトに属するドメインとを常に照合する必要があります。また、検索エンジンの検索結果に表示される広告にも注意が必要です。特に昨年は、この種の感染の主な原因となっているようです。
IoC (侵害の痕跡:Indicators of Compromise )
IP Address |
Purpose |
185[.]186.72.14:9890 |
Observed ZenRAT C2 server |
185[.]156.72.8:9890 |
Observed nonresponsive ZenRAT C2 server |
Domain |
Purpose |
bitwariden[.]com |
Bitwarden look-alike domain |
crazygameis[.]com |
Payload delivery domain |
obsploject[.]com |
OBS Project look-alike domain (recently registered, no longer responsive) |
geogebraa[.]com |
GeoGebra look-alike domain (recently registered, no longer responsive) |
SHA256 |
Observed Filename |
e0c067fc8e10a662c42926f6cdadfa5c6b8c90d5dff3f0e9f381210180d47d37 |
Bitwarden-Installer-version-2023-7-1.exe |
d7d59f7db946c7e77fed4b927b48ab015e5f3ea8e858d330930e9f7ac1276536 |
ApplicationRuntimeMonitor.exe |
8378c6faf198f4182c55f85c494052a5288a6d7823de89914986b2352076bb12 |
Bitwarden-Installer-version-2023-7-1.exe |
f7573ad27ff407e84d3ebf173cbeaaa6aba62eb74b4b2b934bc0433df3d9e066 |
SearchModule.exe |
e318b2c1693bc771dfe9a66ee2cebcc2b426b01547bb0164d09d025467cb9ee3 |
CertificateUpdate.version2.10.12.exe |
60098db9f251bca8d40bf6b19e3defa1b81ff3bdc13876766988429a2e922a06 |
SystemSecurity.exe |
ba36d9d6e537a1c1ecdf1ace9f170a3a13c19e77f582a5cae5c928a341c1be8d |
2421c4cd791b1eexeexe.exe |
986aa8e20962b28971b3a5335ef46cf96c102fa828ae7486c2ac2137a0690b76 |
npp.8.4.8.Installer.exe |
Emerging Threats Rule Coverage
2037786 – ET INFO Pastebin-style Service (textbin.net in TLS SNI)
2047754 – ET MALWARE ZenRAT Ping Command
2047755 – ET MALWARE ZenRAT CnC OK Response
2047754 – ET MALWARE ZenRAT Ping Command
2047755 – ET MALWARE ZenRAT CnC OK Response
2047756 – ET MALWARE ZenRAT Get Status Command
2047757 – ET MALWARE ZenRAT Status Response
2047758 – ET MALWARE ZenRAT Change Status Command
2047759 – ET MALWARE ZenRAT Request Module Command
2047760 – ET MALWARE ZenRAT Request Module CnC Response
2047761 – ET MALWARE ZenRAT Update Command
2047762 – ET MALWARE ZenRAT Update CnC Response (Already Actual)
2047763 – ET MALWARE ZenRAT Tasking Command
2047764 – ET MALWARE ZenRAT Tasking CnC Response M1
2047765 – ET MALWARE ZenRAT Tasking CnC Response M2
Data Decryption script
The following is a decryption script for the data uploaded by the browser stealing module. This script was provided by our Reverse Engineering Team:
#! /usr/bin/env python3
# ZenRAT encrypts stolen browser data before uploading - but does it in 50000 byte chunks
import sys
import hashlib
# from Crypto.Cipher import AES
from Cryptodome.Cipher import AES
def unpad(s):
if s[-s[-1]:] == s[-1:0] * s[-1]:
return s[:-s[-1]]
else:
return s
data = sys.stdin.buffer.read()
h = hashlib.sha256()
h.update(data[9:41]) # HWID - itself the SHA256 of username + machine name + windows ver + msecs
iv = h.digest()[:16]
h = hashlib.sha256()
h.update(data[0x49:0x51]) # Task ID
key = h.digest()
out = b""
for p in range(0x52, len(data), 50016): # CBC adds 16 bytes (blocksize) to the length
aes = AES.new(key, AES.MODE_CBC, iv)
out += unpad(aes.decrypt(data[p:p + 50016]))
sys.stdout.buffer.write(out)
Acknowledgements
We would like to thank Jérôme Segura, Senior Director of Threat Intelligence at Malwarebytes for his discovery of and collaboration on this threat.