duriantaco/ravage

GitHub: duriantaco/ravage

Stars: 2 | Forks: 0

Ravage logo

# Ravage Ravage is a source-available research workspace for autonomous web application penetration-testing agents on controlled, authorized targets. The current system includes: - `ravage attack`: the model-driven `ai-web` loop with scoped tool execution, audit events, reports, resume support, and an optional live observer. - `ravage scan`: deterministic DAST probes that reuse the same scope, audit, workspace, and report shape without spending model turns. - `ravage lab`: deliberately vulnerable local lab boxes for reproducible testing. - Tool-runtime preflight for host or Docker scanners such as `nmap`, `ffuf`, `katana`, `nuclei`, and `sqlmap`. - Optional local Ravage Memory for reviewed, redacted, replay-backed lessons. - Benchmark harnesses for local manifests, isolated competitor comparisons, and XBEN-style controlled runs. ## Responsible Use Read [DISCLAIMER.md](DISCLAIMER.md) and [LICENSE](LICENSE) before running anything. Ravage is provided for research under a restrictive research license; it is not open-source software. Only use Ravage against systems you own or have explicit written authorization to test, inside the agreed rules of engagement. Do not run it against public internet targets, production services, customer environments, employer systems, or any machine outside your authorization. The lab boxes in this repository intentionally contain serious vulnerabilities. Run them only on localhost or an isolated private lab network. Do not expose them to a public or shared network. ## Scope Enforcement Ravage is localhost-first. Remote targets require `--allow-remote-target` and must be explicitly listed in the engagement `scope.in_scope`. HTTP and browser actions are checked against scope, redirects are rechecked before following, and terminal tools are allowlisted to scoped network tools only. For Docker-backed tool runtime, Ravage applies the rendered egress firewall inside each tool container before the tool starts. The audit log records `orchestrator/scope_firewall_plan_generated` and `orchestrator/scope_firewall_rules_applied` with a rule digest; if the container cannot apply the rules, the run fails closed unless `--allow-degraded` is set. The `ravage attack` and `ravage scan` wrappers default to `--tool-runtime auto`; in scoped runs, `auto` uses the Docker-backed path for supported external tools so those firewall rules are present. Host tool runtime still relies on application-layer scope checks rather than kernel-level host firewall changes. Use `--tool-runtime host` only when that degraded enforcement model is acceptable, or `--tool-runtime docker` when Docker must be required explicitly. Firewall destinations remain IP/CIDR-only, so hostname scope entries are skipped rather than relying on DNS at rule-install time. Localhost scopes get a Docker `host.docker.internal` gateway exception for the explicit scoped ports. ## Install From Source Ravage is currently a source-checkout project. There is no published Ravage PyPI release yet, and there are no tagged releases yet. Use Python 3.12. The workspace is managed with `uv`: uv sync --frozen source .venv/bin/activate ravage --help ravage --version For a fresh local wheel-style install without relying on the checkout venv, install the shared schemas and runtime package together: python3.12 -m venv .venv .venv/bin/python -m pip install packages/schemas packages/ravage .venv/bin/ravage --help .venv/bin/ravage --version External scanners are not Python dependencies. The smoothest source-checkout path is the helper script: scripts/install_tools.sh --execute That script sets repo-local `PATH`, `HOME`, and XDG state directories, creates `.tools/bin` when needed, runs the selected install plan, and then runs `ravage tools check` in the same environment. On Linux/Kali/WSL, the host install path is: scripts/install_tools.sh --method apt --execute The apt step may prompt for your sudo password. It installs the apt-available tools such as `nmap`, `whatweb`, `gobuster`, `dirb`, `nikto`, `sqlmap`, and network utilities. Go-based tools that are not reliably available from older Ubuntu apt repositories, such as `ffuf`, `katana`, and `nuclei`, are installed into `.tools/bin`. If `go` is not installed, the installer downloads a repo-local Go toolchain under `.tools/go-root`. When Docker is available and you want the most repeatable runtime: scripts/install_tools.sh --method docker --execute To preview without changing the machine, omit `--execute`: scripts/install_tools.sh --method apt ravage tools install ravage tools check The lower-level `ravage tools install` command is always a dry run unless `--execute` is passed. ## Local Lab Quickstart List the local boxes: ravage lab list ravage lab up ravage-acme-box Run a deterministic scan: ravage scan labs/ravage-acme-box/brief.yaml \ --profile web-basic \ --max-actions 40 \ --observe Run the model-driven agent with a hosted OpenAI-compatible profile: export OPENAI_API_KEY=... ravage attack labs/ravage-acme-box/brief.yaml \ --observe \ --model-profile hosted-openai \ --model-tier low \ --tool-runtime auto \ --tool-image ravage-kali:latest \ --memory off \ --allow-paid-models Stop the box: ravage lab down ravage-acme-box Every `ravage attack` run writes: runs/-/ audit.db agent.stdout report.json workspace/ Every `ravage scan` run writes the same shape, with `scan.stdout` instead of `agent.stdout`. Audit rows are hash-chained as they are written. Verify an untouched run directory or direct database path with: ravage audit verify runs/- ravage audit verify runs/-/audit.db Resume a previous run by pointing at the run directory, workspace directory, or `report.json`: ravage attack labs/ravage-acme-box/brief.yaml \ --resume-from runs/brief-YYYYMMDDHHMMSS/report.json Attach the observer to an existing run: ravage observe runs/brief-YYYYMMDDHHMMSS \ --lab-manifest labs/ravage-acme-box/ravage-lab.yaml To run the recon-heavy perimeter lab, substitute `ravage-perimeter-box`. Its brief explicitly scopes both `http://127.0.0.1:8094` and `http://127.0.0.1:8095`, and requires port scanning plus directory brute-force capabilities: ravage lab up ravage-perimeter-box ravage attack labs/ravage-perimeter-box/brief.yaml \ --observe \ --observe-port 8790 \ --model-profile hosted-openai \ --model-tier low \ --tool-runtime auto \ --tool-image ravage-kali:latest \ --tool-recon \ --memory off \ --allow-paid-models The live web UI does not display credentials. Assisted-mode seed credentials live in each lab's `OPERATOR_NOTES.md`; omit that file from the agent context for stricter black-box testing. The dashboard masks captured flag values by default but shows counts, proof status, agent steps, and the current attack-chain stage. `ai-web` tracks coverage as access state changes. A probe that is blocked by authentication or privilege is not treated as permanently done; after a cookie, header, browser login, default-credential success, or JWT privilege change, the agent releases those blocked candidates for retry. Confirmed command injection and local file inclusion also get tiny read-only flag follow-ups on localhost capture-flag labs only. This is deliberately evidence-gated so the agent covers more ground without learning lab-specific paths or treating memory as proof. The same coverage ledger now records all paths attempted by bounded multi-path probes, so failed variants do not burn later turns as if they were still fresh. JSON account/config routes can also be checked with a bounded business-logic probe for mass-assignment or merge-style privilege changes. ## Included Labs | Lab | Default URL | Difficulty | Flags | Main coverage | | --- | --- | --- | ---: | --- | | `ravage-acme-box` | `http://127.0.0.1:8088` | medium | 4 | login, IDOR, SQLi, weak JWT, SSRF | | `ravage-forgeops-box` | `http://127.0.0.1:8090` | hard | 6 | BOLA, query injection, JWT, traversal, command injection, SSRF | | `ravage-node-market-box` | `http://127.0.0.1:8092` | medium | 5 | BOLA, SQLi, JWT confusion, config merge abuse, SSRF | | `ravage-perimeter-box` | `http://127.0.0.1:8094` and `:8095` | hard | 5 | multi-port recon, hidden paths, default credentials, SQLi, traversal | See [BENCHMARKS.md](BENCHMARKS.md) for scoring rules and latest local run notes. ## Model Providers `ai-web` uses OpenAI-compatible chat-completions routes. Built-in profiles cover local Ollama, LM Studio, vLLM, LiteLLM, and hosted OpenAI-compatible APIs. Inspect routes: ravage --print-model-routes \ --model-profile local-ollama \ --model-tier mid Use hosted models only with explicit spend acknowledgement: ravage attack labs/ravage-acme-box/brief.yaml \ --model-profile hosted-openai \ --model-tier low \ --allow-paid-models See [docs/model-providers.md](docs/model-providers.md) for provider-specific environment variables. ## Memory Ravage Memory is local and optional. It stores redacted candidate lessons in SQLite, retrieves reviewed memories as advisory hints, and only promotes replay-backed lessons. ravage memory review ravage memory show ravage memory promote --reason "replayed on controlled target" --replay-passed ravage memory reject --reason "overfit or noisy" ravage memory export --redacted ravage memory gc Benchmarks default memory to `off` for reproducibility. Normal local/manual runs default to `read`. See [docs/memory.md](docs/memory.md). ## Benchmarks Run the deterministic local SQLi benchmark: ravage --benchmark eval/local_sqli_manifest.yaml \ --output-dir runs/benchmarks/local-sqli Run the `ai-web` benchmark with a local model route: RAVAGE_OLLAMA_MODEL=qwen2.5-coder:32b \ OLLAMA_BASE_URL=http://localhost:11434/v1 \ ravage --benchmark eval/ai_web_manifest.yaml \ --output-dir runs/benchmarks/ai-web-local For hosted routes, preflight before spending: OPENAI_API_KEY=... \ ravage --benchmark eval/ai_web_manifest.yaml \ --output-dir runs/benchmarks/ai-web-hosted-preflight \ --benchmark-model-profile hosted-openai \ --benchmark-model-tier low \ --benchmark-limit 1 \ --benchmark-max-turns 4 \ --benchmark-max-model-requests 4 \ --benchmark-preflight Fake-model tests only prove loop mechanics and scoring behavior. They are not benchmark scores. For Ravage versus external-agent comparisons, run the isolated competitor harness preflight before setting up any large competitor images: ravage competitors preflight \ --config eval/competitor_harness.example.yaml \ --output-dir runs/competitors/preflight The default preflight blocks below 20 GiB free disk. See [Competitor Harness](docs/competitor-harness.md). ## Validation Run the fast tests: python -m pytest packages/schemas packages/ravage/tests tests Run the scope-enforcement integration test when Docker is available: python -m pytest -k test_scope_enforcement ## Docs - [Responsible Use Disclaimer](DISCLAIMER.md) - [License](LICENSE) - [Docs Index](docs/README.md) - [AI Web Operator Guide](docs/ai-web-operator-guide.md) - [Model Providers](docs/model-providers.md) - [Ravage Memory](docs/memory.md) - [Benchmarking](docs/benchmarking.md) - [Competitor Harness](docs/competitor-harness.md) - [Benchmarks And Local Test Boxes](BENCHMARKS.md) Planning and strategy documents under `docs/` are useful project history, but the README, operator guide, benchmark docs, and CLI help are the operational source of truth. ## Packaging Many established Python security tools do publish installable packages on PyPI. Examples include `sqlmap`, `pwntools`, `impacket`, `mitmproxy`, `wapiti3`, `wafw00f`, `dirsearch`, `wfuzz`, and `arjun`. Some still recommend git, Docker, Kali packages, or OS package managers for particular workflows, and PyPI does not install non-Python scanners such as `nmap`. Ravage is now arranged so the publishable runtime package is `packages/ravage`, with distribution name `ravage`, import package `ravage`, and console command `ravage`. The repository root is still a development workspace named `pentest-agent`; do not publish the workspace root. The shared schema models are prepared as a small companion distribution, `ravage-schemas`, with the existing Python import package `pentest_schemas`. Before a PyPI release: - reserve `ravage` and `ravage-schemas` on PyPI and TestPyPI; - publish/install `ravage-schemas` before `ravage`; - decide whether any other workspace members need separate public packages; - keep vulnerable labs, benchmark fixtures, run artifacts, and large assets out of the wheel unless explicitly packaged as separate lab extras; - keep external scanner installation in `ravage tools install`, not Python dependencies; - test the final wheel on TestPyPI in a clean virtual environment. The repository includes a GitHub Actions workflow at `.github/workflows/publish-pypi.yml` for PyPI Trusted Publishing. Configure pending PyPI publishers for both `ravage-schemas` and `ravage` with: - owner: `duriantaco` - repository: `ravage` - workflow: `publish-pypi.yml` - environment: `pypi` Version bumps are automated by Release Please. When conventional commits land on `main`, `.github/workflows/release-please.yml` opens or updates a release PR that bumps both publishable package versions together, updates source fallback versions, and refreshes `CHANGELOG.md`. Merging that release PR creates the matching GitHub release tag, for example `v0.0.1`. Configure `RELEASE_PLEASE_TOKEN` with a token or GitHub App credential if the generated release should trigger the downstream PyPI publish workflow. Publishing is triggered by publishing a GitHub release whose tag matches the package version. ## Versioning Ravage uses semantic versioning for publishable packages and tags. Release tags should use `vMAJOR.MINOR.PATCH`, for example `v0.0.1`, and the package versions in `packages/schemas/pyproject.toml` and `packages/ravage/pyproject.toml` should match the tag without the leading `v`. Conventional commit titles drive the automated bump: `fix(...)` maps to patch, `feat(...)` maps to minor, and breaking-change markers map to major. While Ravage is pre-1.0, minor releases may include breaking changes as the agent APIs, report shape, and packaging surface settle. Patch releases should be limited to compatible bug fixes, docs corrections, and packaging fixes.