GitHub RadarNeeds classification review
Give a man a 0day and he'll have access for a day, teach a man to phish and he'll have access for life. Primary language: Go. 5 stars.
Insufficient evidence to assign a team focus.
Project links:Open GitHub projectBack to radar
<p align="right"> <b>English</b> · <a href="README.zh.md">简体中文</a> · <a href="README.zh-TW.md">繁體中文</a> · <a href="README.ja.md">日本語</a> · <a href="README.ko.md">한국어</a> </p>
<p align="center"> <picture> <source media="(prefers-color-scheme: dark)" srcset="assets/readme/logo-dark.svg" /> <img src="assets/readme/logo.svg" alt="Spearhook" width="96" height="96" title="Spearhook" /> </picture> </p>
<h1 align="center">Spearhook</h1>
<p align="center"> <strong>Self-hosted phishing simulation console for authorized red teams</strong> </p>
<p align="center"> Go + Gin · Next.js · SQLite · single binary · optional remote agents </p>
<p align="center"> <a href="https://spearhook.pages.dev/">Live demo</a> · <a href="#legal-notice">Legal</a> · <a href="#overview">Overview</a> · <a href="#features">Features</a> · <a href="#architecture">Architecture</a> · <a href="#quick-start">Quick start</a> · <a href="#agents">Agents</a> · <a href="#console">Console</a> · <a href="#disclaimer">Disclaimer</a> </p>
---
Spearhook is intended exclusively for authorized security testing, red-team exercises, and phishing awareness training.
Unauthorized use against systems, accounts, or individuals is unlawful. Users are solely responsible for obtaining authorization and for their operation of this software. The authors and contributors accept no liability for misuse.
Do not use Spearhook without written authorization or other clearly verifiable authorization.
---
Spearhook is a self-hosted phishing simulation console covering landing-page hosting, email delivery, open and click tracking, credential capture, and real-time submission notifications. Pages can run on the control plane or be deployed to remote agents.
For readers familiar with Gophish: that toolkit focuses on campaigns and templates, whereas Spearhook is an end-to-end operations console for the engagement. It combines an AI-assisted page library, an AI operations assistant, multi-agent deployment, live QR relays, AI-powered OSINT collection, webhooks, IP blacklisting, audit logging, and role management.
One Go binary embeds the UI (frontend/dist) and serves API + console on the same port. Stack: Go 1.24 / Gin / GORM+SQLite / Next.js static export / optional Docker SDK. Live demo: https://spearhook.pages.dev/.
---
/chat). Token-level SSE streaming via a whitelisted tool registry (list_agents, clone_page, create_project, start_info_gather, create_mail_draft, send_mail_campaign, QR/credentials/blacklist, …). Read-only tools execute automatically, destructive actions require confirmation, and every write is recorded in the audit log. The assistant does not generate HTML directly; URL mirroring is handled by the page-library pipeline.chat/completions or Anthropic /messages). Relative CSS/assets are absolutized against the source origin so previews keep styles./api/<slug>). Optional HTML noise. Tracking public URL and HMAC live under System → Mail Tracking./q/{slug}.png. A local capture script uploads screen frames; pages use {{QR_RELAY_URL}} / {{QR_RELAY_IMG}}.web_search, DeepSeek Search, Brave, Tavily, Serper, or Bocha). Collect publicly available email addresses and phone numbers with sources, export them as CSV, and use them for mail delivery.spearhook-agent runs on additional hosts. A single agent can host multiple projects, and a single project can be deployed to multiple agents. Agents provide heartbeats and buffer access logs in pending-logs.json for retransmission after recovery. Credential submissions are proxied to the control plane in real time; if the control plane is unreachable, visitors receive HTTP 502 (no submission queue is provided).Standard workflow: Configure SMTP and webhooks → mirror or upload a page → create a project (bind agents and push channels) → send mail → await submission notifications → review records. If submission volume is abusive, add the source IP to the blacklist.
---
Browser (i18n UI · JWT · optional Basic Auth)
│
▼
Control plane (Go / Gin · SQLite · embedded Next UI · Assistant SSE)
│
┌─────┴──────────────┐
▼ ▼
Docker / local Flask Remote spearhook-agent(s)
│ │
└─────────┬──────────┘
▼
submits · access logs · mail open/click · live QR · webhooks| Piece | Role | |-------|------| | Control plane (spearhook) | Console, API, SQLite, mail tracking endpoints, QR public URL, AI assistant orchestrator | | Agent (spearhook-agent) | Edge landing-page runtime; initiates an outbound connection to the control plane | | Frontend | Next.js App Router → static frontend/dist, embedded via go:embed | | AI profile | One enabled OpenAI-compatible or Anthropic Messages endpoint for page mirror, assistant tools, and info gather | | Search provider | Web search for info gather: native web_search or DeepSeek / Brave / Tavily / Serper / Bocha |
---
Linux, macOS, or Windows.
| Need | Notes | |------|--------| | Run a release | Binary + config.yaml | | Build from source | Go 1.24+, Node.js (frontend) | | Docker run mode | Docker Engine reachable; skip if you only use local Flask / agents | | Local Flask run mode | python3 + flask, flask_cors, requests | | QR capture | Python 3 + zip from Workbench → QR Phishing (or `scripts/qr-relay`); macOS decode wants zbar | | Agents | Must reach the control plane over HTTP(S) |
| What | Default | |------|---------| | Console / API | :8000 | | Frontend dev | :8081 → proxies /api to :8000 | | Agent landing ports | 20000–30000/TCP on the agent host |
cp config.yaml.example config.yamlReplace placeholders before a real engagement:
server:
port: 8000
gin_mode: release
database:
path: ./data/fishing.db
security:
encryption_key: replace-with-a-generated-key
jwt_secret: replace-with-a-long-random-secret
container_secret: replace-with-another-long-random-secret
agent_registration_token: replace-with-agent-registration-token
platform_basic_auth_enabled: true
container:
ssl_cert_path: /app/certificates/cert.pem
ssl_key_path: /app/certificates/key.pemcmd/generate-encryption-key can mint encryption_key. Mail tracking (public URL, HMAC, redirect allow-list) is configured under System → Mail Tracking after boot — YAML is seed/fallback. Click/open paths are generated per campaign.
Do not commit config.yaml, data/, or TLS keys (gitignored).
./spearhook
# or a build from ./release/ after ./scripts/build-all.shEmpty/default secrets trigger a startup confirm — fine on a lab box. Rotate them before a real job.
./scripts/build-all.shBuilds the frontend, then control plane + agent for linux / windows / darwin (amd64 & arm64), and copies config.yaml.example + agent.yaml.example into release/.
UI only (API already up):
cd frontend && npm install && npm run dev # http://127.0.0.1:8081Open http://localhost:8000 (or your server.port). First boot writes admin credentials to:
cat data/admin_password.txtSave the password, then delete the file. Later resets: cmd/reset-password.
---
Deploy spearhook-agent to additional hosts when not every landing page should run on the control plane. A single project can be deployed to multiple nodes, and a single node can host multiple projects. Each binding has its own port, revision, and logs. Credential submissions are proxied to the control plane in real time; access logs are buffered in pending-logs.json and retransmitted when the control plane becomes reachable again.
Project ports default to `20000–30000/TCP`. The agent initiates an outbound connection. Visitors access the agent directly; when it is behind a reverse proxy, configure advertise_host as described in the full guide.
Token — set security.agent_registration_token on the plane (not the JWT secret) and restart. First register uses that shared token once; then {work_dir}/state.json holds the per-agent id/token (0600 on Linux/macOS).
Start — after ./scripts/build-all.sh:
cp agent.yaml.example agent.yamlserver_url: http://control-plane.example.com:8000 # no trailing slash
registration_token: replace-with-a-long-random-agent-tokenchmod +x ./spearhook-agent
./spearhook-agent -config ./agent.yaml.\spearhook-agent-windows-amd64.exe -config .\agent.yamlYou want a log line like agent … connected to http://….
In the UI — System → Agents until online (~90s without heartbeat = offline). Projects → New, pick agents, attach a page. Each agent is its own instance (pending → deploying → running). Edit = new revision; add agent = deploy; uncheck = delete task.
systemd, Windows service, reverse proxy: [docs/agent-deployment.md](docs/agent-deployment.md).
---
| Area | What you do there | |------|-------------------| | Dashboard | Counts and host CPU / memory | | AI Assistant | Natural-language ops via platform tools (clone, create project, list agents, …) | | Projects | Overview, deployments, logs, credential records | | Workbench → Page Builder | Upload HTML or AI-mirror a URL into the page library | | Workbench → Send Email | Templates, campaigns, open/click | | Workbench → Info Gathering | AI web search → contacts CSV | | Workbench → QR Phishing | Live QR relays + capture script zip | | Push Channels | Webhooks on credential submission | | Agents | Online status / last seen | | IP Blacklist | Block abusive source IPs (added from credential records) | | Mail Services | SMTP profiles | | Users / AI Settings / Mail Tracking | Admin | | Audit Logs | Admin; immutable in-product |
Pages POST to /api/submit by default. HTML placeholders: {{SUBMIT_URL}}, {{REDIRECT_URL}}, {{QR_RELAY_URL}}, {{QR_RELAY_IMG}}, …. Mail: {{email}}, {{click_url}}, {{open_pixel}}, {{landing_url}}, ….
Guides: EN · ZH · ZH-TW · JA · KO
Access log: `data/access-YYYY-MM-DD.l