Linux host discovery with Nmap

Not everyone has the budget to buy an expensive software suite to do host discovery on the network. Fortunately there are some great open source alternatives. By combining the right tools we can discover hosts and filter the ones we are looking for.

In this article we have the goal to determine what systems on our network are running Linux. Of course it is easy to swap out some pieces in the examples to do the same for Windows, Mac OS or BSDs.

Setting up the toolkit

First of all we need to install the proper tools. For our toolkit and this article, these are:

  • nmap
  • xmllint

For both tools it is better to have one of the latest versions. This is especially true for a better precision of the host detection capabilities in nmap.

Debian/Ubuntu:

apt install nmap libxml2-utils

After installation check if both commands work, so we are sure they are available.

Scan the network

Next step is to scan the network. Since we want to know the operating system, we use the -O option with Nmap. For best results we save the data in a XML file, so we can query that later and extract the data we need.

nmap -O -oX nmapscan.txt 10.0.1.1/16

It might take nmap a while to scan the network. To see the progress press enter and it will show an estimated guess on how far it analyzed the network, discovered hosts and related services.

Parse the data

After a while Nmap is finished and we are ready to look at the scan results. With the data already being exported in XML, we can easily parse the data.

In our case we want to show only the systems which are most likely running Linux. Since we are interested in the IP addresses for further follow-up, we only list entries which have an actual IPv4 address. So we search the XML file for Host entries, where the Status has a value “up” for the state field. Additionally we want only the entries within Os, which fall under the OS family of Linux. For these entries we check if there is a IPV4 filled in and then show it on screen.

echo "xpath //host[status[@state='up'] and os[osmatch/osclass[@osfamily='Linux']]]/address[@addrtype='ipv4']/@addr" | xmllint --shell nmapscan.txt

The output might look like this:

Screenshot of xmllint output to filter nmap scan results

Filtering out Linux host from Nmap scan results

While no option is 100% precise, we consider a system to be “Linux” if the osfamily key is set to this value. Some false positives might show up, like appliances which also run Linux. With the gathered data it is usually easy to determine if we have “strange” machine, for example when doing a reverse lookup on the IP address.

For easier export of the data to a file, use a grep together awk, and we have our list of systems running Linux.

echo "xpath //host[status[@state='up'] and os[osmatch/osclass[@osfamily='Linux']]]/address[@addrtype='ipv4']/@addr" | xmllint --shell nmapscan.txt | grep "content=" | awk -F= '{ print $2 }'

With this information we can run a script against this list to check if SSH is accessible, do reverse lookups, or simple store them for later analysis.

Relevant commands in this article

Like to learn more about the commands that were used in this article? Have a look, for some there is also a cheat sheet available.

Feedback

Small picture of Michael Boelen

This article has been written by our Linux security expert Michael Boelen. With focus on creating high-quality articles and relevant examples, he wants to improve the field of Linux security. No more web full of copy-pasted blog posts.

Discovered outdated information or have a question? Share your thoughts. Thanks for your contribution!

Mastodon icon