Cymail — Subcommand Reference
Every subcommand accepts --format json | sarif | csv | html for
machine-readable or shareable output. The defaults below assume the
human text format unless noted.
discover
theHarvester-style email discovery + reputation, with safer SMTP probes and EmailRep.io enrichment per address.
cymail discover --domain example.com
cymail discover --domain example.com --no-smtp # skip SMTP RCPT-TO
cymail discover --domain example.com --no-reputation
cymail discover --domain example.com --seed alice,bob
What it does
- crt.sh — Certificate Transparency SAN harvest for
*@example.com-shaped addresses - DNS SOA RNAME — extracts the responsible-party email baked into the SOA record
- Pattern guessing — common seed names (
admin,security,support, …) + custom seeds - MX RCPT-TO validation — opt-out via
--no-smtp; uses minimal SMTP, never sends DATA - Catch-all probe — single random RCPT against MX; if accepted, validation is suppressed (otherwise every guess looks "valid")
- EmailRep.io reputation — per-address; flags blacklisted / malicious / credentials_leaked / data_breach
JSON output shape: DiscoveryReport { domain, mx_hosts, catch_all, emails[], sources_queried, elapsed_ms }.
reputation
DNS-only signals — safe to run on third-party domains without consent. No SMTP. No POST. No state mutation.
cymail reputation --domain example.com
cymail reputation --domain example.com --no-trust # skip DNSWL
cymail reputation --domain example.com --no-talos
cymail reputation --domain example.com --dkim-selectors mail,smtp,sg
Signals collected
- DNSBL — Spamhaus DBL/SBL/Zen, SURBL, URIBL, Barracuda BRBL + DNSWL trust list
- BIMI — brand-indicator record detect + URLs
- BIMI VMC PKIX chain validation (v0.6.3) — fetches the SVG + cert chain at
l=/a=, validates:- SVG content-type, size (≤32 KB), no
<script>, no externalxlink:href - Cert chain parse (leaf + intermediate(s))
- Leaf subject matches the BIMI domain (CN or SAN)
- Leaf within
not_before/not_after - Issuer CN contains the "Verified Mark" marker (DigiCert / Entrust VMC CAs)
- Leaf carries EKU OID 1.3.6.1.5.5.7.3.31 (
id-kp-bimiIdentifier) — three-step detection (structured EKU walk → raw extension byte scan → full DER scan)
- SVG content-type, size (≤32 KB), no
- DANE TLSA on each MX:25
- DNSSEC (DNSKEY + DS at apex)
- SPF lookup count vs RFC 7208 §4.6.4 cap of 10 (catches silently-broken records that nest too many
include:s) - DKIM key hygiene — RSA
<2048= weak, Ed25519 = ok, missingp== revoked - MX provider fingerprint — 20+ vendors mapped (Microsoft 365, Google Workspace, Proofpoint, Mimecast, IronPort, Barracuda, SES, Mailgun, …)
- Sender Score (v0.6.0, opt-in) — Validity per-MX-IP 0-100. BYO key via
SENDERSCORE_API_KEY. - Cisco Talos reputation (v0.6.0) — apex-domain email + web reputation. Public web API, no key.
The optional extensions field on ReputationReport carries the Sender
Score + Talos results. Older JSON consumers that ignore unknown keys see
no schema change.
leak
HIBP domain breaches, GitHub code search for the domain near secret-shaped neighbours, lookalike-domain enumeration, and commercial breach feeds.
cymail leak --domain example.com
cymail leak --domain example.com --no-lookalikes # skip the slow crt.sh scan
cymail leak --domain example.com --no-hibp --no-github
cymail leak --domain example.com --lookback-days 30
cymail leak --domain example.com --watch # certstream subscription
cymail leak --domain example.com --watch --watch-seconds 600
Default sources
- HIBP
/breaches?domain=— free, unauthenticated. Returns each breach the domain appears in. - GitHub code search for
@example.comnearpassword|secret|apikey. Reports repo + path + URL, never line content. HonoursGITHUB_TOKENfor higher rate limit. - Lookalike-domain enumeration + crt.sh cert-issuance check — 30-50 variants per domain (TLD swaps, dashes, homoglyphs, edit-distance-1, brand-impersonation suffixes), each checked against crt.sh in a configurable lookback window.
--watch (v0.6.1)
Replaces the per-variant crt.sh poll with a push-based CertStream subscription. WS connects, filters the global CT log feed against the lookalike set, emits one JSON line per match. Best-effort reconnect on disconnect.
cymail leak --domain example.com --watch | jq .
Commercial feeds (BYO key, v0.6.2)
Each is independently optional via its own env var. 24h disk cache under
$XDG_CACHE_HOME/cymail/feeds/ so repeated runs don't burn the API
budget.
| Feed | Env var | Format |
|---|---|---|
| DeHashed | DEHASHED_API_KEY | email:apikey |
| IntelX | INTELX_API_KEY | API key |
| SnusBase | SNUSBASE_API_KEY | API key |
Results land on LeakReport.commercial_feeds_v2 with structured
records — record_type / value / breach_label / exposed_at / severity.
rua
DMARC aggregate (RUA) XML report parser + rollup. Closes the dmarcian
moat — receivers like Google, Microsoft, Yahoo, Outlook, Amazon SES,
and Mailgun mail back XML aggregate reports to the address in your
DMARC rua= tag. cymail rua consumes those.
Parse one report
cymail rua parse --file google.com!example.com!1735689600!1735776000.xml
cymail rua parse --file report.xml.gz
cymail rua parse --file google-yyyy-mm.zip
Accepts .xml, .xml.gz, and .zip (multiple .xml inside) automatically.
JSON output: DmarcReport { org_name, email, report_id, date_range, policy_*, records[] } with one DmarcRecord per source-IP/header-from combination.
Aggregate a directory
cymail rua aggregate --dir ./rua-mailbox --domain example.com
Walks the directory (non-recursive), parses every .xml / .xml.gz /
.zip, deduplicates by report_id, and produces a RuaRollup:
reports_seen,records_seen,messages_total,messages_alignedby_source_ip[]— per-IP message count, DKIM/SPF alignment, dispositions, observed header_fromsby_org[]— per-reporting-org count + total messagesorphan_records— count of records whosepolicy_domaindidn't match--domain(so mixed-domain mailboxes work)
Pipe to jq for inline pivot:
cymail rua aggregate --dir ./rua-mailbox --domain example.com \
| jq '.by_source_ip | sort_by(-.messages) | .[0:10]'
header
Forensic analysis of one received email (RFC 5322). Four classes of check:
cymail header --file message.eml
cymail header --file message.eml --format json # full structured output
cymail header --file message.eml --format sarif # platform-ingestable
1. Received chain walk
Parses each Received: header, reverses to oldest-first order, extracts
from, by, with, and parses the timestamp. Flags:
- Backwards timestamps between hops — strong forgery signal (severity
high) - Loopback HELOs (
localhost,[127.0.0.1],[::1]) - Generic-looking HELOs that don't match the
byhostname's parent
2. ARC seal structural validation
Buckets ARC-Authentication-Results / ARC-Message-Signature / ARC-Seal by i= instance. Detects:
- Gaps in the instance chain
- Missing components per instance (must have all 3)
cv=failon the final seal — upstream chain validation failed (severityhigh)
Full cryptographic verification of ARC seals lands in Sprint 99+; v0.6.5 ships the structural checks that already catch most forgery patterns.
3. DKIM body-hash recompute
For each DKIM-Signature header:
- Parse tags (
d=,s=,a=,c=,bh=,l=,h=) - Canonicalize the body per
c=(simple or relaxed) - Recompute SHA-256 of the canonicalised bytes
- Compare against the declared
bh=
Mismatch = body modified after signing — severity critical. This
catches the most damaging DKIM failure mode (in-flight tampering by a
forwarder or malware).
4. Authentication-Results raw capture
Every Authentication-Results header is captured into auth_results_raw
so the operator (or a downstream parser) can inspect what the receiving
MTA itself claimed about SPF/DKIM/DMARC/ARC.
Findings emitted
| ID | Severity | Trigger |
|---|---|---|
cymail.header.received_anomaly | high/medium | Forged/backwards timestamp, loopback HELO |
cymail.header.arc_anomaly | high/medium | Gap, missing component, final cv=fail |
cymail.header.dkim_body_mismatch | critical | Body hash didn't match — message tampered |
cymail.header.arc_seal_broken | high | Synthesized from final cv=fail |
attest
Hardware Root of Trust snapshot. Reports the presence + manufacturer of the host's TPM (Linux/Windows) or Apple Secure Enclave (macOS).
cymail attest
cymail attest --format json
Detection only — no AIK signing, no key generation. Operators use this to inventory device security posture; tamper-detection sees a stable host's TPM vendor flip between check-ins as a high-severity signal.
Same implementation as cyweb attest (ported verbatim).
serve
Embedded web UI for everything above. Cybrium-themed, JS-free, single binary, no external assets.
cymail serve # binds to 127.0.0.1:7777
cymail serve --bind 0.0.0.0:9000
Routes:
/— landing form (mode picker + domain input)/scan?domain=X,/discover?domain=X,/reputation?domain=X,/leak?domain=X— inline HTML reports/scan.{json,csv,sarif,html}?domain=X(and same for every other mode) — export endpoints/attest— host hardware-RoT JSON/healthz— liveness probe
A compact Run scan form appears at the top of every result page so you
can immediately run another scan without going back to the landing
page. Designed for local / container use behind the platform's own
ingress.
update / upgrade
cymail update # refresh local threat-intel cache
cymail upgrade # self-update from signed GH Release
cymail upgrade --dry-run # check + print, don't actually swap
update writes a marker under $XDG_CACHE_HOME/cymail/ so future
incremental refresh logic has a timestamp to compare against. Real
DNSBL/lookalike-DB mirroring lands in v0.7.
upgrade:
- Hits
api.github.com/repos/cybrium-ai/cymail/releases/latest - Downloads the asset matching this platform+arch
- SHA-256 verifies against the release's
checksums.txt - On Windows: PowerShell
Get-AuthenticodeSignaturechecks the new binary is signed byCN=cybriumbefore swapping - Atomically replaces
$(current_exe)viastd::fs::rename