この複数回にわたるシリーズの最初の記事では、Elastic Security Labs チームのマルウェア研究者が REMCOS の脅威について簡単に紹介し、構成の読み込みから感染したマシンの Web ブラウザーのクリーンアップまでの実行フローの前半について詳しく説明します。
はじめに
Elastic Security Labsは、REMCOSバージョン4.9.3の内部の複雑さに焦点を当て、影響の大きい脅威の調査を継続しています。プロ (11 月26 、 2023 )。
Breaking-Securityが開発した REMCOS は、レッドチームツールとして誕生したソフトウェアですが、その後、ほぼすべての分野を狙ったあらゆる種類の脅威に採用されるようになりました。
1 月中旬に分析を実施した時点では、これがANY.RUN によって報告された最も蔓延しているマルウェア ファミリーでした。さらに、同社が 3 月9日2024にバージョン 4.9.4 のリリースを発表したことからもわかるように、現在も活発に開発が進められています。
分析したサンプルはすべて同じREMCOS 4.9.3から得られたものである。Pro x86 ビルド。このソフトウェアは C++ でコーディングされており、文字列およびバイト関連の操作にはstd::stringクラスが多用されています。
REMCOS には、回避技術、権限昇格、プロセスインジェクション、記録機能など、幅広い機能が満載されています。
この記事シリーズでは、以下の点について広範囲に分析します。
- 実行と能力
- ElasticのES|QLクエリを使用した検出およびハンティング戦略
- 構成フィールドの約80%を回復
- C2コマンドの約90%を回復
- IDA Proの各スクリーンショットの下にあるサンプル仮想アドレス
- さらにもっと!
ご質問やご意見がございましたら、ソーシャル メディア@elasticseclabsまたは Elastic Community Slackからお気軽にお問い合わせください。
設定の読み込み
REMCOS 構成は、 SETTINGSという名前のリソース内の暗号化された BLOB に保存されます。この名前は、REMCOS のさまざまなバージョンで一貫して表示されます。
マルウェアは、リソース セクションから暗号化された構成 BLOB を読み込むことから始まります。
暗号化された構成をロードするには、次の Python スクリプトとLiefモジュールを使用します。
import lief
def read_encrypted_configuration(path: pathlib.Path) -> bytes | None:
if not (pe := lief.parse(path)):
return None
for first_level_child in pe.resources.childs:
if first_level_child.id != 10:
continue
for second_level_child in first_level_child.childs:
if second_level_child.name == "SETTINGS":
return bytes(second_level_child.childs[0].content)
バージョン 4.9.3 は、Fortinet の研究者が以前に説明したものと同じ構造と復号化スキームを維持していることを確認できます。
「暗号化された構成」とは、次のように表示される、復号化キーと暗号化されたデータ BLOB を含む構造を指します。
struct ctf::EncryptedConfiguration
{
uint8_t key_size;
uint8_t key[key_size];
uint8_t data
};
次のスクリーンショットに示すように、構成は引き続き RC4 アルゴリズムを使用して復号化されます。
構成を復号化するには、次のアルゴリズムを使用します。
def decrypt_encrypted_configuration(
encrypted_configuration: bytes,
) -> tuple[bytes, bytes]:
key_size = int.from_bytes(encrypted_configuration[:1], "little")
key = encrypted_configuration[1 : 1 + key_size]
return key, ARC4.ARC4Cipher(key).decrypt(encrypted_configuration[key_size + 1 :])
この構成は、文字列\x7c\x1f\x1e\x1e\x7cを区切り文字として分割して、 g_configuration_vectorと呼ぶグローバル ベクトルを初期化するために使用されます。
このシリーズの後半で、構成について詳しく説明します。
UACバイパス
構成でenable_uac_bypass_flag (インデックス0x2e ) が有効になっている場合、REMCOS は既知の COM ベースの手法を使用して UAC バイパスを試行します。
事前に、REMCOS は検出を避けるためにプロセスを偽装します。
REMCOS は、イメージ パスとコマンド ラインをexplorer.exe文字列に置き換えて現在のプロセスの PEB 構造を変更し、元の情報を後で使用するためにグローバル変数に保存します。
よく知られている手法では、 CoGetObject API を利用して、 Elevation:Administrator!new:モニカーをCMSTPLUA CLSID およびICMLuaUtil IID とともに渡し、昇格された COM インターフェイスをインスタンス化します。次に、REMCOS はインターフェースのShellExec()メソッドを使用して、管理者権限で新しいプロセスを起動し、終了します。
この手法は、2023 年の Elastic Security Labs の記事「Windows UAC バイパスの調査: 手法と検出戦略」で以前に文書化されていました。
以下は、Elastic Defend エージェントを使用してこのエクスプロイトを検出した最近のスクリーンショットです。
UACを無効にする
構成でdisable_uac_flagが有効になっている場合 (インデックス0x27 )、REMCOS はreg.exe Windows バイナリを使用してHKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\SystemEnableLUA値を0に設定することで、レジストリでUAC を無効にします。
インストールと永続性
構成でenable_install_flag (インデックス0x3 ) がアクティブ化されると、REMCOS がホスト マシンにインストールされます。
インストール パスは、次の構成値を使用して構築されます。
install_parent_directory(インデックス0x9)install_directory(0x30)install_filename(0xA)
マルウェア バイナリが{install_parent_directory}/{install_directory}/{install_filename}にコピーされます。この例では、 %ProgramData%\Remcos\remcos.exeです。
構成でenable_persistence_directory_and_binary_hiding_flag (インデックス0xC ) が有効になっている場合、インストール フォルダーとマルウェア バイナリは、読み取り専用、隠し、およびシステム属性を適用することで、スーパー隠し (ユーザーが隠しファイルまたは隠しフォルダーの表示を有効にしている場合でも、Windows によってシステム属性を持つファイルを保護するためにファイルが隠し状態に維持される) および読み取り専用に設定されます。
インストール後、REMCOS は、構成で有効になっている次のフラグに応じてレジストリに永続性を確立します。
enable_hkcu_run_persistence_flag(インデックス0x4)HKCU\Software\Microsoft\Windows\CurrentVersion\Run\enable_hklm_run_persistence_flag(インデックス0x5)HKLM\Software\Microsoft\Windows\CurrentVersion\Run\enable_hklm_policies_explorer_run_flag(インデックス0x8)HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run\
その後、マルウェアはShellExecuteWを使用してインストール フォルダーから再起動され、初期プロセスが終了します。
プロセスインジェクション
構成でenable_process_injection_flag (インデックス0xD ) が有効になっている場合、REMCOS は検出を回避するために、指定されたプロセスまたはハードコードされたリストから選択された Windows プロセスに自身を挿入します。
enable_process_injection_flagブール値またはターゲット プロセスの名前のいずれかになります。true(1)に設定すると、注入されるプロセスは次のオプションから「ベストエフォート」方式で選択されます。
iexplorer.exeieinstal.exeielowutil.exe
注: REMCOSで使用できる注入方法は1つだけです。プロセス注入について話すときは、ここで概説する方法に具体的に言及しています。
REMCOS は、プロセス インジェクションに従来のZwMapViewOfSection + SetThreadContext + ResumeThread手法を使用します。これには、共有メモリを介して注入されたバイナリに自身をコピーし、 ZwMapViewOfSection使用してマップし、 SetThreadContextおよびResumeThreadメソッドを使用して REMCOS エントリ ポイントへの実行フローをハイジャックすることが含まれます。
まず、 CreateProcessW API を使用して中断モードでターゲット プロセスを作成し、 GetThreadContext API を使用してそのスレッド コンテキストを取得します。
次に、 ZwCreateSection API を使用して共有メモリを作成し、リモート プロセスへのハンドルとともに、 ZwMapViewOfSection API を使用してそれをターゲット プロセスにマップします。
次に、バイナリのヘッダーとセクションを共有メモリにコピーして、リモート プロセスにロードします。
必要に応じて再配置が適用されます。次に、PEB ImageBaseAddress WriteProcessMemory API を使用して修正されます。その後、REMCOS エントリ ポイントを指す新しいエントリ ポイントでスレッド コンテキストが設定され、プロセスの実行が再開されます。
以下は、当社のエージェントによるこのプロセス インジェクション手法の検出です。
ログモードの設定
REMCOS には、構成のlogging_mode (インデックス0x28 ) フィールドで選択できる 3 つのログ モード値があります。
- 0: ログなし
- 1: トレイアイコンに最小化された状態で起動
- 2: コンソールログ
このフィールドを 2 に設定すると、プロセス インジェクションが有効になっている場合でもコンソールが有効になり、追加情報が公開されます。
ブラウザのクリーニング
enable_browser_cleaning_on_startup_flag (インデックス0x2B ) が有効になっている場合、REMCOS はホストにインストールされている Web ブラウザから Cookie とログイン情報を削除します。
公式ドキュメントによると、この機能の目的はパスワード盗難に対するシステム セキュリティを強化することです。
現在サポートされているブラウザは、Internet Explorer、Firefox、Chrome です。
クリーニング プロセスでは、 FindFirstFileA 、 FindNextFileA 、 DeleteFileA API を使用して、ブラウザの既知のディレクトリ パスから Cookie とログイン ファイルを削除します。
ジョブが完了すると、REMCOS はコンソールにメッセージを出力します。
構成内の 2 つの関連フィールドについて言及する価値があります。
enable_browser_cleaning_only_for_the_first_run_flag(インデックス0x2C)browser_cleaning_sleep_time_in_minutes(インデックス0x2D)
browser_cleaning_sleep_time_in_minutes構成値により、ジョブを実行する前に REMCOS がスリープする時間が決まります。
enable_browser_cleaning_only_for_the_first_run_flagが有効になっている場合、クリーニングは REMCOS の最初の実行時にのみ実行されます。その後、 HKCU/SOFTWARE/{mutex}/FRレジストリ値が設定されます。
後続の実行では、値が存在し、レジストリに設定されている場合は関数が直接返されます。
これで第一回の記事は終わりです。パート 2 では、ウォッチドッグから C2 との最初の通信までの REMCOS 実行フローの後半について説明します。
