Haxoris Wiki

Incomplete Vulnerability Scan Coverage

How Incomplete Vulnerability Scan Coverage works

Incomplete scan coverage is a clean vulnerability report produced by a scan that only ever looked at part of the estate. The scope is a list of CIDR ranges typed in when the scanner was deployed and rarely revised, so new VLANs, lab ranges, DMZ segments and cloud subnets sit outside it. Credentialed scanning fails quietly when the scan account’s password expired or a host refuses the authentication method, and the job still completes. Hosts that were powered off, on VPN or behind a host firewall at scan time are recorded as not responding. Appliance, OT and printer ranges are usually excluded permanently after one outage, and the exclusion is never revisited.

Every one of those states renders on the dashboard as an absence of findings, which reads as an absence of risk. What the report says does not exist is exactly what the attacker uses: the unpatched service, the default credential, the exposed management interface, each of which has its own page in this section. It survives review because the tracked metric is the critical-findings count, and that count falls when coverage falls. A scanner that quietly loses half the estate looks like a successful remediation programme, because nobody’s dashboard shows the denominator.

Incomplete Vulnerability Scan Coverage in practice

Extract the configured scope and compare it to the routed estate

Read the scope out of the scanner rather than from the runbook, then set it against what the network carries.

# What the scanner has actually been told to look at
curl -sk -H "X-ApiKeys: accessKey=<ACCESS_KEY>;secretKey=<SECRET_KEY>" \
  https://scanner.lab.internal:8834/scans | jq -r '.scans[] | [.id, .name, .status] | @tsv'

curl -sk -H "X-ApiKeys: accessKey=<ACCESS_KEY>;secretKey=<SECRET_KEY>" \
  https://scanner.lab.internal:8834/scans/42 \
  | jq -r '.info.targets' | tr ',' '\n' | tr -d ' ' | sort -u > /tmp/scan-scope.txt

# What the core actually routes
ssh netadmin@core-sw01.lab.internal "show ip route" \
  | awk '/^[COBDS]/{print $2}' | sort -u > /tmp/routed.txt

Any routed prefix with no covering entry in the scope is out of scope by omission. A scope written as hostnames instead of prefixes inherits every gap in DNS as well.

Prove that credentialed scanning authenticated

An uncredentialed scan of a Windows or Linux host completes successfully and reports almost nothing, so check the per-host authentication result rather than the job status.

# Scan information plugin output records credentialed status per host
grep -Ei 'credentialed checks *: *(yes|no)' /tmp/scan-export.csv | sort | uniq -c

# Name the hosts where authentication silently failed
awk -F',' '/[Cc]redentialed checks : no/{print $2}' /tmp/scan-export.csv \
  | tr -d '"' | sort -u > /tmp/uncredentialed.txt
wc -l < /tmp/uncredentialed.txt

A host scanned without credentials had its patch level guessed from banners; count it as unscanned, not as clean. Whether the scan account should hold administrative rights everywhere is the Local Administrator Rights Sprawl page’s question. For coverage, the only thing that matters is whether it authenticated.

Separate “no findings” from “no answer”

Classify every host by its state at scan time. Only one of these states is coverage.

HOST STATE AT SCAN TIME         REPORT SHOWS         TRUE COVERAGE
responded, credentials ok       findings or none     scanned
responded, credentials failed   almost no findings   unscanned, banner guess only
no response, powered off        host not scanned     unknown
no response, host firewall      host not scanned     unknown
address outside scan scope      absent entirely      unknown, invisible
range on permanent exclusion    absent entirely      unknown, standing gap

The summary page counts every row after the first as an absence of risk. Reporting those counts beside the severity totals is what converts a green report into an honest one.

Report effective coverage as a percentage of the inventory

Coverage is a ratio, and the denominator is the authoritative asset list, not the scanner’s own host count.

awk -F',' '/[Cc]redentialed checks : yes/{print $2}' /tmp/scan-export.csv \
  | tr -d '"' | sort -u > /tmp/scanned-ok.txt
cut -f1 /tmp/cmdb-export.tsv | sort -u > /tmp/inventory.txt

total=$(wc -l < /tmp/inventory.txt)
covered=$(comm -12 /tmp/inventory.txt /tmp/scanned-ok.txt | wc -l)
printf 'effective credentialed coverage: %d/%d (%d%%)\n' \
  "$covered" "$total" $(( covered * 100 / total ))

# Name the gap so it becomes a ticket, not a rounding error
comm -23 /tmp/inventory.txt /tmp/scanned-ok.txt > /tmp/never-scanned.txt

Report the percentage and the named list together. Where the inventory itself is incomplete the true figure is lower still, which is what the Shadow IT And Unmanaged Hosts page contributes to this number.

How to fix and prevent Incomplete Vulnerability Scan Coverage

  1. Generate scan scope from the inventory and the routing table
    • Rebuild targets from the system of record and the routed prefixes before each cycle, so a new subnet is in scope the day it is created.
    • A saved target list is a snapshot of the estate on the day someone typed it.
  2. Fail the job when authentication fails
    • Alert on any host reporting credentialed checks as no, and on any drop in the authenticated host count against the previous run. A silent authentication failure is a job failure.
  3. Publish coverage next to findings, every time
    • Report scanned, authenticated and unreachable counts as percentages of the inventory on the same page as the severity totals. A findings count with no denominator is not a measurement.
  4. Treat unreachable hosts as unknown, never as clean
    • Re-scan non-responders in a second window at a different time of day, cover roaming endpoints with an agent-based scanner, and hold the remainder on an exception list until evidence arrives.
  5. Time-box every exclusion and cover it another way
    • OT, medical and printer ranges excluded for stability need an owner, an expiry and a compensating method: passive fingerprinting, an accurate model and firmware inventory mapped to vendor advisories, or a scan inside a maintenance window.

Last updated

References