ランサムウェア

知られざるマルウェアファミリ、Vatet、PyXie、Defray777 の詳細

Clock Icon 10 min read

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

次の記事: 「PyXie Lite」

以前のバージョンのPyXieについては、2019年12月にBlackBerry Cylanceが詳しく説明していました。ここでは主に、更新された亜種について、そして弊社が確認した重要な変更点をいくつかご紹介します。

変更点には次のようなものがあります。

  • 強固になったインタープリタ
  • 新たにマッピングし直されたオペコードテーブル
  • データ窃盗および偵察ツールとしての再利用
  • 内部サーバーによるデータの漏出

コードベースが大幅に小さくなったため、弊社ではこの亜種をPyXie Liteと呼んでいますが、名前に惑わされないでください。かなりの威力です。

ローダー

以前のバージョンのPyXieをロードするには、Goopdate.dllおよびLMIGuardianDll.dllのサイドロードアプリケーションがよく使用されていましたが、弊社が分析した最近の亜種では、Vatetが使用されています。

復号されたVatetペイロードには、シェルコードローダーによって追加されるPyXieの第1段階が含まれています。シェルコードローダーは、PyXieの第1段階をメモリにマッピングして実行します。

このシェルコードローダーは、MurmurHash3ハッシュを利用して、プロセス実行時に必要なAPIを特定します。

dll 関数 APIハッシュ
Kernel32.dll GetProcAddress 0x261C88ED
Kernel32.dll VirtualAlloc 0xC17E7EB2
Kernel32.dll LoadLibraryExA 0x4B9B30B9

表2: MurmurHash3 APIハッシュ

第1段階

第1段階の目的は、第2段階のペイロードを復号してメモリ内で実行することです。

ミューテックス

ミューテックスは、複数のインスタンスの同時実行を防ぐために作成されます。次のロジックが使用されます。

  • GetComputerNameAを呼び出してコンピュータ名を取得する。失敗した場合、DEFAULTCOMPNAMEにフォールバックする。
  • コンピュータ名のMD5ハッシュを計算する。
  • 計算されたハッシュと0x2とのXOR演算を実行する。
  • StringFromGUID2で演算結果を文字列に変換する。
  • CreateMutexWを呼び出し、変換された文字列を使ってミューテックスを作成する。
文字列の暗号化

重要な意味を持つ文字列は暗号化されており、暗号化にはあるルーチンが使用されています。そのルーチンは、暗号化テキストの各バイト値にインデックス値を加算し、その結果を0x7F(ASCII文字セットの最大値)でマスクし、さらに長さの等しいキーとのXOR演算を実行します。

Vatetローダーの文字列復号ルーチンの例

表3: 文字列の復号例

復号された文字列
uiAccess=true”
-q -s {%S} -p %u
werfault.exe
vsjitdebugger.exe
dvdplay.exe
onedrivesetup.exe
openwith.exe
%windir%\syswow64\
%windir%\system32\
kernel32.dll
KiUserExceptionDispatcher
RtlCreateUser
IsWow64Process
\StringFileInfo\%04x%04x\ProductName

表4: 復号された第1段階の文字列

ペイロードの復号化

次の段階のペイロードは、バイナリの.gfidsセクションにある暗号化された7zアーカイブに保存されています。このペイロードは、以前BlackBerry Cylanceの記事で取り上げられた、変更されたRC4アルゴリズムで復号されます。復号には、次のハードコードされたキーを使用します: 2C01443389BDFC7330A3386981C43E154AE8B60EC6646D916F93D18137A53544

次の段階のペイロードは、バイナリの.gfidsセクションにある暗号化された7zアーカイブに保存されています。これは、すでに復号された7zアーカイブを示しています。
図12: 復号された7zアーカイブ
ペイロードの実行

OpenProcessTokenおよびGetTokenInformationが呼び出され、LocalSystemアカウントでプロセスが実行されているかどうかを確認します。この確認は、次の段階のペイロードの実行方法を判断するために使用されます。

LocalSystemで実行されていると判断した場合、ペイロードは、Windowsディレクトリから選択された、新たに作成されたプロセスに挿入されます。このプロセスのコマンドラインは次のフォーマットにしたがっており、侵害指標に使えます。

LocalSystemで実行されていると判断した場合、ペイロードは、Windowsディレクトリから選択された、新たに作成されたプロセスに挿入されます。このプロセスのコマンドラインは、こちらに示す特有のフォーマットに従い、インジケータとして使用できます。
図13: コマンドライン引数

LocalSystemとして実行されていることが確認できない場合は、現在のプロセスのメモリ領域内でペイロードが実行されます。

第2段階

第2段階のペイロードは、カスタムコンパイルされたPythonインタープリタです。PyXieの以前の亜種で使用されていたものとよく似ています。

設定

