Skip to main content

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

  1. crt.sh — Certificate Transparency SAN harvest for *@example.com-shaped addresses
  2. DNS SOA RNAME — extracts the responsible-party email baked into the SOA record
  3. Pattern guessing — common seed names (admin, security, support, …) + custom seeds
  4. MX RCPT-TO validation — opt-out via --no-smtp; uses minimal SMTP, never sends DATA
  5. Catch-all probe — single random RCPT against MX; if accepted, validation is suppressed (otherwise every guess looks "valid")
  6. 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 external xlink: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)
  • 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, missing p= = 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.com near password|secret|apikey. Reports repo + path + URL, never line content. Honours GITHUB_TOKEN for 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.

FeedEnv varFormat
DeHashedDEHASHED_API_KEYemail:apikey
IntelXINTELX_API_KEYAPI key
SnusBaseSNUSBASE_API_KEYAPI 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_aligned
  • by_source_ip[] — per-IP message count, DKIM/SPF alignment, dispositions, observed header_froms
  • by_org[] — per-reporting-org count + total messages
  • orphan_records — count of records whose policy_domain didn'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]'

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 by hostname'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=fail on the final seal — upstream chain validation failed (severity high)

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

IDSeverityTrigger
cymail.header.received_anomalyhigh/mediumForged/backwards timestamp, loopback HELO
cymail.header.arc_anomalyhigh/mediumGap, missing component, final cv=fail
cymail.header.dkim_body_mismatchcriticalBody hash didn't match — message tampered
cymail.header.arc_seal_brokenhighSynthesized 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:

  1. Hits api.github.com/repos/cybrium-ai/cymail/releases/latest
  2. Downloads the asset matching this platform+arch
  3. SHA-256 verifies against the release's checksums.txt
  4. On Windows: PowerShell Get-AuthenticodeSignature checks the new binary is signed by CN=cybrium before swapping
  5. Atomically replaces $(current_exe) via std::fs::rename