HackBlue

Tools · Nmap and network discovery · 07 / 25

Nmap -sV service and version detection: how it works and how to read it

See how Nmap matches banners and probe responses against nmap-service-probes, tune --version-intensity, and verify versions before you file a finding.

11 min read · practice only with authorization

Probes, matches, and soft matches

Version detection connects to each open port and starts by listening, because many services such as SSH, SMTP, and FTP announce themselves with a banner. If nothing arrives, Nmap sends probes from its nmap-service-probes database, like an HTTP GET or a TLS ClientHello, and compares the replies against thousands of regular expressions.

A full match fills in the product, version, and sometimes extra info such as the OS or a hostname. A soft match identifies the protocol but not the product, so you might see “http” without a server name. Unknown responses get a fingerprint printed so you can submit it to the project.

Intensity trades time for coverage

Each probe has a rarity from 1 to 9. The default intensity of 7 tries most probes. --version-light drops to 2 for speed, and --version-all goes to 9 for stubborn services. Higher intensity sends more unusual data to each port, which takes longer and is more likely to upset fragile devices.

On a lab, try light first and only escalate on ports that stay unidentified. On production equipment such as printers or industrial controllers, check with the owner before running heavy version probes at all.

Snippet
sudo nmap -sV --version-light 192.168.56.101
sudo nmap -sV --version-all -p 8443 192.168.56.101

Lab: confirm a version two ways

Run -sV against a lab VM with SSH and a web server. Note the SSH version string, for example “OpenSSH 9.6p1 Ubuntu 3ubuntu13”. Then confirm it from the host itself with ssh -V and dpkg -l openssh-server. The distribution suffix matters, because Ubuntu and Debian backport security fixes without changing the upstream version number.

That backporting is the single most common reason vulnerability findings based purely on banners are wrong. A banner saying OpenSSH 8.9 on a fully patched Ubuntu 22.04 host can still include fixes for CVEs filed against 8.9. The package changelog, not the banner, tells you.

Snippet
sudo nmap -sV -p 22,80 192.168.56.101
# on the VM
ssh -V
dpkg -l openssh-server | tail -1
apt changelog openssh-server | head -20

Writing a version finding

Quote the exact string Nmap printed and the probe that matched, which you can see with --version-trace. Say whether you confirmed it on the host. A finding that reads “Nmap reports Apache httpd 2.4.41; host package apache2 2.4.41-4ubuntu3.17 includes the fix” is far more useful than a CVE list copied from the banner.

Banners can also be changed by administrators. ServerTokens Prod in Apache or server_tokens off in nginx hides the version deliberately. A missing version is not proof of anything either way.

Diagram

How -sV decides what is listening

  1. Listen

    Wait a few seconds for a banner the service sends on its own.

  2. Probe

    Send probes from nmap-service-probes, rarest last, up to the intensity.

  3. Match

    Compare replies to regex signatures for product, version, and extra info.

  4. Verify

    Confirm the package version on the host before calling it vulnerable.

    Command
    dpkg -l openssh-server

Check yourself

1. Which file holds the probes and match patterns -sV uses?

2. What does raising --version-intensity do?

3. Nmap reports an old OpenSSH version on an Ubuntu host. Why might it not be vulnerable?