設定は、zlib圧縮されたjson Blobに保存されており、インタープリタの.gfidsセクションにあります。以前のバージョンのPyXieとは異なり、今回は暗号化されていません。変数sys.builtin_json_cfgは、PySys_SetObjectを呼び出して作成されます。圧縮されている設定Blobは、この変数に保存され、その後最終段階のPythonコンポーネントで使用されます。

変数sys.builtin_json_cfgは、PySys_SetObjectを呼び出して作成されます。圧縮されている設定Blobは、この変数に保存され、後で最終段階のPythonコンポーネントで使用されます。
図14: sys.builtin_json_cfg変数の作成
復号された文字列

第2段階では、第1段階で述べたものと同じ文字列暗号化を使用します。

kernel32.dll
openwith.exe
onedrivesetup.exe
dvdplay.exe
vsjitdebugger.exe
werfault.exe
-q -s {%S} -p %u
oleout32.dll
VariantClear
Mozilla\Firefox
Mozilla\Firefox\profiles.ini
SOFTWARE\Clients\StartMenuInternet\firefox.exe\shell\open\command
I_CryptUIProtect
cryptui.dll
RtlCreateUserThread
import core.modules.winapi_stubs as winapi_stubs
import core.zip_logs as zip_logs
import os
zip_logs.send_zip_log(winapi_stubs.get_self_executable_path(), os.getpid(), ‘CERTS’, r’%s’)
KiUserExceptionDispatcher
uiAccess=”true”
\StringFileInfo\%04x%04x\ProductName
\VarFileInfo\Translation
\\?\globalroot\systemroot\system32\drivers\null.sys
SystemDrive
IsWow64Process
core.entry_point
zipimporter
memzipimport
libs_zip_ctx
start_bind_port

表5: 復号された第2段階の文字列

最終段階: Libs.zip

最終段階のPyXieバイトコードは、インタープリタのバイナリ内に組み込まれた、暗号化されたZIPファイルに含まれています。以前のバージョンのPyXieでは、メモリからバイトコードをインポートするためにmemzipimportライブラリが使用されていました。

PyXie Lite

この亜種内の「コア」モジュールが41個のファイルで構成されているのに対し、以前のバージョンのPyXieでは、BlackBerry Cylanceの分析によると79個のファイルが確認されています。この相違は、次のセクションで取り上げる機能の変化によるものです。

図15: バイトコードのリスト

インタープリタの強化

バイトコードを簡単に分析したところ、以前のバージョンのPyXieと同様にヘッダが取り除かれていることがわかりました。また、オペコードテーブルが再度変更されており、以前のバージョンのPyXieから復元されたオペコードは、このバイトコードの逆コンパイルには使用できなくなっていました。

バイトコードを簡単に分析したところ、以前のバージョンのPyXieと同様にヘッダが取り除かれていることがわかりました。オペコードテーブルが再度変更されており、以前のバージョンのPyXieから復元されたオペコードは、このバイトコードの逆コンパイルには使用できなくなっていました。
図16: 以前のPyXieから復元されたオペコードを使用してバイトコードを逆コンパイルする試みはエラーに終わる

この状況は理解しつつも、オペコードの復元に使用できるバイトコードを生成できるのではないかという望みにかけてインタープリタにDeDropのall.pyを強制的にインポートしてみたのですが、残念ながらスクリプトをインポートするだけでは、インタープリタにバイトコードを出力させることはできませんでした。

インタープリタをよく調べてみると、sys.dont_write_bytecode変数がtrueに設定されていました。この設定は、モジュールがインポートされたときにバイトコードがディスクに書き出されるのを防止する効果があります。分析作業を妨げるために、開発者が意図的にこのような操作をしたように見えます。

インタープリタをよく調べてみると、sys.dont_write_bytecode変数がtrueに設定されていました。この設定は、モジュールがインポートされたときにバイトコードがディスクに書き出されるのを防止する効果があります。
図17: sys.dont_write_bytecodeがtrueに設定されている
検索順序の脆弱性を利用してインタープリタをハイジャック

インタープリタを分析している間に、インタープリタが現在の作業ディレクトリから多数のモジュールをロードしようと試みており、検索順序のハイジャックに対して脆弱であることがわかりました。

PyXieが現在の作業ディレクトリから多数のモジュールのロードを試み、検索順序のハイジャックに対して脆弱であることを示すスクリーンショット
図18: 現在の作業ディレクトリからライブラリのロードを試みるPyXie

弊社では、PyXieがインポートを試みたモジュールの1つに簡単なPythonシェルをドロップして、この脆弱性を有利に利用することができました。これにより、インタープリタに自由にアクセスできるようになったので、sys.dont_write_bytecode変数を上書きしたり、必要に応じてモジュールのオペコードを生成したり、PyXieの設定のダンプまで取得できるようになりました。

PyXieがインポートを試みたモジュールの1つに簡単なPythonシェルをドロップして、PyXieの検索順序の脆弱性を有利に利用することができました。
図19: 検索順序の脆弱性を利用してインタープリタの制御機能を掌握

