mailforge
Red-team mail operations toolkit — pixel beacons, landing pages, delivery testing, SPF/DKIM/DMARC offensive analysis, OSINT email harvesting, template variation
v1.0.2Authorized engagements only. mailforge generates outbound material that lands
in target inboxes. Every command that produces a deliverable refuses to start without
--engagement-id and --authorized-by; recipient scope is enforced by
--allow-domain. Use only within a written, signed engagement authorization from the
asset owner.
Quick Start
Install via jcli (recommended)
jcli install mailforge
If you don't have jcli yet, install it first with
curl -fsSL https://cli.johlem.net/tools/jcli/install.sh | bash.
Or install directly
curl -fsSL https://cli.johlem.net/tools/mailforge/install.sh | bash
This drops a single Rust binary at ~/.local/bin/mailforge and verifies its
SHA-256 (and Ed25519 signature, if signify is installed).
Generate per-recipient tracking pixels
mailforge beacon gen \
--to alice@target.com,bob@target.com \
--from noreply@example.com \
--from-name "IT Help Desk" \
--company "Target Corp" \
--base https://t.example.com \
--template password-reset \
--allow-domain target.com \
--engagement-id RT-2026-04 \
--authorized-by "Jane Client" \
--out-dir ./eml
Run the open-tracking callback server
mailforge beacon serve \
--listen 0.0.0.0:8080 \
--log ./opens.jsonl \
--engagement-id RT-2026-04
Report on captured opens
mailforge beacon report ./opens.jsonl
mailforge beacon report ./opens.jsonl --output markdown
mailforge beacon report ./opens.jsonl --output json --out-file report.json
Offensive SPF / DMARC posture check
mailforge spoof check example.com
mailforge spoof lookalikes paypal.com
OSINT email harvesting
mailforge harvest crt-sh target.com
mailforge harvest wayback target.com --limit 50
mailforge harvest pattern target.com --names-file ./names.txt
What it does
mailforge consolidates the originally-planned six standalone red-team mail tools under one binary. Each subcommand shares the same engagement context, AUTHORIZED gate, HMAC token signer, operator secret store, evidence directory, and output formatter. One engagement uses one secret, one auth audit trail, one evidence tree.
- One unified binary. Beacon + landing + bench + spoof + harvest + spin
all behind
mailforge <subcommand>. - Engagement-mandatory gates. Every output-producing subcommand refuses
to run without
--engagement-idand--authorized-by. Domain scope enforced by--allow-domain. - HMAC-SHA256 tokens. Tracking pixels carry per-recipient tokens verified server-side; no cleartext recipient in URLs.
- AES-256-GCM credential encryption. Capture files (landing-page form submissions etc.) encrypted at rest with PBKDF2 600k-iter passphrase key.
- Pipe-clean output. Every command supports
--output {json,csv,markdown}and-O/--out-filefor stable scripting / SIEM ingest.
Subcommands
| Command | What it does |
|---|---|
beacon gen | Per-recipient .eml generation with HMAC-tokened tracking pixel + suite signature header. |
beacon serve | axum HTTP server. GET /p/{token}.png returns the embedded 67-byte 1×1 PNG + appends JSON-Lines event per hit. Honors X-Forwarded-For. |
beacon report | Aggregate opens.jsonl into per-recipient table with UA-derived client family. |
beacon templates | List 8 embedded pretexts with MITRE mapping: plain, password-reset, security-notice, shared-document, meeting-invite, invoice, package-delivery, mfa-setup. |
land serve | axum landing-page server with 3 embedded clones (M365 / Google / Okta). POST capture → JSONL, redirect to legitimate provider login. |
land templates | List the embedded landing templates. |
bench send | Minimal SMTP client (plain port 25/587, AUTH LOGIN). Probe message + full transcript with per-line codes. |
bench mx | DNS MX lookup, sorted by preference. |
spoof check | Offensive SPF + DMARC posture: Open / Permissive / Strict / LockedDown verdict + per-record exploit notes. |
spoof lookalikes | 4 generator families: homoglyph (ASCII confusables), IDN (Cyrillic with Punycode), typo (drop / transpose / hyphen), TLD swap. |
harvest crt-sh | Pull every cert from crt.sh, regex-extract in-scope email addresses from Subject CN. |
harvest wayback | Walk Wayback CDX captures (capped), regex-extract @<domain> mentions. |
harvest pattern | Names-file × 12 patterns (first.last, flast, first.l, lastfirst, …) → candidate addresses. |
spin | ~token~ word-bank substitution. 30+ token sets (calls-to-action, urgency, salutations, finance, IT pretexts). Deterministic via --seed. |
Pretext templates (beacon)
Eight pretexts ship embedded with MITRE ATT&CK mapping in the slug label.
Operators select with --template <slug>.
| Slug | Scenario | MITRE |
|---|---|---|
plain | Blank — pixel + minimal HTML wrapper. | — |
password-reset | IT password-expiry notice with renewal link. ~spin~-tokenised. | T1566 + T1078 |
security-notice | Suspicious-sign-in notice (Entra / Google style). | T1566 + T1078.004 |
shared-document | SharePoint / Drive share notification. | T1566 + T1204.001 |
meeting-invite | Calendar invite preview. | T1566.001 |
invoice | Overdue-invoice pretext (BEC). | T1566 + T1534 |
package-delivery | Courier redelivery pretext. | T1566.002 |
mfa-setup | Force-MFA-enrolment pretext. | T1528 + T1098.005 |
On-disk layout
~/.local/bin/mailforge # the static binary itself
~/.local/bin/mailforge.bak # previous version (rollback target)
~/.mailforge/secret # 32-byte HMAC secret (chmod 600, auto-init from /dev/urandom)
~/.local/share/mailforge/ # per-tool data dir (catalogues, state)
MAILFORGE_HOME overrides the secret-store location so each engagement can
scope into its own secret (separate engagements should not share secrets).
Design choices
- Unified, not modular distribution. One binary, not six. The shared gate / secret / output / signature infrastructure is too valuable to fragment.
- No SMTP send built into
beacon. Generates.eml; delivery is through the operator's own authorised mail server (msmtp / swaks / engagement relay). Decouples message authorship from sending infra. - No TLS termination on the servers. Both
beacon serveandland serveare HTTP-only — wrap with caddy / nginx for TLS. Keeps the binary small and rotates secrets via reverse-proxy config. - Mandatory engagement scope. A red-team binary that produces outbound material without an engagement reference is malware; we refuse before doing anything.
Authorization: mailforge generates and serves material that targets real
inboxes / browsers. Run only within a written, signed engagement authorization from the asset
owner. The auth-log captured at engagement time
(X-Mailforge-Engagement + X-Mailforge-Authorized-By headers in
every generated .eml) is the audit-trail that proves authorization to an
incident-responder who discovers the payload.
Review every script before piping into bash: install.sh · mailforge/install.sh