A few weeks ago I decided to build something I'd always dreamed of: a web vulnerability scanner. Not a toy — a real tool with behavioral detection, an enterprise dashboard, and a Threat Intelligence module that tells you which of your findings are being actively exploited in the wild.
It's written in Rust, it's open source (MIT/Apache-2.0), and today I want to share how one specific part of it works: the CTI correlation engine.
The problem with flat vulnerability lists
Most scanners give you a list: "you have 373 vulnerabilities". But a security team doesn't fix all 373 at once. They need to know: which ones are hackers actually using right now?
That's the gap my scanner tries to fill.
How the CTI module works
The scanner ships with a curated knowledge base of emerging ransomware groups (DireWolf, Devman, MintEye, and others) and their known exploitation patterns, plus a live pull of the CISA KEV catalog (Known Exploited Vulnerabilities) — CVEs that CISA confirmed are being exploited in the wild.
After each scan, the correlation engine matches detected vulnerabilities against both sources:
- CWE-level matching against CISA KEV entries
- Pattern matching against exploitation techniques attributed to specific ransomware groups
- Priority scoring so the report puts the most dangerous findings first
The result is a report section like this:
12 of your findings match actively exploited CVEs (CISA KEV). 3 match exploitation patterns of the Devman ransomware group, commonly used against exposed admin panels.
The stack
-
Rust with
reqwest,tokio,clap,rayonfor parallel scanning - Axum for the Enterprise web dashboard (JWT auth, scan history)
- Reports in Markdown and PDF with executive summaries
What I learned building it
As someone without a formal CS background who learned Rust from scratch for this project:
- The borrow checker is strict but fair — it caught real bugs before runtime.
- Deterministic detection beats heuristic guessing for scan results; AI-assisted triage is where LLMs shine.
- The Rust ecosystem (crates.io) made PDF generation, HTML sanitization, and parallelism almost painless.
Try it
- Repo: https://github.com/5n4vc4smh8-pixel/vuln-scanner
- Site: https://5n4vc4smh8-pixel.github.io/vuln-scanner/
Only scan systems you own or have permission to test.
Feedback welcome — especially on the detection engines and the CTI correlation logic. What would you add?


Top comments (4)
The threat intelligence module is where scanners can become much more useful than a checklist. The key is freshness and explainability: why this finding matters now, what source informed it, and whether the risk changes based on the target’s actual stack rather than a generic severity label.
"Spot on. That’s exactly the philosophy behind the CTI module in vuln-scanner.
We moved away from just showing a generic 'High/Critical' label because, in the real world, a 'Medium' that is actively being exploited by a ransomware group like DireWolf or Devman is much more dangerous than a theoretical 'Critical' with no known exploit.
Regarding your points:
Explainability: Our reports now link findings directly to the actor's behavior. Instead of just a CWE, you get the 'why': 'This vulnerability is a priority because it matches the initial access pattern of [Group X]'.
Freshness: We are integrating the CISA KEV (Known Exploited Vulnerabilities) catalog to ensure the 'freshness' of what constitutes an immediate threat.
Context-Aware Risk: This is the next frontier for us. We’re working on a fingerprinting engine to adjust the risk score based on the target’s specific stack (e.g., downgrading a PHP-specific vuln if the target is running Node.js).
Would love to have your insights on the GitHub repo if you have time to dig into the CTI implementation. Feedback like this is what helps us build tools that actually help defenders prioritize."
That is the right tradeoff. A severity label is only useful after it is connected to exploitability, actor behavior, and what the defender should do next. The reports become much more valuable when they explain why this finding matters now, not just where it sits in a generic CVSS bucket.
"What would you add?"