You can build a surprisingly robust asset registry using nothing more than Nmap and a bit of scripting.

Let’s say you want to know what services are running on your internal network. You’ve got a subnet, 192.168.1.0/24, and you want to catalog every active host and the services it’s exposing.

First, we need to discover which hosts are up. A quick nmap -sn 192.168.1.0/24 will send ARP requests (on a local network) or ICMP echo requests (if scanning across a router) to every IP in the subnet. It won’t scan ports, just ping them.

nmap -sn 192.168.1.0/24

This will output a list of hosts that responded. You’ll see output like:

Nmap scan report for 192.168.1.1
Host is up (0.00020s latency).
Nmap scan report for 192.168.1.10
Host is up (0.0050s latency).
...

Now, we want to find out what services are running on those live hosts. We’ll use nmap -sV which performs a service version detection scan. This is crucial because it doesn’t just tell you port 80 is open; it tries to figure out if it’s Apache, Nginx, or something else.

nmap -sV -oG nmap_scan_results.gnmap 192.168.1.0/24

The -oG flag outputs the results in "Grepable" format, which is perfect for parsing with standard Unix tools. We’re scanning the entire subnet again, but this time with service version detection enabled.

Let’s look at a snippet of nmap_scan_results.gnmap:

# Nmap 7.91 scan initiated Fri Oct 27 10:00:00 2023 as: nmap -sV -oG nmap_scan_results.gnmap 192.168.1.0/24
# State         Id        Proto     Port      Service       V
Host: 192.168.1.1     Status: Up
Host: 192.168.1.1     Proto: 6   Port: 22    Service: ssh       Version: OpenSSH 8.2p1 Ubuntu 4ubuntu0.5
Host: 192.168.1.1     Proto: 6   Port: 80    Service: http      Version: Apache httpd 2.4.41 ((Ubuntu))
Host: 192.168.1.1     Proto: 6   Port: 443   Service: ssl/http  Version: Apache httpd 2.4.41 ((Ubuntu))
Host: 192.168.1.10    Status: Up
Host: 192.168.1.10    Proto: 6   Port: 135   Service: msrpc     Version: Microsoft RPC
Host: 192.168.1.10    Proto: 6   Port: 139   Service: netbios-ssn Version: Microsoft Windows netbios-ssn
Host: 192.168.1.10    Proto: 6   Port: 445   Service: microsoft-ds Version: Windows Server 2019 Standard 17763
...

This output gives us the IP address, the protocol (TCP or UDP), the port number, the common service name (like http, ssh, microsoft-ds), and critically, the Version string. This version string is gold for inventory. It tells you exactly what software and version is running on that port.

To build an asset registry, you can parse this nmap_scan_results.gnmap file. A simple awk script can extract the relevant fields:

awk '/^Host:/ { ip = $2 } /^Host:.*Port:/ { print ip "," $4 "," $5 "," $6 }' nmap_scan_results.gnmap > asset_registry.csv

This awk command does two main things:

  1. When it sees a line starting with Host:, it stores the IP address in the ip variable.
  2. When it sees a line starting with Host: and also containing Port:, it prints the stored IP, followed by the port number, service name, and version string, separated by commas.

The output asset_registry.csv will look like this:

192.168.1.1,22,ssh,OpenSSH 8.2p1 Ubuntu 4ubuntu0.5
192.168.1.1,80,http,Apache httpd 2.4.41 ((Ubuntu))
192.168.1.1,443,ssl/http,Apache httpd 2.4.41 ((Ubuntu))
192.168.1.10,135,msrpc,Microsoft RPC
192.168.1.10,139,netbios-ssn,Microsoft Windows netbios-ssn
192.168.1.10,445,microsoft-ds,Windows Server 2019 Standard 17763
...

This CSV file is your asset registry. You can import it into a spreadsheet, a database, or use it for further analysis. For instance, you could quickly identify all servers running an outdated version of Apache or all Windows machines with SMB exposed.

The real power comes from combining this with other Nmap options. For example, using -O to attempt OS detection provides another layer of information.

nmap -sV -O -oN nmap_scan_results.txt 192.168.1.0/24

The -oN flag outputs in normal format, which is more human-readable and includes OS detection results. You’d then need a more sophisticated script to parse this, but it would give you OS information alongside service details.

A common pitfall is assuming all devices respond to pings. If a host has ICMP blocked, the -sn scan won’t see it. In such cases, you can use a SYN scan (-sS) which is stealthier and often gets through firewalls that block ICMP, but requires root privileges.

sudo nmap -sS -sV -oG nmap_scan_results.gnmap 192.168.1.0/24

Remember to run Nmap scans during off-peak hours or with appropriate network impact considerations. For large networks, breaking the scan into smaller subnets can be more manageable.

The most surprising thing is how much detailed version information Nmap can glean from just a few packets. It’s not just guessing; it’s analyzing the banners and responses from services to match them against a vast internal database of known software and versions. This is why nmap -sV is so effective for inventory.

You’ll likely want to schedule these scans regularly and store the output historically to track changes in your environment.

Want structured learning?

Take the full Nmap course →