私たちが選択したモジュールのバイトコードさえ出力できれば、マッピングし直されたオペコードの復元とPyXieの逆コンパイルはごく簡単です。この亜種のオペコードのコピーは、付録に記載されています。

機能

これまでに述べたように、PyXie Liteは、データの収集と漏出の自動化に焦点を当てて再利用されたものです。

実行を開始すると、tempfile.NamedTemporaryFile()コマンドの出力に基づいた名前を持つステージングディレクトリを作成します。

%temp%\tmp1rjvhglo

表6: ステージングディレクトリの名前の例

次に、PyXie実行時のユーザーアカウントによって決定されるルーチンの組み合わせを実行して、システムからデータを収集します。表7は、これらの各ルーチンと、どのアカウントタイプの場合にどのルーチンを実行するかを詳細に示したものです。

ルーチン ユーザータイプ 説明
_mimi_redirector すべて メモリ内でMimikatzを実行する。次のリスト内の新たに作成されたプロセスに挿入する: write.exe、notepad.exe、explorer.exe
_main_routine すべて
  • システムに関する基本的な詳細情報の収集
  • ソフトウェアのインベントリの取得
  • cookieの収集
  • LogMeInデータの収集
  • Citrixデータの収集
  • KeePassの金庫情報の収集
_save_sysinfo すべて レジストリからアンインストールリストを収集
_get_passwords すべて Lazagneを使用してパスワードを収集
_find_files システム 設定で指定されているキーワード、ディレクトリ、拡張子に基づいてファイルおよびディレクトリを検索し、収集する
_scan_network システム ネットワークスキャンを実行する
_run_shell_cmds システム システムの詳細情報を収集するための一連のコマンドを実行する
_get_desktop_files ユーザー find_filesに似ているが、現在のユーザーのデスクトップを検索するのみ
_take_screenshot ユーザー スクリーンショットを取得する
_get_ps_history ユーザー Powershellの履歴を収集する

表7: PyXieのルーチン

設定で指定されている、以下のキーワードとディレクトリのリストから、攻撃者が関心を持っているデータのタイプについていくつかのヒントが得られます。

passw logins wallet private
confidential username wire access
treason vault operation bribery
contraband censored instruction credent
cardholder secret explosive suspect
personal cyber restricted balance
passport victim submarine checking
saving routing esxi vsphere
spy admin newswire bitcoin
ethereum n-csr 10-sb 10-q
convict tactical engeneering military
disclosure attack infrastruct marketwired
agreement illegal nda hidden
privacy fraud statement finance
marketwired clandestine compromate concealed
investigation security

表8: PyXie Liteの設定に指定されたキーワード(スペルの間違いはそのまま記載)

データ収集ルーチンの一部として、システムの詳細情報を収集するために多数のコマンドが実行されます。

netstat -an
net user
net use
net view /all
net view /all /domain
net share
net config workstation
net group “Domain Admins”
net group “Enterprise Admins”
route print
net localgroup
ipconfig /all
tasklist /V
wmic process
arp -a
gpresult /z
cmdkey /list
net config workstation
nslookup -type=any %userdnsdomain%
vssadmin List Shadows
wmic qfe list
klist
manage-bde -status
nltest /domain_trusts
nltest /domain_trusts /all_trusts
qwinsta
ipconfig /displaydns
systeminfo
dclist
net group “domain admins” /domain
net localgroup “administrators”
wmic path win32_VideoController get name
wmic cpu get name
reg.exe save hklm\security %LOCALAPPDATA%\temp\[RANDOM]
reg.exe save hklm\system %LOCALAPPDATA%\temp\[RANDOM]
reg.exe save hklm\sam %LOCALAPPDATA%\temp\[RANDOM]

表9: 実行されたコマンド

PyXie実行時のユーザーアカウントによって決定されるルーチンの組み合わせを実行して、システムからデータが収集されますが、データを引き出す前にステージングディレクトリに収集されます。
図20: データ漏出の前に、ステージングディレクトリ内のルーチンから収集されたデータ
データの漏出

収集されたデータが含まれるステージングディレクトリは、圧縮されたZIPアーカイブに追加され、暗号化された後に設定のgatesセクションで指定されたサーバーに送信されます。このアーカイブの暗号化にはAES方式をCBCモードで使用し、キーとしてTHIS_KEY_IS_FOR_INTERNAL_USE_ONLYを使用します。16バイトのランダムな初期化ベクトル(IV)を使用して暗号化されたアーカイブに追加します。これまでサンプルを確認してきた中で、データの漏出に利用されたサーバーは、通常、被害を受けたネットワーク上にある、内部の侵害されたサーバーでした。このようなネットワークでは、ポート31337/tcp、900/tcp8443/tcpでリスニングしています。今回被害を受けたネットワークから、攻撃者がどのようにデータを漏出させたのかは確認できなかったのですが、少なくとも1つのインシデントでは、データ漏出に利用されたサーバーでCobalt Strikeが実行されていました。

続きを読む: 最後の重要な記事: Defray777

Enlarged Image