
CobaltWhispersは、Cobalt Strike用のBeacon Object Files(BOF)コレクションを利用するアグレッサースクリプトで、プロセスインジェクション、永続化などを実行し、直接システムコール(SysWhispers2)を利用してEDR/AVをバイパスします。
著者: @Cerbersec
CobaltWhispers は、Cobalt Strike 用の Beacon Object Files のコレクションを利用し、直接システムコールを活用して EDR/AV をバイパスしながら、プロセスインジェクションや永続化などを実行する aggressor スクリプトです。
CobaltWhispers は SysWhispers2 と InlineWhispers2 を基盤としています。
CobaltWhispers は StayKit、および Hasherezade と Forrest Orr の研究成果に基づいています。
CobaltWhispers は、NVISO Security のレッドチームでのインターンシップの一環として作成されました。関連するブログ記事は こちら (process-injection) と こちら (kernel karnage) にあります。
CobaltWhispers のコンパイルにはいくつかのツールが必要です:
apt install mingw-w64apt install make各プロジェクトが機能するには、SysWhispers2 / InlineWhispers2 によって生成された3つのファイルが必要です:
これらのファイルは InlineWhispers2 のドキュメントに従って生成できますが、これは最適な方法ではありません。大量の未使用コードが含まれるためです:
git clone https://github.com/Sh0ckFR/InlineWhispers2 && cd InlineWhispers2
cd SysWhispers2/ && python3 syswhispers.py --preset all -o syscalls_all && cd ..
python3 InlineWhispers2.py
代わりに、SysWhispers2 を使用して必要な API の出力ファイルのみを生成し、それらを手動(またはスクリプトで)InlineWhispers2 に渡して適切な形式に変換してください。詳細は同梱の makefile を参照するか、同梱のファイルを使用する場合は自己責任で行ってください。
| ペイロードタイプ | ターゲット | 信頼性 (0-5) | 昇格権限 | 備考 |
|---|---|---|---|---|
| - | - | 5 | いいえ | 親プロセスから権限を継承 |
非マイクロソフト署名バイナリをブロックするコード整合性ガード (CIG) を有効にして、中断状態の新しいプロセスを生成します。指定された親プロセスをスプーフィングします。PID が返されます。
親プロセス: 親として設定するプロセスの名前
実行可能ファイルの場所: 新しいプロセスを生成するために使用されるディスク上の実行可能ファイルのフルパス
| ペイロードタイプ | ターゲット | 信頼性 (0-5) | 昇格権限 | 備考 |
|---|---|---|---|---|
| Shellcode/Raw | PID | 5 | いいえ | - |
NtCreateThreadEx を使用してリモートプロセスにペイロードをインジェクションします
プロセス PID: リモートプロセスのプロセス ID
ペイロードの場所: ディスク上のバイナリ形式のペイロードの場所 (条件付き | オプション)
ペイロード b64: base64 エンコードされた文字列形式の生のシェルコード (条件付き | オプション)
リスナー: ペイロードを生成するためのリスナー (条件付き)
Beacon ペイロードを生成するにはリスナーを指定する必要があります。手動のペイロードが必要な場合は、ディスク上の生のバイナリへのパス、または Base64 エンコードされたシェルコードで提供する必要があります。
| ペイロードタイプ | ターゲット | 信頼性 (0-5) | 昇格権限 | 備考 |
|---|---|---|---|---|
| Shellcode/Raw | PID | 2 | いいえ | ターゲットプロセスをクラッシュさせる可能性があります |
NtQueueApcThread を使用してリモートプロセスにペイロードをインジェクションします
プロセス PID: リモートプロセスのプロセス ID
スレッド数: APC 呼び出しを追加するスレッドの数
ペイロードの場所: ディスク上のバイナリ形式のペイロードの場所 (条件付き | オプション)
ペイロード b64: base64 エンコードされた文字列形式の生のシェルコード (条件付き | オプション)
リスナー: ペイロードを生成するためのリスナー (条件付き)
Beacon ペイロードを生成するにはリスナーを指定する必要があります。手動のペイロードが必要な場合は、ディスク上の生のバイナリへのパス、または Base64 エンコードされたシェルコードで提供する必要があります。
| ペイロードタイプ | ターゲット | 信頼性 (0-5) | 昇格権限 | 備考 |
|---|---|---|---|---|
| Shellcode/Raw | サロゲートプロセス | 5 | いいえ | - |
NtMapViewOfSection を使用してサロゲートプロセスにペイロードをインジェクションします
親プロセス: 親として設定するプロセスの名前
実行可能ファイルの場所: 新しいプロセスを生成するために使用されるディスク上の実行可能ファイルの場所
ペイロードの場所: ディスク上のバイナリ形式のペイロードの場所 (条件付き | オプション)
ペイロード b64: base64 エンコードされた文字列形式の生のシェルコード (条件付き | オプション)
リスナー: ペイロードを生成するためのリスナー (条件付き)
Beacon ペイロードを生成するにはリスナーを指定する必要があります。手動のペイロードが必要な場合は、ディスク上の生のバイナリへのパス、または Base64 エンコードされたシェルコードで提供する必要があります。
| ペイロードタイプ | ターゲット | 信頼性 (0-5) | 昇格権限 | 備考 |
|---|---|---|---|---|
| PE | サロゲートプロセス | 5 | いいえ | x64 PE ペイロードが必要です |
トランザクションセクションとマップ済みビューを使用して、サロゲートプロセスにペイロードをインジェクションします。リモートエントリポイントと PEB が更新され、異常なメモリセクションやメモリ権限はありません。詳細は こちら を参照してください。
親プロセス: 親として設定するプロセスの名前
実行可能ファイルの場所: 新しいプロセスを生成するために使用されるディスク上の実行可能ファイルの場所
ペイロードの場所: ディスク上の x64 PE ペイロードの場所 (条件付き | オプション)
ペイロード b64: base64 エンコードされた文字列形式の x64 PE ペイロード (条件付き | オプション)
リスナー: ペイロードを生成するためのリスナー (条件付き)
Beacon ペイロードを生成するにはリスナーを指定する必要があります。手動のペイロードが必要な場合は、ディスク上の x64 PE へのパス、または Base64 エンコードされた x64 PE で提供する必要があります。
現在未実装
| ペイロードタイプ | ターゲット | 信頼性 (0-5) | 昇格権限 | 備考 |
|---|---|---|---|---|
| 位置独立シェルコード (PIC) | サロゲートプロセス | 5 | はい | 書き込み権限でシステム DLL を開くには昇格権限が必要です |
トランザクションセクションと DLL ホロウイングを組み合わせて、サロゲートプロセスにペイロードをインジェクションします。詳細は こちら を参照してください。
親プロセス: 親として設定するプロセスの名前
実行可能ファイルの場所: 新しいプロセスを生成するために使用されるディスク上の実行可能ファイルの場所
ペイロードの場所: ディスク上のバイナリ形式のペイロードの場所 (条件付き | オプション)
ペイロード b64: base64 エンコードされた文字列形式の生のシェルコード (条件付き | オプション)
リスナー: ペイロードを生成するためのリスナー (条件付き)
Beacon ペイロードを生成するにはリスナーを指定する必要があります。手動のペイロードが必要な場合は、ディスク上の生のバイナリへのパス、または Base64 エンコードされたシェルコードで提供する必要があります。
指定された場所にレジストリキーを作成または変更します。
キー名: 値の名前
コマンド: レジストリが使用されたときに実行されるコマンド
レジストリキー: レジストリキーが作成される場所
Hidden: キー名の先頭に null バイトを付加します。regedit でエラーが発生します
Cleanup: 作成されたキーを削除します
Cleanup にはキー名とレジストリキー (場所) が必要です。
指定された場所にレジストリキーを作成または変更します。
キー名: 値の名前
コマンド: レジストリが使用されたときに実行されるコマンド
レジストリキー: レジストリキーが作成される場所
Hidden: キー名の先頭に null バイトを付加します。regedit でエラーが発生します
Cleanup: 作成されたキーを削除します
Cleanup にはキー名とレジストリキー (場所) が必要です。
UserInit: 「キー名」と「レジストリキー」を自動的に設定します。
指定された場所にレジストリキーを作成または変更します。
キー名: 値の名前
コマンド: レジストリが使用されたときに実行されるコマンド
レジストリキー: レジストリキーが作成される場所
Hidden: キー名の先頭に null バイトを付加します。regedit でエラーが発生します
Cleanup: 作成されたキーを削除します
Cleanup にはキー名とレジストリキー (場所) が必要です。
指定された場所にレジストリキーを作成または変更します。
キー名: 値の名前
コマンド: レジストリが使用されたときに実行されるコマンド
レジストリキー: レジストリキーが作成される場所
Hidden: キー名の先頭に null バイトを付加します。regedit でエラーが発生します
Cleanup: 作成されたキーを削除します
Cleanup にはキー名とレジストリキー (場所) が必要です。
UserInitMprLogonScript: 「キー名」と「レジストリキー」を自動的に設定します。
スケジュールされたタスクの COM ハンドラをハイジャックします。DLL を指す HKCU:\Software\Classes\CLSID\\InprocServer32 にレジストリキーを作成します。
クラス ID: タスクの COM ハンドラ CLSID に対応する CLSID
DLL パス: ロードされる DLL へのパス
Cleanup: 作成されたキーを削除します
| 信頼性 (0-5) | 昇格権限 | 備考 |
|---|---|---|
| 4 | はい | ターゲットシステムを BSOD させる可能性があります |
任意のカーネルメモリ読み取り/書き込みが可能な脆弱性のある署名済みドライバ (NalDrv/iqvm64.sys) をロードします。ntoskrnl.exe の g_CiEnabled または CI.dll の g_CiOptions フラグを変更して、ドライバ署名強制 (DSE) を無効化します。
非署名ドライバ (Interceptor/Interceptor.sys) をロードし、その後 DSE フラグの値を復元します。署名済みドライバと非署名ドライバの両方がディスクに書き込まれます。
| ドライバ | MD5 チェックサム |
|---|---|
| iqvm64.sys | 1898ceda3247213c084f43637ef163b3 |
| Interceptor.sys | 508c8943359717cfa0c77b61ebea2118 |
脆弱性のあるドライバの場所: ディスク上のバイナリ形式の脆弱性のある署名済みドライバの場所
悪意のあるドライバの場所: ディスク上のバイナリ形式の悪意のある非署名ドライバの場所
脆弱性のあるドライバ名: レジストリキー '\Registry\Machine\System\CurrentControlSet\Services\' の作成に使用する名前
脆弱性のあるドライバのデバイス名: ドライバとの通信に使用する名前 '\DosDevices\'
悪意のあるドライバ名: レジストリキー '\Registry\Machine\System\CurrentControlSet\Services\' の作成に使用する名前
悪意のあるドライバのデバイス名: ドライバとの通信に使用する名前 '\DosDevices\'
ターゲットパス: 脆弱性のあるドライバと悪意のあるドライバのファイルを書き込む一時パス
| 信頼性 (0-5) | 昇格権限 | 備考 |
|---|---|---|
| 5 | はい | - |
指定されたレジストリキーを使用してターゲット上のドライバをアンロードし、指定されたパスのディスクからバイナリを削除します。
ドライバのレジストリキー: ドライバのアンロードに使用するレジストリキー '\Registry\Machine\System\CurrentControlSet\Services\'
ドライバのインストールパス: ディスク上のドライバの場所
| 信頼性 (0-5) | 昇格権限 | 備考 |
|---|---|---|
| 4 | いいえ | ターゲットシステムを BSOD させる可能性があります |
Information: Interceptor ドライバをクエリします
Hook: ターゲットドライバのメジャー関数 (IRP) をフックします
Unhook: ターゲットドライバのメジャー関数を復元します
Patch: ターゲットのカーネルコールバックにパッチを適用します
Restore: ターゲットのカーネルコールバックを復元します
Vendors: サポートされているベンダーを表示します
Modules: ロードされているすべてのドライバをクエリします
Hooked modules: フックされているすべてのドライバを表示します
Callbacks: 登録されているすべてのコールバックをクエリします
Index: インデックスでドライバをフックします (参照: information - modules)
Name: デバイス名でドライバをフックします (\Device\Name)
Values: カンマ区切りのインデックスリスト (条件付き)
Name: ターゲットドライバのデバイス名 (条件付き)
'Index' が選択された場合は Values が必要です。'Name' が選択された場合は Name が必要です。
Index: インデックスでドライバをアンフックします (参照: information - hooked modules)
All: フックされているすべてのドライバをアンフックします
Values: カンマ区切りのインデックスリスト (条件付き)
'Index' が選択された場合は Values が必要です。
Vendor: ベンダーモジュールに関連付けられたすべてのコールバックにパッチを適用します
Module: モジュールに関連付けられたすべてのコールバックにパッチを適用します
Process: プロセスコールバックにパッチを適用します
Thread: スレッドコールバックにパッチを適用します
Image: イメージコールバックにパッチを適用します
Registry: レジストリコールバックにパッチを適用します
Object process: オブジェクトプロセスコールバックにパッチを適用します
Object thread: オブジェクトスレッドコールバックにパッチを適用します
Values: カンマ区切りのインデックスリスト (参照: information - callbacks) (条件付き)
Name: カンマ区切りのモジュール名リスト、または単一のベンダー名 (参照: information - vendors) (条件付き)
'process'、'thread'、'image'、'registry'、'object process'、または 'object thread' が選択された場合は Values が必要です。'vendor' または 'module' が選択された場合は Name が必要です。
Vendor: ベンダーモジュールに関連付けられたすべてのコールバックを復元します
Module: モジュールに関連付けられたすべてのコールバックを復元します
Process: プロセスコールバックを復元します
Thread: スレッドコールバックを復元します
Image: イメージコールバックを復元します
Registry: レジストリコールバックを復元します
Object process: オブジェクトプロセスコールバックを復元します
Object thread: オブジェクトスレッドコールバックを復元します
All: すべてのコールバックを復元します
Values: カンマ区切りのインデックスリスト (参照: information - callbacks) (条件付き)
Name: カンマ区切りのモジュール名リスト、または単一のベンダー名 (参照: information - vendors) (条件付き)
'process'、'thread'、'image'、'registry'、'object process'、または 'object thread' が選択された場合は Values が必要です。'vendor' または 'module' が選択された場合は Name が必要です。