Real-time Threat Intelligence Fusion Engine
Vortex is a high-performance threat intelligence fusion platform written in Julia. It aggregates, correlates, and analyzes indicators of compromise (IOCs) from 50+ threat intelligence feeds in real-time, providing security teams with actionable intelligence.
- 50+ Pre-configured Feeds: AlienVault OTX, Abuse.ch (URLhaus, Feodo, Bazaar), MISP, VirusTotal, Shodan, Censys, Spamhaus, OpenPhish, PhishTank, and more
- 19 IOC Types: IP, Domain, URL, MD5/SHA1/SHA256, Email, CVE, JA3, CIDR, Bitcoin addresses, YARA rules, and more
- Automatic Deduplication: Smart merging of IOCs from multiple sources with confidence scoring
- Rate-Limited Polling: Respect API limits with configurable polling intervals
- Threat Correlation: 7 built-in correlation rules to identify related threats
- ML-Based Clustering: K-means clustering to group similar threats
- Anomaly Detection: Identify unusual IOCs using distance-based detection
- Threat Scoring: Weighted scoring model with decay and source reputation
- Attribution Prediction: Predict threat actor attribution based on IOC features
- Predefined Hunt Queries: C2, ransomware, APT, phishing, cryptomining
- Custom Hunt Rules: Create automated hunts with alerting
- Timeline Analysis: Track threat activity over time
- Pattern Matching: Regex-based IOC value searching
- Rule-Based Alerts: Configure alerts for high-risk IOCs, specific categories, or patterns
- Severity Levels: Critical, High, Medium, Low, Info
- Webhook Notifications: Slack, Teams, Discord, and custom webhooks
- Alert Management: Acknowledge, investigate, resolve, or escalate
- GeoIP Lookup: Location, ASN, ISP information
- WHOIS Data: Domain registration details
- DNS Resolution: A, AAAA, MX, TXT, NS records
- Reputation Scoring: VirusTotal, AbuseIPDB, Shodan
- STIX 2.1: Standard threat intel format
- MISP: Event and attribute export
- Detection Rules: Snort, Suricata, YARA, Sigma
- Data Formats: CSV, JSON
using Pkg
Pkg.add(url="https://github.com/nullsec-security/vortex")using Vortex
# Create the threat intelligence engine
engine = create_vortex_engine()
# Add threat feeds
add_feed!(engine, urlhaus_feed())
add_feed!(engine, feodo_tracker_feed())
add_feed!(engine, alienvault_otx_feed("YOUR_API_KEY"))
add_feed!(engine, spamhaus_drop_feed())
# Start the engine (begins polling feeds)
start!(engine)
# Search for an IOC
results = search_ioc(engine, "8.8.8.8")
for ioc in results
println("Found: $(ioc.value) - Risk: $(ioc.risk_score)")
end
# Bulk check
iocs_to_check = ["192.168.1.1", "malware.example.com", "suspicious.ru"]
matches = search_bulk(engine, iocs_to_check)
# Check engine status
status(engine)# Quick hunt
result = threat_hunt(engine, "cobalt")
# Hunt for C2 infrastructure
query = hunt_c2_infrastructure()
c2_result = execute_hunt(engine, query)
# Hunt for recent high-risk threats
query = hunt_recent_threats(24) # Last 24 hours
recent = execute_hunt(engine, query)
# Custom hunt query
custom_query = create_hunt_query(
name="My Hunt",
ioc_types=[IOC_IP, IOC_DOMAIN],
tags=["ransomware", "c2"],
min_risk_score=60.0,
date_from=now() - Day(7)
)
result = execute_hunt(engine, custom_query)
# Generate report
report = export_hunt_report(result; detailed=true)
println(report)# Add default alert rules
for rule in default_alert_rules()
add_alert_rule!(engine, rule)
end
# Create custom alert rule
my_rule = create_alert_rule(
name="Critical Ransomware",
alert_type=ALERT_IOC_MATCH,
severity=ALERT_CRITICAL,
tags=["ransomware", "lockbit", "blackcat"],
min_risk_score=70.0,
notify_webhook=["https://hooks.slack.com/services/..."]
)
add_alert_rule!(engine, my_rule)
# Check alerts
alerts = get_alerts(engine)
for alert in alerts
println("$(alert.severity): $(alert.title)")
end
# Acknowledge an alert
acknowledge_alert!(alerts[1]; by="analyst@company.com")
# Resolve an alert
resolve_alert!(alerts[1];
by="analyst@company.com",
notes="Confirmed false positive - internal testing"
)# Correlation analysis
iocs = collect(values(engine.iocs))
correlations = correlate_iocs(iocs[1:100])
for corr in correlations
println("Correlated: $(corr.source_ioc) <-> $(length(corr.related_iocs)) IOCs")
end
# Build correlation graph
graph = build_graph(iocs)
components = find_components(graph)
centrality = calculate_centrality(graph)
# Clustering
clusters = cluster_threats(engine; k=10)
for cluster in clusters
println("$(cluster.label): $(cluster.size) IOCs, avg risk: $(cluster.avg_score)")
end
# Anomaly detection
anomalies = detect_anomalies(engine; contamination=0.1)
for anom in anomalies[1:10]
println("Anomaly score: $(anom.anomaly_score) - $(anom.explanation)")
end
# Threat scoring
model = ScoringModel()
for ioc in iocs[1:10]
score = score_ioc(ioc, model)
println("$(ioc.value): $(score.score) ($(score.risk_level))")
end# Create enrichment providers
providers = [
geoip_provider(),
virustotal_enrichment_provider("YOUR_VT_API_KEY"),
abuseipdb_provider("YOUR_ABUSEIPDB_KEY")
]
# Enrich an IOC
ioc = get_ioc(engine, "192.168.1.1")
enriched = full_enrich(ioc; providers=providers)
# Access enrichment data
if enriched.geoip !== nothing
println("Location: $(enriched.geoip.city), $(enriched.geoip.country_name)")
println("ASN: $(enriched.geoip.asn) - $(enriched.geoip.org)")
end
for rep in enriched.reputation
println("$(rep.source): $(rep.score) ($(rep.detection_count) detections)")
end# Export to STIX 2.1
stix_bundle = export_stix(iocs)
write("threat_intel.stix.json", stix_bundle)
# Export to MISP
misp_event = export_misp(iocs; event_info="Weekly IOC Export")
write("threat_intel.misp.json", misp_event)
# Export to CSV
csv_data = export_csv(iocs)
write("iocs.csv", csv_data)
# Export to detection rules
snort_rules = export_snort(iocs)
suricata_rules = export_suricata(iocs)
yara_rules = export_yara(iocs)
sigma_rules = export_sigma(iocs)
# Export with filtering
config = ExportConfig(
FORMAT_STIX,
true, # include_metadata
false, # include_enrichment
true, # pretty_print
5000, # max_items
true, # stix_bundle
false, # misp_galaxy
',', # csv_delimiter
0.5, # min_confidence
50.0, # min_risk_score
[IOC_IP, IOC_DOMAIN] # ioc_types
)
filtered_export = export_stix(iocs; config=config)# Create intel store
store = create_intel_store()
# Store IOCs
store_ioc!(store, ioc)
store_iocs!(store, iocs)
# Query store
query = create_query(
ioc_types=[IOC_IP],
min_risk_score=50.0,
tags=["c2", "malware"],
sort_by=:risk_score,
limit=100
)
results = execute_query(store, query)
# Save to disk
save_store(store, "intel_store.json")
# Load from disk
store = load_store("intel_store.json")
# Get statistics
stats = store_stats(store)
println("Total IOCs: $(stats["total_iocs"])")
println("Risk distribution: $(stats["risk_distribution"])")| Type | Description | Example |
|---|---|---|
IOC_IP |
IPv4 address | 192.168.1.1 |
IOC_IP_V6 |
IPv6 address | 2001:db8::1 |
IOC_DOMAIN |
Domain name | malware.example.com |
IOC_URL |
Full URL | https://evil.com/malware.exe |
IOC_HASH_MD5 |
MD5 hash | d41d8cd98f00b204e9800998ecf8427e |
IOC_HASH_SHA1 |
SHA1 hash | da39a3ee5e6b4b0d3255bfef95601890afd80709 |
IOC_HASH_SHA256 |
SHA256 hash | e3b0c44298fc1c149afbf4c8996fb924... |
IOC_EMAIL |
Email address | attacker@evil.com |
IOC_CVE |
CVE identifier | CVE-2024-1234 |
IOC_JA3 |
JA3 fingerprint | 3b5074b1b5d032e5620f69f9f700ff0e |
IOC_JA3S |
JA3S fingerprint | Server JA3 fingerprint |
IOC_CIDR |
CIDR range | 192.168.0.0/24 |
IOC_BITCOIN |
Bitcoin address | 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa |
IOC_FILENAME |
File name | malware.exe |
IOC_FILEPATH |
File path | C:\Windows\System32\evil.dll |
IOC_REGISTRY |
Registry key | HKLM\Software\Malware |
IOC_MUTEX |
Mutex name | Global\EvilMutex |
IOC_USER_AGENT |
User agent string | Browser/malware signatures |
IOC_YARA |
YARA rule name | rule_malware_family |
| Provider | Feed | Data |
|---|---|---|
| Abuse.ch | URLhaus | Malicious URLs |
| Abuse.ch | Feodo Tracker | Banking trojan C2s |
| Abuse.ch | Malware Bazaar | Malware samples |
| Abuse.ch | SSL Blocklist | Malicious SSL certs |
| AlienVault | OTX | Multi-type IOCs |
| Spamhaus | DROP | IP blocklist |
| Emerging Threats | IPs | Malicious IPs |
| Blocklist.de | IPs | Attacking IPs |
| OpenPhish | Phishing | Phishing URLs |
| PhishTank | Phishing | Verified phishing |
| VirusTotal | API | File/URL/IP analysis |
| Shodan | API | Internet scanning |
| Censys | API | Internet scanning |
| MISP | Custom | Threat sharing |
# Create custom feed
my_feed = custom_feed(
name="My Internal Feed",
url="https://internal.company.com/iocs.json",
api_key="...",
format="json",
poll_interval=300
)
add_feed!(engine, my_feed)βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Vortex Engine β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββ β
β β Feeds β β Analysis β β Alerting β β
β β β β β β β β
β β β’ OTX β β β’ Scoring β β β’ Rule Engine β β
β β β’ Abuse.ch β β β’ Correlationβ β β’ Notifications β β
β β β’ MISP β β β’ Clustering β β β’ Webhook/Email β β
β β β’ VirusTotal β β β’ Anomaly β β β β
β β β’ Shodan β β β’ Attributionβ β β β
β β β’ Custom β β β β β β
β ββββββββ¬ββββββββ ββββββββ¬ββββββββ ββββββββββββ¬ββββββββββββ β
β β β β β
β βΌ βΌ βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β IOC Store β β
β β β’ 19 IOC Types β’ Indexing β’ Deduplication β’ Querying β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββ β
β β Enrichment β β Hunting β β Export β β
β β β β β β β β
β β β’ GeoIP β β β’ Queries β β β’ STIX 2.1 β β
β β β’ WHOIS β β β’ Rules β β β’ MISP β β
β β β’ DNS β β β’ Reports β β β’ Snort/Suricata β β
β β β’ Reputation β β β β β’ YARA/Sigma β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Vortex is designed for high-performance threat intelligence processing:
- IOC Ingestion: 100,000+ IOCs/second
- Search: Sub-millisecond lookups via indexing
- Correlation: Parallel processing for large datasets
- Memory: Efficient storage with configurable limits
- Scalability: Supports millions of IOCs
- API keys are stored in memory only (not logged)
- Supports TLS for all feed connections
- Rate limiting prevents API abuse
- No sensitive data written to disk without encryption
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
MIT License - see LICENSE for details.
- Abuse.ch for their excellent threat feeds
- AlienVault OTX for threat intelligence
- MISP Project for threat sharing standards
- The Julia community for an amazing language
Vortex - Bringing order to the chaos of threat intelligence
Part of the NullSec Security project.