This demo analyzes a captured PHP phishing kit in a locked-down sandbox. The parent job unpacks the kit, delegates one child job per PHP file, and emits a structured incident report with IOCs, deobfuscated snippets, Yara, STIX, and screenshots when available.
Showcases: PHP-native AST parsing, bounded deobfuscation, per-file delegation, read-only kit leases, artifact refs, and per-incident dollar caps that the runtime enforces.
cp .env.example .env
make upGenerate the synthetic kit and submit it once the CLI is wired:
make sample
make submitThe sample is fake on purpose. Shipping real phishing kits in a public repo would be, uh, not a great life choice.
| Variable | Default | Effect |
|---|---|---|
ARCP_AGENT_NAME |
kit.analyze |
Parent kit-analysis agent. |
ARCP_CHILD_AGENT_NAME |
kit.analyze_file |
Child agent for one PHP file. |
SANDBOX_PORT |
9200 |
HTTP port for sandbox tool execution. |
SANDBOX_PHP_VERSION |
8.4 |
PHP version expected inside the sandbox. |
SANDBOX_DEOBFUSCATE_MAX_ROUNDS |
8 |
Max unwrap passes per file. |
SANDBOX_PER_CALL_TIMEOUT_MS |
5000 |
Per-tool timeout in the sandbox. |
KIT_DIR |
/work/kit |
Mounted kit workspace. |
REPORTS_DIR |
/work/reports |
Mounted report output directory. |
KIT_BUDGET_USD |
0.50 |
Parent job spend ceiling. |
PER_FILE_BUDGET_USD |
0.02 |
Child job spend ceiling. |
KIT_FILE_COUNT_CAP |
200 |
Refuse kits above this count. |
SAMPLE_KIT_PATH |
/work/kit/incoming/synthetic-coinbase-kit.zip |
Default synthetic kit path. |
OLLAMA_MODEL |
qwen2.5:1.5b-instruct |
Local model used for file verdicts. |
ARCP_SDK_VERSION |
latest |
Composer dependency version. |
The runtime runs normal PHP agent code. The sandbox container runs the spicy bits:
php.lintphp.parse_astphp.deobfuscate_roundyara.scanregex.extract_urlstld.classifyscreenshot.render
The parent has read access to the kit tree and write access to reports. A child only gets fs.read for its one file, tool.call for parse/deobfuscation, and USD:0.02. If one file tries to eat the whole budget, it gets cut off and the parent keeps going with a partial finding.
No net.fetch is granted. If you want WHOIS enrichment later, put it in a separate tool container and grant it explicitly.
The parent lease uses cost.budget: ["USD:0.50"]. Every child gets USD:0.02, so one cursed file cannot burn the whole incident budget. On local Ollama the dollar number may be notional, but the accounting and enforcement path is the same. That is the real point.
src/Runtime/Agents/KitAnalyze.php- parent agent.src/Runtime/Agents/KitAnalyzeFile.php- child agent.src/Runtime/Tools/*.php- tool adapters that call the sandbox.src/Client/Cli.php- Symfony Console commands:kit:submit,kit:list,kit:report.samples/synthetic-coinbase-kit/- inert sample kit contents.
src/ is still a build-safe scaffold, so make verify proves dependency install before the full sandbox lands.
make verify