The flood problem
Point a scanner at a real network and it comes back with a flood: hundreds or thousands of findings, sorted by a severity number the tool assigned automatically. It is tempting to treat that output as the answer. It is not. A scanner reports potential issues — conditions that might be vulnerabilities — and it has no idea which ones are real, which ones matter, and which ones can actually be reached and abused.
The value of this phase is not the scan; it is the triage. Handing a client a raw scanner dump is lazy, and it is usually wrong — it buries the two or three findings that could get them breached under a thousand that cannot, and it includes results that were never true to begin with. Your job is to turn that flood into a short, validated, prioritized list: a small number of findings you have confirmed are real, ordered by how much they actually endanger the organization.
False positives and why they happen
Scanners are fast because they guess. A huge fraction of findings come not from actually exercising a vulnerability but from reading a version banner — the service announces "I am Apache 2.4.49," the scanner looks that string up against a list of known issues, and it flags everything that version was ever vulnerable to. Often the service is not vulnerable at all. The banner lied, or the lookup was too coarse, and now you have a false positive.
The classic trap is backported patches. Distributions like RHEL and Debian routinely fix a security bug in an older package without bumping its version number — they patch the flaw and keep the version string the same so nothing downstream breaks. A version-based check has no way to see the fix. It reads the old version number, matches it against a known CVE, and reports the software as vulnerable when it was patched weeks ago. This single behavior produces a large share of the false positives in any credentialed scan.
- Backported patches — the version string stays old, but the vulnerability is already fixed. Version-based checks flag it anyway.
- Compensating controls — a firewall, WAF, or configuration setting blocks the path the vulnerability would need, so the flaw is present but not exploitable in context.
- Unreachable services — the scanner flagged a port or service that is not actually reachable by an attacker from where the threat would come.
- Low detection confidence — some plugins openly self-report low confidence; they are educated guesses the tool wants a human to confirm.
The conclusion is simple and non-negotiable: never trust a finding you have not validated. The scanner's severity column is a hypothesis, not a verdict.
Manual validation
Validation means confirming that the specific condition the finding claims actually holds — not that a version number matched, but that the vulnerability is genuinely present on this host, in this configuration, right now. Before a finding goes into the report, you do one of three things: check the actual configuration (read the setting, the file, the running version, the patch state), reproduce the exact prerequisite the vulnerability requires, or safely test the behavior in a way that demonstrates the flaw without causing damage.
This is slower than trusting the scanner, and that is the point. The two failure modes both cost you, in opposite ways:
- A false positive in a report destroys trust. The client patches a "critical" you reported, discovers it was never exploitable, and starts doubting every other line you wrote. One bad finding can discredit a whole engagement.
- A false negative gets someone breached. Dismiss a real finding as noise and you have handed an attacker an unguarded door. The cost lands on the organization, not on you, which is exactly why it is your responsibility to catch.
Prioritizing beyond the CVSS number
Once a finding is validated, it needs a place in line. The instinct is to sort by CVSS base score and call it done — but a CVSS base score is a starting point, not the answer. It describes a vulnerability in the abstract, with no knowledge of your environment, your exposure, or whether anyone has ever actually weaponized it. A "medium" that is internet-facing and has a working exploit outranks a "critical" buried on an isolated host that no one can reach.
Real prioritization combines the base score with real-world signals. Each one answers a different question, and together they tell you what to put at the top of the list:
| Signal | What it tells you | Where to check |
|---|---|---|
| CVSS base score | The vulnerability's inherent severity in the abstract — how bad it is if exploited. A baseline, not a ranking. | nvd.nist.gov · the scanner's finding detail |
| Public exploit exists | Whether working attack code is already published. A confirmed flaw with a public exploit is dramatically more urgent than one without. | exploit-db.com · searchsploit · GitHub |
| CISA KEV listing | That the vulnerability is being actively exploited in the wild right now — not theoretical, but in use by real attackers. | cisa.gov/kev |
| Internet exposure | Whether the affected service is reachable from outside, or buried deep in an internal segment. Reachability changes everything. | Your scan scope · external recon · firewall rules |
| Asset value / sensitivity | What the host actually does — a domain controller or a database of customer records outranks a forgotten test box. | Asset inventory · the client's own context |
None of these signals stands alone. The findings that belong at the top of your list are the ones where several line up at once: a validated, high-severity flaw, on an exposed and valuable asset, with a public exploit ready to go. That intersection — not the raw CVSS column — is what real prioritization produces.
Public exploits — the urgency multiplier
Of all the signals above, one deserves its own section because it changes a finding's urgency more than any other: does a working public exploit already exist? A confirmed vulnerability that has published, working attack code is dramatically more dangerous than one that does not. The first can be abused by anyone who can download a script; the second still requires an attacker to develop the exploit themselves — a barrier that filters out most of them. When triaging, a public exploit pushes a finding sharply up the list.
The canonical place to check is the Exploit Database at exploit-db.com — a large, curated, CVE-tagged archive of public exploits and proof-of-concept code maintained by OffSec. You search it by product, version, or CVE; if there is an entry, working attack code is already in the world and your finding just became far more urgent. It is the first stop for turning "this is theoretically vulnerable" into "this is exploitable today."
On Kali Linux the same database ships offline as a command-line tool, searchsploit, which queries a local copy of the Exploit Database with no network required:
- searchsploit apache 2.4.49 — find published exploits for a specific product and version.
- searchsploit -w CVE-2021-41773 — include the upstream exploit-db.com URLs for each hit.
- searchsploit -m 50383 — copy a chosen exploit out to your working directory, ready to read and adapt.
The Exploit Database is the canonical source, but it is not the only one. Check GitHub for proof-of-concept repositories — many fresh exploits land there first, before they are ever curated into a database — and check the CISA KEV catalog, which tells you not just that an exploit exists but that the vulnerability is being actively exploited in the wild right now.
From triage to target list
Put it all together and the output of this phase is not the scanner's report — it is a ranked, validated target list. Each entry is a finding you have personally confirmed is real, scored not by the raw CVSS column but by the combination of severity, exposure, asset value, and whether an exploit already exists. The top entries are the ones that are confirmed, high-impact, and ideally come with a known exploit path.
That list is exactly what the next phase consumes. Where vulnerability analysis asks "what is wrong here, and which of it is real and dangerous?", exploitation asks "can I actually use it?" — and it starts from the top of the list you just built. A clean handoff looks like this:
- Validated, not assumed — every target on the list has been confirmed, so exploitation does not waste time on false positives.
- Ranked by real risk — the highest-value, most-exposed, most-exploitable findings are at the top, so effort goes where it matters.
- Exploit path noted — where a public exploit exists, it is recorded with the finding, so the next phase knows exactly where to start.
Next, we cross that bridge: exploitation — taking the confirmed, prioritized targets from this list and turning a known weakness into actual access.