Zedmos CTI
User Guide

User Guide

Everything you need to take Zedmos CTI from sign-up to a fully wired SOC pipeline. Copy/paste-able curl examples throughout.

1. Quickstart (5 minutes)

The fastest path: log in to the admin console, issue a firewall token, and pull one of the curated feeds into your existing security stack.

1
Open the admin console and sign in with the credentials your operator gave you. If you don't have any yet, contact sales@zedmos.com.
2
Go to FW Tokens in the top nav. Click Issue new token, give it a name, optionally restrict to ti / security / waf kinds, and copy the value — it is shown once.
3
Test the pull from your laptop:
TOKEN="tihub_..."
curl -H "Authorization: Bearer $TOKEN" \
  https://cti.zedmos.net/v1/feeds/security/phishing/domains.txt | head
4
Wire that URL into your firewall. Examples for every vendor live at /integrations and section §6 Vendor exports.

2. Getting an API token

Every /v1/feeds/* and /v1/lookup/* endpoint is bearer-token gated. Tokens are issued from the admin console and hashed with SHA-256 server-side, so plaintext is never stored — that's also why we only show it once.

Token kinds

KindUse case
tiGeneric threat-intel (domain/IP block lists)
securitySecurity-policy categories (phishing, malware, ransomware…)
wafWAF-grade signatures + JA3/JA4 fingerprints

One token can carry multiple kinds. Token rotation: just issue a new one and update your firewall config; revoking on the old token takes effect immediately (no grace window).

Tokens are tenant-scoped. Sharing across tenants is detected via pull-volume fingerprinting and will get the token disabled.

3. Pulling feeds

All feeds follow the URL convention:

/v1/feeds/<kind>/<category>/<format>

Some popular combinations:

URLFormat
/v1/feeds/security/phishing/domains.txtplain domain list
/v1/feeds/ti/botnet_cc/ips.txtplain IP/CIDR list
/v1/feeds/security/malware_virus/suricata.rulesSuricata DNS-block rules (priority + threat metadata)
/v1/feeds/security/ransomware/sigma.ymlSigma rule (MITRE-tagged)
/v1/feeds/ti/file_sha256_malware/yara.yarYARA hash rule
/v1/feeds/security/phishing/stix.jsonSTIX 2.1 bundle
/v1/feeds/security/phishing/unbound.rpzRPZ DNS sinkhole zone

Available categories

phishing · malware_virus · ransomware · botnet_cc · banking_trojan · info_stealer · spyware_adware · keyloggers · exploit_kit · cryptominer · scanner · ddos_amplifier · anonymizer · bulletproof_hosting · dynamic_dns · newly_registered · turkish_usom · iot_botnet · ja3 · ja4 · compromised · recent_outbreaks · ...

See the full live catalogue at /v1/public/sources.

4. IOC scoring (composite filter)

Every IOC carries four 0-100 scores. The most useful one for production is composite: a weighted aggregate that drives default sorting and our recommended block threshold.

Score meanings

ScoreWhat it measures
confidenceHow sure are we this IOC is malicious? (source quality × consensus × enrichment × sighting feedback)
threatHow dangerous if hit? (severity 1-10 × category weight × tier multiplier)
popularityHow widely observed? (distinct sources × 30d sightings × age window)
compositeWeighted aggregate: confidence×0.45 + threat×0.35 + popularity×0.20

min_score gating — recommended workflow

Every feed export accepts ?min_score=N (0-100). Gate by composite to ship only high-signal IOCs to noisy environments:

# Full feed (default — includes community-tier indicators)
curl -H "Authorization: Bearer $TOKEN" \
  https://cti.zedmos.net/v1/feeds/security/phishing/domains.txt

# Strict mode: composite >= 70 (verified + corroborated only)
curl -H "Authorization: Bearer $TOKEN" \
  "https://cti.zedmos.net/v1/feeds/security/phishing/fortinet.txt?min_score=70"

# Response includes X-Tihub-Min-Score and X-Tihub-Row-Count headers
Recommended thresholds: 70 for production block lists, 50 for SIEM enrichment, 30 for SOC investigation pivots, 0 for research.

Per-IOC lookup

curl -H "Authorization: Bearer $TOKEN" \
  https://cti.zedmos.net/v1/lookup/domain/example.bet

Returns tier, sources, categories, the four scores, the effective MITRE techniques, and a recommendation string ready for ticketing.

5. MITRE ATT&CK mapping

Zedmos maps each category to a curated list of ATT&CK tactics + techniques (Enterprise v15, 2026 Q1). The mapping shows up in three places:

Coverage matrix

Live aggregate of which ATT&CK techniques we cover, with IOC counts per technique. Open /admin-mitre-coverage.html (public, no auth) or hit the JSON:

curl https://cti.zedmos.net/v1/public/mitre/coverage | jq '.techniques[0:5]'

6. Vendor-native exports

Same IOC set, packaged for direct paste into your firewall console. All endpoints accept ?min_score.

Fortinet FortiGate

config system external-resource
  edit "zedmos-phishing"
    set type domain
    set resource "https://cti.zedmos.net/v1/feeds/security/phishing/fortinet.txt?min_score=70"
    set user-agent "Bearer <TOKEN>"
  next
end

Palo Alto Networks (External Dynamic List)

# Objects → External Dynamic Lists → Add
# Type: IP List
# Source: https://cti.zedmos.net/v1/feeds/security/phishing/paloalto.txt
# Repeat every: Hour
# Certificate Profile: leave blank (HTTPS trusted by default)

Check Point Quantum

ioc_feeds add \
  --feed_name Zedmos_Phishing \
  --transport_type web_url \
  --resource https://cti.zedmos.net/v1/feeds/security/phishing/checkpoint.csv \
  --feed_action prevent \
  --feed_format CSV

Sophos / Cisco Umbrella / Meraki / Juniper SRX / MikroTik / Pi-hole / OPNsense / Unbound RPZ

Snippets and config hints for all 16 supported integrations: /integrations.

7. EASM scanner — declare & scan your surface

EASM = External Attack Surface Management. You declare the externally-facing assets you own (domains, IPs, CIDRs, URLs) and Zedmos scans them periodically for misconfigurations and exposures.

What we check (today)

Workflow

1
Open EASM console (from admin nav → 🛰 EASM).
2
Use the Add Asset form: paste your tenant id, pick the type, enter the value (e.g. api.example.com), optional label, scan interval in minutes. Click Add.
3
Hit Scan now on the asset row — first scan takes 5-15 seconds. Findings appear in the Open Findings table below, ordered by severity.
4
For each finding: Ack (working on it) · Resolve (fixed; auto-flips back to open if the condition returns) · FP (false positive, hide it).

Severity ladder

SeverityExamplesSLA suggestion
criticalExposed .git, .env, AWS creds, dangling CNAME to taken-over providerfix today
highApache server-status, phpinfo, missing clickjacking protectionthis week
mediumMissing HSTS, weak TLS cipherthis sprint
lowServer banner version leak, missing CSPbacklog

8. Brand protection — typosquat & homograph hunting

Declare a "brand watch" with your root domain(s); we'll enumerate up to 1,500 visually-similar variants across 8 algorithms, resolve them on public DNS in parallel, and alert on each one that's actively registered (i.e. a real attacker squat, not a hypothetical).

Algorithms used

Workflow

1
Open Brand console (admin nav → 🛡 Brand).
2
Use the Add Watch form — provide tenant id, a name, comma-separated root domains (e.g. example.com, example.net) and brand keywords.
3
Hit Scan now — typically 2-5 seconds. Each variant that resolves to a public IP becomes a BrandAlert.
4
In the alerts table, click Takedown on a suspect alert; we'll auto-create a draft request with RDAP-pulled abuse contact + a pre-filled email body. Edit before sending.
Brand pipeline runs every 6 hours by default per watch; tune via the watch's run_interval_min field.

9. Takedown workflow

A TakedownRequest is a state-machine record that follows your abuse case end-to-end.

Lifecycle

StateMeaningNext action
draftAuto-created, awaiting your editEdit subject/body, then mark submitted
submittedYou sent the email/form, awaiting replyWait 48-72h; re-send if no ack
acknowledgedRegistrar/host confirmed receiptTrack for resolution
in_progressThey're investigatingRe-verify in 7 days
removedTarget offline (DNS NX / page 410)Auto-marked; you can re-open if it comes back
deniedRegistrar refusedEscalate to ICANN / hosting provider
stale30+ days, no responseAuto-resubmit candidate

RDAP abuse-contact lookup

curl -H "Cookie: session=..." \
  https://cti.zedmos.net/admin/v1/admin/brand/abuse-contact/example.bet
# → { registrar: "abuse@example-reg.com", abuse_email: "...", raw: {...} }

10. API reference (cheat sheet)

Public (no auth)

EndpointReturns
GET /v1/public/healthhealth probe
GET /v1/public/sourcesfeed catalogue
GET /v1/public/dashboardoverall stats
GET /v1/public/mitre/coverageMITRE coverage matrix (5-min cached)
GET /v1/integrations/vendors16-entry vendor catalog

Bearer-token endpoints

EndpointReturns
GET /v1/feeds/<kind>/<cat>/domains.txtplain domain list
GET /v1/feeds/<kind>/<cat>/ips.txtplain IP/CIDR list
GET /v1/feeds/<kind>/<cat>/suricata.rulesSuricata 7 rules (priority + threat metadata)
GET /v1/feeds/<kind>/<cat>/sigma.ymlSigma rule (MITRE tagged)
GET /v1/feeds/<kind>/<cat>/yara.yarYARA rule (hash-based)
GET /v1/feeds/<kind>/<cat>/stix.jsonSTIX 2.1 bundle
GET /v1/feeds/<kind>/<cat>/{fortinet,paloalto,checkpoint,sophos,...}vendor-native exports
GET /v1/lookup/<type>/<value>per-IOC lookup with scores + MITRE

Admin endpoints (session JWT cookie)

EndpointPurpose
POST /admin/v1/admin/easm/assetsAdd EASM asset
POST /admin/v1/admin/easm/assets/:id/scanTrigger scan
GET /admin/v1/admin/easm/summaryAsset rollup
POST /admin/v1/admin/brand/watchesCreate brand watch
POST /admin/v1/admin/brand/watches/:id/scanRun typosquat scan
POST /admin/v1/admin/brand/alerts/:id/takedownSpawn takedown request
GET /admin/v1/admin/brand/abuse-contact/:domainRDAP abuse lookup

11. Troubleshooting

401 unauthorized

Your token is wrong, expired, or revoked. Check FW Tokens in the admin console — disabled tokens have enabled=false. Issue a fresh one.

The feed I want is empty

You're probably hitting a strict min_score on a small category. Drop the filter (?min_score=0) and inspect X-Tihub-Row-Count; if it's still 0 the category may not have IPs/domains of that type — try the alternate format.

Suricata rejects the .rules file

You probably have a Suricata version without dns.query support (pre-5.0). Our rules require Suricata ≥ 6. For older boxes, use opnsense.txt or fortinet.txt as a plain alias.

EASM scan returns 0 findings

Either your perimeter is well-tuned (good!) or the asset is unreachable from our scanner egress. Check the errors[] array in the scan result for network-level failures.

Typosquat scan found 100+ variants — too noisy

Filter the BrandAlert list by severity=high (homograph hits) first; those are the highest-signal. Mark obvious legitimate brand-adjacent domains (e.g. partner sites) as ignored — they won't re-fire.


Still stuck? Email support@zedmos.com with the asset/alert ID. We aim for < 4h response on Premium, < 1 business day on Plus.