The world's most capable AI-agentic penetration testing CLI. Orchestrates 52 security tools with Claude AI for exploit chaining: all from a single terminal command.
phantom connects to the backend at http://127.0.0.1:8731. Launch the desktop app first, or start the backend with:python -m uvicorn python.api.main:app --host 127.0.0.1 --port 8731
phantom is bundled with PhantomYerra and automatically added to your user PATH during installation. Open a new terminal after installing to use it:
phantom --version # phantom 45.1.11
phantom --help # full command reference
If phantom is not found, add this to your PATH manually:
C:\Users\<you>\AppData\Local\Programs\PhantomYerra\resources\bundled-tools
These apply to every command:
| Flag | Short | Default | Description |
|---|---|---|---|
--api <url> | - | http://127.0.0.1:8731 | Backend URL (override for remote/team deployments) |
--output <mode> | - | pretty | Output format: pretty | json | table | csv |
--verbose | -v | off | Show API calls, timing, and raw responses (debug/trace mode) |
--quiet | -q | off | Suppress banner and progress - results only (ideal for piping) |
--timeout <secs> | - | 60 | HTTP request timeout override (seconds) |
--proxy <url> | - | - | Route traffic through proxy (e.g. Burp Suite: http://127.0.0.1:8080) |
| Code | Meaning | CI/CD Gate Usage |
|---|---|---|
0 | Success | Always pass pipeline |
1 | Error (unreachable backend, bad args, scan failed) | Fail on tool error |
2 | Critical findings detected | Block merge/deploy on critical vulns |
Start a scan and watch live progress until completion. The most powerful single command:
phantom run --target https://app.example.com
# Full power:
phantom run \
--target https://app.example.com \
--type web \
--engagement pentest \
--intensity aggressive \
--rate-limit 100 \
--threads 25 \
--header "Authorization: Bearer eyJ..." \
--header "X-Custom-Header: value" \
--cookie "session=abc123; csrf=xyz" \
--exclude "/logout" --exclude "/health" \
--tool-args "nuclei:-severity critical,high;ffuf:-mc 200,302 -fc 404" \
--out-dir ./findings/2026-04-09
| Flag | Required | Values | Description |
|---|---|---|---|
--target | Yes | URL, IP, CIDR | Target to test |
--type, -T | No | web api network mobile cloud iot firmware sast dast | Attack surface (default: web) |
--engagement, -e | No | pentest bug-bounty red-team compliance audit | Engagement type |
--intensity, -i | No | light standard aggressive exhaustive | Scan depth and aggression |
--auth | No | token string | Bearer/auth token for authenticated scanning |
--rate-limit | No | integer (req/s) | Requests per second (for IDS evasion or rate-limited targets) |
--threads | No | integer | Parallel tool threads |
--header | No | "Key: Value" | Inject custom HTTP headers (repeatable) |
--cookie | No | cookie string | Session cookies for authenticated scanning |
--exclude | No | URL pattern | Skip URL patterns (repeatable) |
--scope-file | No | file path | File with in-scope targets (one per line) |
--tool-args | No | "tool:args;tool:args" | Pass-through flags to individual tools |
--out-dir | No | directory path | Auto-save findings JSON to this directory when scan completes |
The most powerful flag - pipe specific arguments directly to individual tools:
# Only scan for critical/high severity with nuclei; aggressive sqlmap with WAF bypass
--tool-args "nuclei:-severity critical,high;sqlmap:--level=5 --risk=3 --tamper=space2comment"
# Aggressive ffuf fuzzing with custom wordlist
--tool-args "ffuf:-mc 200,301,302,403 -fc 404 -w /wordlists/custom.txt"
# Nuclei with custom templates only
--tool-args "nuclei:-t /path/to/custom-templates"
Start a scan without blocking. Same flags as run, plus:
# Start and return scan ID immediately
phantom scan start --target https://api.example.com --type api --intensity aggressive
# Start and wait (same as `phantom run`)
phantom scan start --target https://target.com --wait --out-dir ./results
Extra flag: --wait - block terminal until scan completes (live progress shown)
Stream live progress for any scan. Shows: progress bar, phase, current tool, finding count, criticals.
phantom scan watch --scan-id abc123
phantom scan watch --scan-id abc123 --interval 5 --out-dir ./results
| Flag | Default | Description |
|---|---|---|
--scan-id | required | Scan to watch |
--interval | 3 | Poll interval in seconds |
--out-dir | - | Auto-save findings when complete |
# All findings
phantom scan findings --scan-id abc123
# Critical only
phantom scan findings --scan-id abc123 --severity critical
# CVSS ≥ 9.0 only
phantom scan findings --scan-id abc123 --min-cvss 9.0
# Save to file
phantom scan findings --scan-id abc123 --out ./findings.json
# Pipe to jq for custom filtering
phantom scan findings --scan-id abc123 --output json | jq '.[] | select(.cve_id != null)'
| Flag | Description |
|---|---|
--scan-id | Required |
--severity <level> | Filter: critical | high | medium | low | info |
--min-cvss <score> | Filter by minimum CVSS 3.x base score (e.g. 7.0) |
--out <file> | Save findings to JSON file - path printed to terminal |
phantom scan status --scan-id abc123 # progress bar + current tool + finding count
phantom scan list # all scans with IDs, targets, status
phantom scan pause --scan-id abc123
phantom scan resume --scan-id abc123
phantom scan cancel --scan-id abc123
Runs Claude AI to develop and validate exploits for confirmed findings.
# Run exploit engine on all findings from a scan
phantom exploit run --scan-id abc123
# Target a specific finding
phantom exploit run --scan-id abc123 --finding-id f001
# Save generated PoC script to file (path printed automatically)
phantom exploit run --scan-id abc123 --save-poc ./poc-CVE-2025-21298.py
# List available exploit modules
phantom exploit modules
| Flag | Description |
|---|---|
--scan-id | Scan to exploit |
--finding-id | Target a specific finding (optional) |
--save-poc <file> | Save the AI-generated PoC script - file path printed to terminal |
# Database stats
phantom cve stats
# Search by keyword
phantom cve search --query "Apache Log4j"
# Filter by CVSS score
phantom cve search --query "RCE" --min-cvss 9.0
# Only actively exploited CVEs (CISA KEV)
phantom cve search --query "spring" --kev-only
# Limit results and save to file (path printed automatically)
phantom cve search --query "deserialization" --min-cvss 8.0 --limit 50 --out ./cves.json
# Full CVE details
phantom cve get --id CVE-2021-44228
# Force sync from NVD
phantom cve sync
| Flag | Command | Description |
|---|---|---|
--query, -q | search | Keyword, CVE ID, or product name |
--min-cvss | search | Minimum CVSS 3.x base score (e.g. 9.0) |
--limit, -l | search | Max results (default: 20) |
--kev-only | search | Only show CVEs on CISA KEV (actively exploited) |
--out <file> | search | Save results to file - path printed to terminal |
--id | get | CVE ID to look up |
# HTML report (saved in current dir as <scan-id>.html - path printed automatically)
phantom report --scan-id abc123
# PDF report to specific file
phantom report --scan-id abc123 --format pdf --output-file ./pentest-report.pdf
# SARIF for GitHub Security / CI integration
phantom report --scan-id abc123 --format sarif --out-dir ./reports
# JSON export
phantom report --scan-id abc123 --format json --output-file results.json
| Flag | Default | Description |
|---|---|---|
--scan-id, -s | required | Scan to report on |
--format, -f | html | pdf | html | sarif | json | md |
--output-file | - | Explicit output file path (overrides --out-dir) |
--out-dir | . (current dir) | Save report as <scan-id>.<format> in this directory |
The saved file path is always printed to the terminal.
# List all campaigns
phantom campaign list
# Create campaign with targets from file
phantom campaign create --name "Q2 Red Team" --targets targets.txt
# targets.txt format (one per line):
# https://app1.example.com
# https://app2.example.com
# 192.168.1.0/24
# Add more targets later
phantom campaign add-targets --id <id> --targets more-targets.txt
# Show campaign status and findings
phantom campaign show --id <id>
phantom history
phantom history --limit 50
phantom history --output json | jq '.[] | select(.critical_count > 0)'
phantom history --limit 100 --out ./history.json # path printed automatically
# List all 52 bundled tools with surface, version, required status
phantom tools list
# Verify all tools are executable
phantom tools check
# Check dependencies (npcap, python, etc.)
phantom tools deps
# Sidecar health + version + uptime
phantom health
# Platform/OS info
phantom sysinfo
Use --verbose to see exactly what API calls are made, timings, and raw responses:
phantom scan status --scan-id abc123 --verbose
# Output:
# → GET http://127.0.0.1:8731/api/scans/abc123
# ← 200 OK 34ms
# ▸ Scan Status
# Scan ID abc123
# Status running
# Progress [████████████░░░░░░░░] 61%
Use --quiet for scripts and pipelines - suppresses all decorative output:
phantom scan findings --scan-id abc123 --output json --quiet | jq '.[] | .title'
All saved file paths are always printed to the terminal.
| Command | Flag | Default Save Location |
|---|---|---|
scan run / scan start --wait | --out-dir <dir> | <dir>/<scan-id>.json |
scan watch | --out-dir <dir> | <dir>/<scan-id>.json |
scan findings | --out <file> | Explicit file path required |
report | --out-dir <dir> | <dir>/<scan-id>.<format> (default: current dir) |
report | --output-file <file> | Explicit file path |
exploit run | --save-poc <file> | Explicit file path |
cve search | --out <file> | Explicit file path |
history | --out <file> | Explicit file path |
name: PhantomYerra Security Scan
on: [push, pull_request]
jobs:
pentest:
runs-on: self-hosted # Windows runner with PhantomYerra installed
steps:
- name: Run web application scan
run: |
phantom run \
--target ${{ vars.STAGING_URL }} \
--type web \
--engagement audit \
--intensity aggressive \
--out-dir ./security-results \
--quiet
# Exit code 2 = critical findings → pipeline fails automatically
- name: Generate SARIF report
if: always()
run: |
SCAN_ID=$(phantom history --limit 1 --output json --quiet | jq -r '.[0].id')
phantom report --scan-id $SCAN_ID --format sarif --out-dir ./security-results --quiet
- name: Upload SARIF to GitHub Security tab
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: security-results/
# Full scan → findings → PDF report in one pipeline
phantom run -q --target https://staging.example.com --type web --out-dir ./results && \
LAST=$(phantom history -l 1 --output json -q | jq -r '.[0].id') && \
phantom report --scan-id $LAST --format pdf --out-dir ./results -q && \
echo "Done. Check ./results/"
# All phantom API calls routed through Burp (127.0.0.1:8080)
phantom run --target https://example.com --proxy http://127.0.0.1:8080 --verbose
PhantomYerra ships a full YerraScan Payload Library - professional-grade wordlists and attack payloads organized by surface, class, and technique. Every scan has access to these sets out of the box. No download, no setup, no separate wordlist manager.
phantom CLI.
Display every built-in payload set, grouped by surface and attack class:
phantom payloads
# Output:
# YerraScan Payload Library - 25 sets, 3,247 entries
#
# SURFACE: web
# web/directories/common 500 entries Common directory and path names
# web/directories/sensitive 120 entries Admin, backup, config paths
# web/xss/reflected 150 entries Reflected XSS payloads (all contexts)
# web/xss/stored 85 entries Stored XSS, tag-breaking variants
# web/xss/dom 60 entries DOM-based XSS, URL fragment payloads
# web/sqli/union-based 100 entries UNION SELECT variants, column probing
# web/sqli/blind-boolean 75 entries Boolean blind injection payloads
# web/sqli/error-based 55 entries Error-based extraction payloads
# web/lfi/traversal 180 entries Path traversal, null-byte, encoding
# web/ssrf/internal 110 entries SSRF to internal services + metadata
# web/ssti/all 95 entries SSTI for Jinja2, Twig, FreeMarker, Pebble
# web/xxe/all 70 entries XXE, OOB, SSRF via XXE payloads
# web/rce/shell-meta 40 entries Shell metacharacter injection
#
# SURFACE: api
# api/endpoints/rest 320 entries Common REST API paths
# api/graphql/introspection 15 entries GraphQL introspection + abuse queries
# api/jwt/secrets 200 entries JWT weak secret candidates
#
# SURFACE: auth
# auth/usernames/common 250 entries Common service and admin usernames
# auth/passwords/top500 500 entries Top 500 common passwords
# auth/credentials/defaults 180 entries Default device + service credentials
#
# SURFACE: cloud
# cloud/s3/buckets 150 entries S3 bucket name candidates
# cloud/azure/storage 90 entries Azure blob container names
# cloud/gcp/buckets 80 entries GCP storage bucket names
#
# SURFACE: network
# network/ports/critical 42 entries Critical port numbers for service discovery
#
# SURFACE: iot
# iot/credentials/devices 200 entries IoT device default credentials
#
# SURFACE: secrets
# secrets/patterns/regex 62 entries Regex patterns for secret detection
Inspect the first entries in any payload set before using it:
phantom payloads show web/sqli/union-based
# Output (first 10 entries shown):
# Payload Set : web/sqli/union-based
# Entries : 100
# Surface : web
# Attack Class: SQL Injection: UNION-based data extraction
#
# 1: ' UNION SELECT NULL--
# 2: ' UNION SELECT NULL,NULL--
# 3: ' UNION SELECT NULL,NULL,NULL--
# 4: ' ORDER BY 1--
# 5: ' ORDER BY 2--
# 6: ' UNION ALL SELECT NULL--
# 7: " UNION SELECT NULL--
# 8: `) UNION SELECT NULL--
# 9: ' UNION SELECT 'a',NULL--
# 10: ' UNION SELECT NULL,'a'--
# ... (90 more entries: use phantom payloads export to save all)
Pass any payload set directly to a scan using --payload-set. The platform loads and uses these entries during the relevant attack phase automatically:
# Directory enumeration with 500 common paths
phantom scan start --target https://example.com --payload-set web/directories/common
# Reflected XSS with 150 context-aware payloads
phantom scan start --target https://example.com --payload-set web/xss/reflected
# UNION-based SQL injection testing
phantom scan start --target https://example.com --payload-set web/sqli/union-based
# LFI / path traversal across all encoding variants
phantom scan start --target https://example.com --payload-set web/lfi/traversal
# SSRF with internal metadata endpoint candidates
phantom scan start --target https://example.com --payload-set web/ssrf/internal
# SSTI against template engines (all major engines covered)
phantom scan start --target https://example.com --payload-set web/ssti/all
# REST API endpoint discovery
phantom scan start --target https://api.example.com --payload-set api/endpoints/rest
# Cloud S3 bucket enumeration
phantom scan start --target target-prefix --payload-set cloud/s3/buckets
# Default IoT credentials bruteforce
phantom scan start --target 192.168.1.1 --payload-set iot/credentials/devices
Combine --payload-set with any other scan flags - --type, --intensity, --header, --rate-limit, etc. The payload set determines the wordlist; all other scan logic runs as normal.
Bring your own wordlist using --wordlist. Accepts any plain-text file, one entry per line:
# Use a custom directory wordlist from SecLists or your own collection
phantom scan start --target https://example.com --wordlist /path/to/directories.txt
# Use a custom credential list for auth testing
phantom scan start --target https://example.com --wordlist /path/to/credentials.txt
# Combine custom wordlist with specific scan type
phantom scan start \
--target https://api.example.com \
--type api \
--wordlist /path/to/api-endpoints.txt \
--intensity aggressive
# Windows path example
phantom scan start --target https://example.com --wordlist "C:\wordlists\custom.txt"
Custom wordlists are streamed directly: no size limit, no preprocessing required. UTF-8 and ASCII both supported.
Save any built-in payload set to disk for inspection or offline use:
# Export to current directory
phantom payloads export web/xss/reflected
# Export to specific file
phantom payloads export web/xss/reflected --out ./xss-payloads.txt
# File path is always printed to terminal after export
| Payload Set | Surface | Description | Entries |
|---|---|---|---|
web/directories/common | Web | Common directory and file path names for enumeration | 500 |
web/directories/sensitive | Web | Admin consoles, backup paths, config file locations | 120 |
web/xss/reflected | Web | Reflected XSS payloads across all injection contexts | 150 |
web/xss/stored | Web | Stored XSS, tag-breaking and event-handler variants | 85 |
web/xss/dom | Web | DOM-based XSS using URL fragments and JS sinks | 60 |
web/sqli/union-based | Web | UNION SELECT variants and column count probing | 100 |
web/sqli/blind-boolean | Web | Boolean-based blind injection payloads | 75 |
web/sqli/error-based | Web | Error-based data extraction payloads | 55 |
web/lfi/traversal | Web | Path traversal, null-byte, double-encoding variants | 180 |
web/ssrf/internal | Web | SSRF to internal services, cloud metadata endpoints | 110 |
web/ssti/all | Web | SSTI payloads for Jinja2, Twig, FreeMarker, Pebble | 95 |
web/xxe/all | Web | XXE, out-of-band exfiltration, SSRF-via-XXE | 70 |
web/rce/shell-meta | Web | Shell metacharacter and command injection payloads | 40 |
api/endpoints/rest | API | Common REST API path fragments for endpoint discovery | 320 |
api/graphql/introspection | API | GraphQL introspection queries and abuse techniques | 15 |
api/jwt/secrets | API | Weak JWT signing secret candidates | 200 |
auth/usernames/common | Auth | Common service and administrative usernames | 250 |
auth/passwords/top500 | Auth | Top 500 most commonly used passwords | 500 |
auth/credentials/defaults | Auth | Default device and service credentials (user:pass pairs) | 180 |
cloud/s3/buckets | Cloud | S3 bucket name candidates for open bucket discovery | 150 |
cloud/azure/storage | Cloud | Azure blob container and storage account names | 90 |
cloud/gcp/buckets | Cloud | GCP Cloud Storage bucket name candidates | 80 |
network/ports/critical | Network | Critical port numbers for targeted service discovery | 42 |
iot/credentials/devices | IoT | Default credentials for common IoT and embedded devices | 200 |
secrets/patterns/regex | Secrets | Regex patterns for API keys, tokens, and secret detection | 62 |
Integrate your own wordlists permanently so they appear in phantom payloads and can be referenced by set name:
# Register a custom payload set
phantom payloads add \
--name "custom/sqli/oracle" \
--file /path/to/oracle-sqli.txt \
--surface web \
--description "Oracle-specific SQL injection payloads"
# It immediately appears in phantom payloads and is usable by name:
phantom scan start --target https://example.com --payload-set custom/sqli/oracle
# Remove a custom set
phantom payloads remove custom/sqli/oracle
Built-in sets (prefixed web/, api/, auth/, etc.) are read-only and updated with each PhantomYerra release. Custom sets survive updates and are stored separately.
| Capability | phantom | Kali/Parrot tools | Metasploit |
|---|---|---|---|
| Unified multi-tool orchestration | ✓ 52 tools, one CLI | ✗ separate per tool | ✗ exploit-focused only |
| AI exploit generation | ✓ Claude AI built-in | ✗ | ✗ |
| CVE intelligence (127k+) | ✓ live + offline | ✗ (searchsploit ~26k) | ✓ module-based |
| SARIF / CI-CD output | ✓ | ✗ | ✗ |
| Campaign management | ✓ multi-target | ✗ | ✓ (Pro only) |
| Rate limiting + thread control | ✓ | ✓ (per-tool) | ✓ |
| Per-tool arg passthrough | ✓ --tool-args | ✓ native | N/A |
| Proxy support | ✓ --proxy | ✓ per-tool | ✓ |
| Interactive exploitation shell | ✗ (GUI handles this) | ✗ | ✓ msfconsole |
| Verbose/trace mode | ✓ --verbose | ✓ per-tool | ✓ |
| Auto-save all outputs | ✓ --out-dir | ✗ manual | ✗ manual |
| Exit code 2 on criticals | ✓ | ✗ | ✗ |