tl;dr: With the tool nmap-parse-output you can convert, manipulate or extract data from a Nmap/masscan scan output. This allows you to get the information you’re looking for by just entering a straightforward command.
A while ago, we had to scan a mass amount of IPs within a project for a customer. While it’s feasible to read the whole output of a Nmap scan if you have just a few alive hosts, this was not possible anymore for this mass amount of systems. We’ve started with a masscan to scan all 2^16 ports of the IP ranges and wanted to perform a more precise analysis of the alive hosts (which had responded to at least one SYN packet) with Nmap. The result of this scan grew to nearly a hundred megabyte and we now had to do an analysis of which ports we had to look deeper into and which are intended to be open.
In the past, I have used the Grepable Output (-oG) sometimes, and sometimes XML Output (-oX)
with XPath extract specific information (like HTTP ports) from a scan. I never liked using
cut and co. very much to extract information. Mostly, because it led to unreadable lines of shell commands which are not well adaptable for other use cases.
So I’ve created a bunch of XPath queries to gather the information I’m interested. As a text file full of XPath queries is not very cool, I put them into a little tool: The result is a small shell script named nmap-parse-output. The script takes the XML output of a Nmap or masscan scan and executes an XSL Transformation file with xsltproc and prints the result.
Usage of nmap-parse-output
The usage of nmap-parse-output is pretty simple: It takes the Nmap XML output as the first argument and the command as the second argument. The list of available commands is printed if no command is given or you can look here for it. Bash and ZSH completion is support, too.
If you want to get a few impressions of what you can do with the script, here are some example commands.
Print usage and list of commands:
Write HTML output to scan.html:
$ ./nmap-parse-output scan.xml html > scan.html
Generates a list of all HTTP(s) ports:
$ ./nmap-parse-output scan.xml http-ports http://192.168.0.1:8081 https://192.168.0.1:8443
List all names of detected services and get a list of hosts with the port for the service http-proxy:
$ ./nmap-parse-output scan.xml service-names http https http-proxy ms-wbt-server smtp $ ./nmap-parse-output scan.xml service http-proxy 192.168.0.24:8085 192.168.0.25:9000
Exclude some hosts from a scan and generate a list of ports:
$ ./nmap-parse-output scan.xml exclude '192.168.1.1,192.168.1.20' | nmap-parse-output - ports 22,80,443,8080
scan-all.xml to include only hosts scanned in
scan-subnet.xml and write the output to
$ ./nmap-parse-output scan-all.xml include $(./nmap-parse-output.sh scan-subnet.xml hosts | tr "\n" ",") > filtered-scan.xml
Add comments to a scan, mark specific ports red, and generate a HTML report with the annotations:
$ ./nmap-parse-output scan.xml comment-ports '8080,10.0.20.4:443' 'this port should be filtered' | ./nmap-parse-output - mark-ports '8080,10.0.20.4:443' red | ./nmap-parse-output - comment-hosts '10.0.20.1' 'look further into this host' | ./nmap-parse-output - html > test.html
Remove all ports found in
scan-after.xml and write the output to
$ ./nmap-parse-output scan-after.xml exclude-ports $(./nmap-parse-output.sh scan-before.xml host-ports | tr "\n" ",") > filtered-scan.xml
Extend & Contribute
If you created a cool new command, feel free to make a pull request! I am looking forward to your contribution! 😉