Skip to content
Vsevolod Djagilev edited this page Jun 2, 2024 · 7 revisions

Basic 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|sqlite|excel|d2] [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

More Advanced Usage Examples

Example with filters

There is an option for filters in nmap-formatter, example of such command:

cat nmap.xml | nmap-formatter json --filter ".Status.State == 'up' && any(.Port, { .PortID == 22})" | jq

Would return only those hosts, that are not offline (state is up) and which have any .Port (this is a list) of 22.

Examples with 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'

Example with JQ & Nikto

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.

Flags and Output Options

There is various flags and output options that allow you to customize your output.

Common Flags

  • -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

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.

Output Options

Common options that are applied for all formats/files

Flag Description Default Example
--filter Filter each host by using query expression language https://expr-lang.org/ which is applied to Host struct [] --filter '.Status.State == "up" && any(.Port, { .PortID in [80,443] })' or can be added multiple options (would be applied with AND rule)
--skip-down-hosts Adds new filter in front of all other filter that removes hosts that are offline false --skip-down-hosts=true

HTML

Flag Description Default Example
--html-skip-header Skips header (title) in HTML output false --html-skip-header=true
--html-skip-toc Skips table of contents in HTML output false --html-skip-toc=true
--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

Markdown

Flag Description Default Example
--md-skip-header Skips header (title) in Markdown false --md-skip-header=true
--md-skip-toc Skips table of contents in Markdown false --md-skip-toc=true
--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

CSV

N/A

JSON

Flag Description Default Example
--json-pretty Pretty print of JSON output false --json-pretty=true

DOT (Graphviz)

N/A

SQLite

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

D2

N/A