Skip to content

Latest commit

 

History

History

README.md

php - phishing-kit teardown sandbox

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.

Quickstart

cp .env.example .env
make up

Generate the synthetic kit and submit it once the CLI is wired:

make sample
make submit

The sample is fake on purpose. Shipping real phishing kits in a public repo would be, uh, not a great life choice.

Configure

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.

How it is wired

The runtime runs normal PHP agent code. The sandbox container runs the spicy bits:

  • php.lint
  • php.parse_ast
  • php.deobfuscate_round
  • yara.scan
  • regex.extract_urls
  • tld.classify
  • screenshot.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.

Budget story

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.

Where to add code

  • 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.

Verify install only

make verify