Ethical › Module 5 › Lesson 2
Scanner Reports vs Real Risk
False positives, missing context, and why you verify on systems you own.
Visual · scanner_vs_risk
A scanner row is a hypothesis. Confirmed risk needs inventory, exposure, and a check on systems YOU own — not a Nessus blast of the café.
Opening
A red row is a rumor with a CVE ID. Risk is a condition on a machine you are allowed to know.
Lesson 1 named the catalog: a CVE is a handle for a bug, an advisory is the prose, and “vulnerable” is a condition with versions and exposure — not a shell. This lesson names the object that fools people next: the scanner report. A commercial or open scanner can print a table of CVE IDs next to hostnames because a banner, a package string, or a probe looked similar to a fingerprint. That table is useful as a work queue. It is not a confirmation that remote code execution is sitting on the wire. It is not permission to scan the internet, the café, or a campus /24 “to find more rows.” Cyberlium’s rule is the same permission line as Modules 1–4: you verify on systems you own or are hired (in writing) to assess. python -m http.server on 127.0.0.1 with a noisy Server token is not Log4Shell (CVE-2021-44228) and is not Heartbleed (CVE-2014-0160). Mapping a teaching listener to a famous Java or OpenSSL bug because a scanner UI looks exciting is theater. You will write scanner-vs-risk-notes.txt, chmod 600, and practice the sentence: scanner row ≠ confirmed risk. Next lesson is treatment — patch, compensate, or accept — with an owner. Today is why you do not treat the spreadsheet as a kill chain.
1. What a scanner actually matched: a fingerprint, not a shell
At a high level, vulnerability scanners guess. They read a version from a banner (Module 4), a package list, an HTTP header, or a plugin that sends a bounded probe and looks for a known response shape. The plugin then attaches a CVE ID and a severity borrowed from NVD or the vendor. That pipeline is why Lesson 1 told you a matching CVE is a hypothesis until inventory and exposure line up. The scanner did not sit in a change-advisory board. It did not open your bill of materials. It did not know whether the feature flag that makes the bug reachable is even on. It printed a row because a string looked close enough for the plugin author.
That guess is still valuable when you own the host: it is a prioritized reading list. You open the public advisory (browser, NVD or vendor — same literacy as Lesson 1), you check YOUR installed version, you check whether the service is reachable from an untrusted network, and you write a ticket. The guess is poison when you point the scanner at strangers. Unauthorized scanning is still unauthorized scanning if the output is a CVE table instead of an nmap screenshot. This course does not teach you to Nessus-scan the internet, a coffee-shop gateway, or a school lab “because the tool is for vulnerability analysis.” The tool does not create consent. Module 1 already spent a whole lesson on that sentence.
Command guide
Scanner matched a fingerprint — WHAT/WHY (not a shell)
═══ INSTALL ═══
Linux (Debian/Ubuntu):
Command — copy this
sudo apt install python3
macOS:
Command — copy this
brew install python3
Windows: Download https://python.org/downloads/
═══ COMMANDS ═══
Command — copy this
cat >> "$NOTES" << 'EOF' scanner_matched: a fingerprint / version token / plugin id scanner_did_not: prove a working exploit or business impact EOF
Command — copy this
python3 - << 'PY'
row = {'plugin': 'example-http-version', 'severity': 'HIGH', 'evidence': 'Server header looked old'}
print('row', row)
print('question: did this match a fingerprint or a shell? => fingerprint')
PY2. False positives: the row is red and the bug is not there
A false positive is a reported CVE that does not apply to the actual product, version, or configuration. Classic causes: a banner that names a product family but not the vulnerable build; a custom Server token that collides with a plugin regex; a container that still advertises an old parent image name after the library was patched; a teaching stack (python http.server) whose Server: SimpleHTTP string has nothing to do with a Java logging library. If you “confirm” that last one by downloading a Log4Shell proof-of-concept, you have confirmed nothing except that you crossed this course’s ethics line. The honest confirmation is inventory: what package is installed on a system you own.
Scanners also duplicate. One OpenSSL bug can appear as three plugin IDs. One WordPress plugin can light up a dozen CVE rows that were all fixed in a single vendor bump you already applied. Deduping is analysis. Copy-pasting the whole export into Slack as “we are owned” is not. Write, for each noisy row you choose to study: why the plugin might have fired, what version string it saw (if you are allowed to see it), and what you still do not know. Missing knowledge is not a license to probe a neighbor until the plugin goes green. Missing knowledge is a ticket on YOUR box: check rpm/dpkg/pip freeze/composer.lock on a host you administer, or write “not in inventory — out of scope.”
Command guide
False positives — WHAT/WHY (red row, bug not there)
═══ COMMANDS ═══
Command — copy this
cat >> "$NOTES" << 'EOF' false_positive_example: plugin fired on a version token I already patched my_check: compare to inventory I own — not a weaponized verify against others EOF
3. Missing context: inventory, exposure, and the condition the advisory hid in paragraph three
Even a true version match is not automatic risk. Inventory answers “do we run this product at this version.” Exposure answers “can an untrusted network reach the thing the advisory describes.” Advisories are full of conditions: local-only, debug flag, specific module enabled, authentication already required, only if a deprecated protocol is on. Lesson 1 told you dropping the condition is how scanner theater happens. This lesson makes it operational. If the CVSS vector says local and your service is not handing that local interface to strangers, the internet-facing panic is misplaced. If the vector says network but the daemon is bound to 127.0.0.1 — the bind you practiced in Module 4 — the café cannot reach it. Risk without exposure is a patch cadence item, not an incident siren.
Context also includes compensating controls you will name properly in Lesson 3: a WAF rule, a feature toggle, a network allow-list, an unused-service stop. You do not need to run an exploit to know a control is in the way. You read the advisory, you read YOUR architecture notes, you write “not reachable from untrusted networks” or “feature disabled.” If you cannot see the architecture because the host is not yours, you do not scan it to find out. You either have RoE or you do not. Café Wi-Fi is not RoE. A classmate’s laptop on the same SSID is not RoE. example.com’s A record is not a Nessus target (Module 2 already forbade turning a DNS fact into a scan).
4. Verify only on systems you own — localhost http.server is not Log4Shell
Verification in this module means: open a public CVE page, then check inventory and exposure on a machine whose owner is you (or a written client). It does not mean: fire a scanner at 1.1.1.1/8, at 10.0.0.0/8, or at every host that answered ping in a hotel. It does not mean: take Module 4’s Server: SimpleHTTP line, paste it into a scanner, and declare CVE-2021-44228 because the UI font is red. Log4Shell is a Java logging-library issue in some deployments. Heartbleed is an OpenSSL memory-disclosure issue in some TLS stacks. python -m http.server is a teaching HTTP listener. Those sentences are different species. Mixing them is how people get expelled from labs and, in worse rooms, from jobs.
If you want a legal verification drill on a box you own, check a package you actually installed: python --version, openssl version, a pip list for libraries you added, a container digest you built. Write the name and version next to “not automatically the CVE I read.” If the version is in range for a public advisory, Lesson 3 will make you choose patch, compensate, or accept — still without a proof-of-concept. If the version is not in range, write “false-positive candidate / not installed.” That is verification. searchsploit, Metasploit, and “just a GET with a JNDI string” are not this course. Do not Nessus-scan the internet. Do not Nessus-scan the café. Do not nmap strangers “to feed the scanner.”
5. False negatives exist too — silence is not a patch certificate
Module 4 hid a trap in the other direction: a generic Server header is not proof the software is patched. Scanners that only fingerprint banners will miss what they cannot see. Hidden versions, custom front doors, and libraries that never speak a banner (Log4j inside an app, a crypto library behind TLS) are why “the scan was clean” is not the same as “we read our SBOM.” Cyberlium will not turn that fact into a homework assignment to write stealthy exploits. It turns it into humility: a green scanner cell is another hypothesis. Defenders still patch on a cadence, still inventory, still treat CVEs from vendor mail even when the scanner was quiet.
Your notes must hold both errors: “row present, maybe false,” and “row absent, maybe blind.” The ethical response to both is the same surface: systems you own, public advisories, written treatment next lesson. The unethical response is to widen the scan until something looks like a trophy. Widening the scan onto networks you do not own is the failure this heading exists to kill. Lock the notes so a shared lab account cannot republish your (even hypothetical) host list. chmod 600 under $HOME/cyberlium-lab — same hygiene as cve-literacy-notes.txt.
6. Wrong vs right: Nessus-the-internet vs a locked note that a row is not risk
Worked failure — same CVE column, opposite job. Right never needs a café scan or a PoC to finish vulnerability analysis.
Wrong
Treat every red cell as RCE. Nessus-scan random internet ranges, the café gateway, or campus 10.x “to populate the report.” Map localhost http.server to Log4Shell or Heartbleed and attack it. Download exploit code to “verify.” Skip inventory and exposure. Paste live target lists into a public gist. Call a scanner PDF a confirmed breach.
Right
Call a scanner row a hypothesis. Check inventory and exposure only on systems you own (or written RoE). Remember the teaching listener is not a famous library CVE. Read public NVD/vendor pages. Write false-positive and missing-context lines in $HOME/cyberlium-lab/scanner-vs-risk-notes.txt, chmod 600. Next: Patch, Compensate, or Accept — with an owner, not a Metasploit screenshot.
7. Hands-on: scanner-vs-risk-notes.txt — hypothesis, context, ethics; never a wide scan
Create the notes on a computer you own. Fill the template in your own words. Optional: record one package version from YOUR box (python, openssl, or a library you installed) as inventory practice — not as a scanner target list. Do not point a vulnerability scanner at the internet. Do not point it at the café. Do not feed Module 4’s loopback banner into an exploit. chmod 600 when the file exists.
Mission: scanner-vs-risk-notes.txt — row ≠ risk, chmod 600
1) In your own words: a scanner row is a fingerprint hypothesis; confirmed risk needs inventory, exposure, and advisory conditions on systems in scope. 2) Write why localhost http.server is not Log4Shell/Heartbleed. Optional: one local package version from a box YOU own. Fill $HOME/cyberlium-lab/scanner-vs-risk-notes.txt and chmod 600. 3) Ethics line: no Nessus/OpenVAS against the internet or café, no nmap of strangers, no PoC, no Metasploit.
Stuck? Ask Cyberlium AI Mentor
If “the scanner already proved RCE” still feels true, ask for a hint — not a plugin pack. Try: "Hint only: why a scanner row is a fingerprint hypothesis, why false positives and missing exposure matter, why localhost http.server is not Log4Shell, and why I must not Nessus-scan the internet or café?" You still fill scanner-vs-risk-notes.txt. No PoC. No random IPs.
You can now look at a red cell and say “hypothesis” without pretending you popped a shell. False positives, missing inventory, and missing exposure are why analysis is a job. Verification stays on systems you own. The teaching listener is still not a famous CVE. This is original Cyberlium teaching mapped to the CEH v13 vulnerability-analysis domain — not official EC-Council training, not a cert, not exam dumps. Next — Patch, Compensate, or Accept — risk treatment for a finding with a written owner, not a screenshot of Metasploit. Still no exploits. Still no café scans.
Knowledge Check
APPLY: A classmate imports a scanner PDF, sees CVE-2021-44228 next to 127.0.0.1:8000 python http.server, and wants to Nessus the café “to find the real ones.” What is the row, and what do you do?
Multiple choice
Knowledge Check
APPLY: True or False: If a scanner lists a CVE against a banner you saw on localhost http.server, you have confirmed remote code execution and should scan random internet IPs for more copies.
True or False
Knowledge Check
APPLY: Which note pairing matches scanner-versus-risk hygiene for this lesson?
Multiple choice
Knowledge Check
APPLY: curl of http://192.168.0.1/ shows a home router login (TP-Link / Netgear / Huawei / "Router Admin"). Is that DEMO in scope as a hacking target?
Multiple choice