This tutorial will walk you through your first ExploitHunter.app research session from start to finish. You'll set up the app, create a project, authorize a target, and run a basic recon session against the bundled Hard Juice Shop lab.
ExploitHunter has two supported ways to run:
- Packaged desktop app: install or build the Electron package for a normal app window. It starts the same local service for you.
- Local service: run the service yourself and open
http://localhost:3210in your OS browser. This is the default path below and the clearest mode for development.
- Node.js >= 24.0.0
- pnpm 12.8.1 via Corepack
- Docker and Docker Compose (v2), only for bundled labs and containerized tooling
- Docker Sandboxes (
sbx0.39 or newer), recommended for isolated development and workspace command execution - Either Ollama installed locally or an OpenRouter API key (dashboard)
Sign in once, then launch the checked-in clone-mode environment:
sbx login
pnpm sandbox:devThe environment gives Codex a private clone, a private Docker daemon, the project's pinned Node 24 and pnpm toolchain, 16 GiB of memory, and host-loopback port mappings. The app keeps stable host port 3210; Docker assigns free host ports for Studio and MinIO so the sandbox can coexist with host services. Run sbx ports exploit-hunter-dev to see them. Inside the sandbox, use the normal pnpm install, docker compose up -d, and pnpm dev commands. Fetch or push commits you want to keep before running pnpm sandbox:remove; removing a clone-mode sandbox deletes its private clone.
The app itself prefers Docker Sandboxes for Mastra workspace commands when it runs directly on the host. Each thread/task gets a stable sandbox that mounts only its canonical workspace and starts with network denied. The checked-in development environment selects the local Mastra backend because the outer microVM is already the isolation boundary and nested Docker Sandboxes are not supported.
The Kali managed lab remains available for authorized workflows that need direct UDP, ICMP, raw sockets, or packet capture; Docker Sandboxes proxy TCP and DNS and intentionally block those direct protocols.
# Clone and enter the repo
git clone https://github.com/justsml/ExploitHunter.app.git
cd ExploitHunter.app
# Use the pinned package manager
corepack enable
corepack prepare pnpm@12.8.1 --activate
# Install dependencies
pnpm install
# Configure environment
cp .env.example .envOpen .env and review the local defaults:
# Everything persistent lives here by default.
EH_DATA_DIR=.data
EH_APP_DB_URL=file:.data/exploit-hunter.sqlite
EH_STORAGE_URL=sqlite://.data/mastra.sqlite
EH_VECTOR_URL=lance://.data/lancedb
EH_ARTIFACT_URL=file:.data/artifacts
# Optional: leave blank to use the local Ollama fallback when available.
OPENROUTER_API_KEY=
# Or use OpenRouter:
# OPENROUTER_API_KEY=sk-or-v1-your-key-here
EH_MODEL_URL=llm://openrouter/deepseek/deepseek-v4-flashThe EH_* values are deployment overrides and remain authoritative over a
previously saved app config. To use PostgreSQL for both application and Mastra
state, set EH_APP_DB_URL and EH_STORAGE_URL to their respective
postgresql://... URIs.
For a local app database, use file:.data/name.sqlite for a project-relative
path and file:///absolute/path.sqlite for an absolute path. The app normalizes
legacy SQLite URL spellings at its configuration boundary.
Start the bundled lab if you want the tutorial target, then start the app:
# Optional lab target
docker compose up -d hard-juice-shop
# Seed demo data (optional, gives you a sample project)
pnpm db:seed
# Start the app
pnpm devOpen http://localhost:3210. If you are using a packaged Electron build instead, open the app; it launches this local service behind the desktop window.
To inspect agents, tools, memory, and traces in Mastra Studio, start it in a second terminal:
pnpm studioOpen http://localhost:4111. Studio uses the configured Mastra store. For concurrent app and Studio processes, use PostgreSQL for shared durable storage or separate SQLite files.
- You should see the Create Project screen (or an empty project list)
- Click New Project and name it something like "Hard Juice Shop Recon"
- Enter a description: "First pass at the bundled Hard Juice Shop"
- Click Create
You now have a durable project with Mastra memory, artifact storage, and a dedicated lab workspace.
Before Hunter can touch anything, you need to declare and authorize the target:
- In the project chat, send:
I want to authorize the target http://127.0.0.1:3323 for testing - Hunter should respond with a target authorization request surface
- Review the target details and click Approve
The target is now authorized for the project. This is deliberate: scope should live in the app's authorization ledger, not in a temporary prompt or environment variable.
Now that your target is authorized, start exploring:
Let's run a baseline HTTP probe against the Hard Juice Shop lab
Hunter will:
- Create a research plan with tasks
- Run an HTTP probe against the target
- Save the probe output as an artifact
- Index the evidence into the project's RAG memory
You'll see the plan panel update with task progress. When the probe completes, the findings surface will show what was discovered.
- Click the Evidence tab in the right panel
- Browse the HTTP probe artifact — it includes the raw request/response
- Hunter may suggest next steps based on what they found
Try these prompts to explore more features:
Create a system map of the target's endpointsCheck for missing security headersRun a deeper probe on the login endpointWalk me through the attack surface
- Check the ExploitHunter roadmap for current priorities
- Read docs/architecture.md for the full system design
| Problem | Likely Cause | Fix |
|---|---|---|
| No projects or artifacts after moving machines | .data was not copied |
Copy the whole .data directory or restore a tar/zip backup of it |
| Agent won't run probes | Target not authorized or active action not approved | Authorize the target in chat and approve the specific probe/action when asked |
| "Model not available" errors | Ollama model not pulled, Ollama missing, or OpenRouter quota exhausted | Run pnpm ollama:gemma4, verify Ollama is installed, or check OPENROUTER_API_KEY billing |
pnpm dev fails on startup |
Missing .env or wrong Node version |
cp .env.example .env, check node --version (must be >= 24.0) |
| Hard Juice Shop not loading | Container not started | docker ps | grep juice-shop should show the lab container on port 3323 |
| Recall quality changed after switching embeddings | Existing vectors were built with another embedding identity | Check .data/lancedb/thread-rag-indexes.json; re-index disk artifacts when prompted |