
Phishing simulation and awareness framework for node-based campaigns, credential capture, SMTP delivery, CAPTCHA, and optional browser credential replay.
Phishing simulation and security awareness framework with configurable workflows, campaign management, and optional credential proxy.
cd into it../deploy.sh - this will configure the pre-preqs for you, assuming you are on ubuntu../start.sh --preload-ml. This will start the servers and pre-load the ML models we useYou get the Admin UI at http://localhost:8000 and the phishing server at http://localhost:1234. Default login: admin / admin123. Change the password after first login.
Forward 8000 to your local over ssh to access the admin panel. Do NOT expose the admin panel or flask server (port 1234) directly to the internet.
deploy.sh will install a caddy server on the same host, everything is build assuming you will use caddy as a reverse proxy. You don't have to, but here be dragons.
Optional flags for start.sh:
--with-caddy — Start Caddy via Docker (local testing only).--preload-ml — Pre-download phishing detection model (~1.3GB); avoids first-use delay when using the Phishing Detector plugin.--reset-db — Reset the database and reinitialize.--admin-only — Start only the admin server (port 8000).--phishing-only — Start only the phishing server (port 1234).--skip-init — Skip database initialization.--skip-setup — Skip venv/deps setup; just load .env and start servers.Without start.sh, after installing dependencies and initializing the database you can run both servers with: uv run python -m cli start.
Python: See requirements.txt. Core stack includes Flask, SQLAlchemy, Jinja2, Pydantic, Flask-Login, python-jose, passlib, cryptography, and Flask-WTF. The Phishing Detector plugin uses transformers and torch. The credential proxy uses Playwright; optional integrations use OpenAI/Anthropic and boto3 (AWS Connect).
Development: requirements-dev.txt adds pytest, pytest-cov, and related testing tools. Install with uv pip install -r requirements-dev.txt for running tests and coverage.
System (production): The deploy script targets Ubuntu/Debian. It installs uv, Caddy (reverse proxy), and system packages such as libmagic1. For the credential proxy, start.sh runs uv run playwright install chromium to install Chromium.
Production preparation on Ubuntu. Idempotent. It:
requirements.txt..env from .env.example if missing and generates SECRET_KEY and JWT_SECRET_KEY if not set.storage/caddy/data, storage/caddy/config, storage/uploads, storage/templates, storage/assets, instance).--init-db (runs uv run python -m cli init --force).It does not start the application. For production: start Caddy (reverse proxy), then start the app with ./start.sh or a process manager so all traffic reaches the app via the proxy.
Development and local startup. It:
.env and ensures SECRET_KEY and JWT_SECRET_KEY (generates them if default values are present).requirements.txt.uv run playwright install chromium for the credential proxy.--preload-ml (~1.3GB).--skip-init). Use --reset-db to delete and reinitialize.--with-caddy (local testing only).uv run python -m cli start; use --admin-only or --phishing-only to run one.In production, the application must run behind a reverse proxy. Do not expose the Flask development servers directly to the internet.
The reverse proxy is responsible for TLS termination, correct Host headers, path and domain routing, and separating admin traffic from campaign traffic. The app listens on localhost or an internal port; the proxy handles public HTTPS and forwards to the admin server (e.g. port 8000) and the phishing server (e.g. port 1234) according to your configuration.
Recommended: Use Caddy as the reverse proxy. deploy.sh installs Caddy via APT. The project includes Caddyfile examples (e.g. Caddyfile.minimal). After running deploy.sh, start Caddy (e.g. caddy run --config /path/to/Caddyfile.minimal) and then start the application with ./start.sh or a process manager. Any equivalent reverse proxy (nginx, Traefik, etc.) is acceptable as long as the app is not exposed directly.
Reel is a phishing simulation and security awareness framework. Operators use the admin UI to manage campaigns, workflows, templates, and targets. The phishing server serves campaign landing pages and runs workflows—node-based graphs of plugins—on each request.
There are two application entry points in app.py: create_app() for the phishing server and create_admin_app() for the admin UI. Campaigns can be inbound (a visitor follows a link; GET and POST workflows handle page views and form submissions) or outbound (the system sends emails or calls via sending workflows). Caddy can be used for domain-based routing of campaigns. The credential proxy uses Playwright for browser automation to replay captured credentials on target sites.
A user visits a campaign URL (e.g. /<campaign_uid>). The phishing server routes by campaign UID. For GET requests it runs the campaign’s GET workflow (e.g. render landing page, CAPTCHA); for POST requests it runs the POST workflow (e.g. validate input, capture credentials, redirect). Workflows are of type campaign and declare HTTP method support (GET, POST, or BOTH). Execution context includes campaign, request, session, and variables. The response is taken from context keys such as _response_html, _response_redirect, or _response_json. Inbound workflows are used for landing pages, CAPTCHA, credential capture, redirects, and logging.
An operator runs a sending workflow from the admin UI, linked to a campaign (the campaign’s “Workflow” / sending workflow). The sending executor runs a single workflow of type sending: it selects targets (e.g. from CSV or tracked users), optionally validates or pre-renders content, then iterates over targets—rendering the email, applying rate limits, and sending via a plugin (e.g. SMTP). There is no visitor GET/POST; the workflow generates content and sends it to a list of targets.
Summary:
When building workflows, use {{variable}} syntax for interpolation. Nested paths use dot notation: {{nested.key}}.