In brief. Triaging an indicator usually means opening a dozen browser tabs and retyping the useful bits into a ticket. ioc-enrich takes an IP, domain, URL, hash, or email and returns a single aligned table, pulling from free intelligence sources that need no API keys to start. It refangs defanged indicators, enriches the host a URL points at, and prints text, JSON, or a plain indicator list you can pipe onward.
The problem
Indicator triage is one of the most repetitive tasks in a SOC. You get an IP, a domain, a file hash, and before you can say anything useful about it you are reading geolocation on one site, open ports on another, a reputation score on a third, WHOIS on a fourth, then retyping the three facts that mattered into a ticket. The work is not hard; it is just slow and mechanical, and the reformatting at the end is pure friction.
I wanted a single command that takes an indicator and hands me back something I can paste straight into a report, without first having to sign up for anything.
How it works
You give it an indicator and it does three things: classifies what kind it is, refangs it if it arrived defanged (hxxps://evil[.]com becomes https://evil.com), and fans out to every applicable source at once. The sources that need no key do the core work — Shodan InternetDB for open ports and known CVEs, GreyNoise for scanner/noise classification, the Tor exit list, ip-api for geolocation and ASN, RDAP for domain age, crt.sh for certificate-transparency subdomains, and CIRCL hashlookup for known files. If you add free keys for VirusTotal, AbuseIPDB, abuse.ch, or AlienVault OTX, those light up too; if you don't, they show as a labeled skip and the report still renders.
One detail I find myself using constantly: when you enrich a URL, the tool also enriches the host it points at and shows those rows under the URL. Seeing where a link actually goes is usually the whole question in link triage.
Using it
python -m ioc_enrich 8.8.8.8 evil[.]com hxxps://bad[.]site/login
# from a file, one indicator per line
python -m ioc_enrich --file iocs.txt
# text (default), json, or csv
python -m ioc_enrich --file iocs.txt --format csv -o report.csv
# see the output with no network and no keys
python -m ioc_enrich --demo
Every enrichment key is optional. A missing key simply skips that one source, and the tool tells you which sources were available so you can read the result in context.
What it is, and isn't
This is enrichment, not a verdict engine. It gathers and formats evidence; the analyst decides. CIRCL hashlookup in particular reports whether a hash is a known file — often a legitimate system binary — not whether it is malicious, so a miss there is not a clean bill of health. The free tiers carry rate limits, so large batches may need keys or a slower pace. Within those bounds it does the boring part of triage fast, which is the point.