-
Notifications
You must be signed in to change notification settings - Fork 56
Usage
Export nmap scan results using -oX
option in nmap:
nmap -A -T4 -oX nmap.xml [target]
Choose format (html, csv, markdown or json) and use with nmap formatter
nmap-formatter [html|csv|md|json|dot] [path-to-nmap.xml] [flags]
Or alternatively you can read file from stdin and parse it
cat some.xml | nmap-formatter json
Same way it can be piped using nmap -> nmap-formatter -> jq. But I would suggest to save XML output to some file in the first place.
nmap -v -A -T5 -oX - 192.168.1.1 | nmap-formatter json | jq
Convert nmap output to nicer HTML
nmap-formatter html [path-to-nmap.xml] > some-file.html
Convert nmap output to Markdown
nmap-formatter md [path-to-nmap.xml] > some-markdown.md
Convert nmap output to JSON
nmap-formatter json [path-to-nmap.xml]
# This approach is also possible
cat nmap.xml | nmap-formatter json
It can be also combined with a jq tool
cat nmap.xml | nmap-formatter json | jq
List all the found ports and count them:
nmap-formatter json nmap.xml | jq -r '.Host[]?.Port[]?.PortID' | sort | uniq -c
Output:
1 "22"
2 "80"
1 "8080"
Select only those hosts that have http service running:
nmap-formatter json nmap.xml | jq '.Host[]? | . as $host | .Port[]? | select(.Service.Name== "http") | $host.HostAddress.Address' | uniq -c
Explanation:
nmap-formatter json nmap.xml | # Simply parsing nmap.xml file and converting that to json
jq '.Host[]? | # Piping through jq and making query: selecting each host. '?' showing that .Host[] array might be empty
. as $host | # Saving $host as a variable, we would use it later
.Port[]? | # Select a list of ports (which might not exist/be empty)
select(.Service.Name== "http") | # Where service name is "http", nmap determines that by itself
$host.HostAddress.Address' | # Select parent $host variable and print an address, also it's end of jq query with `'`
uniq -c # Display those addresses in unique manner, counting repeated occurences
Result of such command:
1 "192.168.1.1"
1 "192.168.1.2"
2 "192.168.1.3"
# In this case 192.168.1.3 has 2 http services running (for example on ports 80 and 8080).
Another example where it is needed to display only filtered ports:
nmap-formatter json nmap.xml | jq '.Host[]?.Port[]? | select(.State.State == "filtered") | .PortID'
Display host IP addresses that have filtered ports:
nmap-formatter json nmap.xml | jq '.Host[]? | . as $host | .Port[]? | select(.State.State == "filtered") | .PortID | $host.HostAddress.Address'
Scan just found http services with Nikto web-server scanner:
nmap-formatter json nmap.xml | jq -r '.Host[]? | . as $host | .Port[]? | . as $port | select(.Service.Name== "http") | [$host.HostAddress.Address, $port.PortID] | @tsv' | awk '{ print "-host "$1" -port "$2 }' | xargs -n4 nikto
# We extract address and port with the help of jq tool, print them separately with \t
# Like this: 192.168.1.1 80, and using awk we print arguments for `nikto` web-server scanner
# We use then xargs to pass those arguments to nikto itself
NB! In some cases it's definitely easier to use Grepable Output (nmap option -oG
) instead of this approach, this one has been made simply as a proof of concept.
There is various flags and output options that allow you to customize your output.
-
-f
,--file [filename]
outputs result to the file (by default output goes to stdout) -
--help
display help message -
--version
display version (also can be used: ./nmap-formatter version)
Custom options can be used to deliver some information to the output (like user ID, or environment or hostname where scan has been performed). For this purpose there is --x-opts
flag exists. It's possible to use multiple variables:
nmap-formatter md nmap-file.xml --x-opts="Hostname=$HOST" --x-opts="Terminal=$TERM"
The end result would contain those values after Scan Summary
chapter. It would look something like this:
Key | Value |
---|---|
Hostname | hostname123 |
Terminal | xterm-256color |
This command is applicable only in HTML & Markdown templates.
Flag | Description | Default | Example |
---|---|---|---|
--html-skip-down-hosts |
Skip hosts that are down (offline/unable to connect), so they won't be shown in the output | true |
--html-skip-down-hosts=false |
--html-skip-summary |
Skip summary, it won't show various meta information about the scan | false |
--html-skip-summary=false |
--html-skip-traceroute |
Skip traceroute information (from the machine that ran nmap to the target) | false |
--html-skip-traceroute=false |
--html-skip-metrics |
Skip miscellaneous metrics information | false |
--html-skip-metrics=true |
--html-skip-port-scripts |
Skip port scripts output (nse-scripts) | false |
--html-skip-port-scripts=false |
--html-use-template |
Use specific HTML template instead of default one | "" |
--html-use-template /path/to/template.html |
--html-dark-mode |
Dark mode in HTML template, enabled by default | true |
--html-dark-mode=false |
Flag | Description | Default | Example |
---|---|---|---|
--md-skip-down-hosts |
Skip hosts that are down (offline/unable to connect), so they won't be shown in the output | true |
--md-skip-down-hosts=false |
--md-skip-summary |
Skip summary, it won't show various meta information about the scan | false |
--md-skip-summary=false |
--md-skip-traceroute |
Skip traceroute information (from the machine that ran nmap to the target) | false |
--md-skip-traceroute=false |
--md-skip-metrics |
Skip miscellaneous metrics information | false |
--md-skip-metrics=true |
--md-skip-port-scripts |
Skip port scripts output (nse-scripts) | false |
--md-skip-port-scripts=false |
--md-use-template |
Use specific Markdown template instead of default one | "" |
--md-use-template /path/to/template.md |
Flag | Description | Default | Example |
---|---|---|---|
--csv-skip-down-hosts |
Skip hosts that are down (offline/unable to connect), so they won't be shown in the output | true |
--csv-skip-down-hosts=false |
Flag | Description | Default | Example |
---|---|---|---|
--json-pretty |
Pretty print of JSON output | false |
--json-pretty=true |
N/A
Flag | Description | Default | Example |
---|---|---|---|
--sqlite-dsn |
A location to SQLite database (DSN) | nmap.sqlite |
file:nmap.db?shared=true |
--scan-id |
A unique scan ID that would allow you to populate scan table with unique identifiers | uniquely generated UUID | my-scan |