Utilities for generating nmap target expressions.
Available scripts:
Collapse nmap XML scan results into (port,host) expression pairs.
usage: nmapxml [-0] [-x] [-P] [-S] [-T] [-U] [--prefix WHEN] [-c |
--exact] [--open] [--closed] [--filtered] [--unfiltered]
[--open-filtered] [--closed-filtered] [--state STATE]
[--reason REASON] [--reason-ttl EXPR] [--service NAME]
[FILE ...]
positional arguments:
FILE nmap scan results (file, xml) (default: stdin)
options:
-0, --null separate output items with null character instead of whitespace
-x, --extraports check the 'extraports' subelement for additional matches
protocol options:
include only the specified protocol(s) (default: all)
-P, --ip include if protocol='ip'
-S, --sctp include if protocol='sctp'
-T, --tcp include if protocol='tcp'
-U, --udp include if protocol='udp'
--prefix WHEN when to prepend '[PSTU]:' prefix in generated port expressions.
choices=(never, always, auto) (default: auto)
never: do not add prefixes, collapse ports into a single expression.
always: add prefixes.
auto: add prefixes, except when tcp is the only protocol.
port state options:
include only the specified port state(s) (default: state!='closed')
-c, --complement include the complement of the given port states, eg. '-c --closed' => {'open','filtered','open|filtered'}
--exact include only the exact given port states.
otherwise, also includes ambiguous states, eg. '--filtered' => {'filtered','open|filtered','closed|filtered'}
--open include if state='open'
--closed include if state='closed'
--filtered include if state='filtered'
--unfiltered include if state='unfiltered'
--open-filtered include if state='open|filtered'
--closed-filtered include if state='closed|filtered'
--state STATE include if state like STATE (comma-separated, allow-wildcard)
--reason REASON include if reason like REASON (comma-separated, allow-wildcard)
--reason-ttl EXPR include if reason_ttl equals/satisfies EXPR (comma-separated, allow-cmp-eval)
service options:
--service NAME include if service like NAME (comma-separated, allow-wildcard)
Output is ready to consume as nmap arguments.
The expressions are grouped by their shared ports. If hosts A,B have identical port signatures and can be combined into a single host expression, then they will be collapsed into host AB and emitted as a single (ports,addrs) pair.
A two-phase approach is usually much more efficient for aggressive scanning, because nmap ends up only sending version probes and running scripts on those ports/hosts already known to be open.
nmapxml allows you to do a two-phase scan in the same pipeline.
Example: two-phase scan pipeline
nmap -sS -oX - 10.0.0.0/24 | nmapxml -0 | xargs -n2 -0 -P4 nmap -A -pExample: two-phase scan pipeline, write scan results to a single file (uses GNU parallel)
nmap -sS -oX - -iL addrs.txt -p- | nmapxml -0 | parallel -n2 -0 -j200% -k nmap -A -oN - -p | tee scan.nmapThere are various options for filtering results.
Examples:
nmapxml --open scan.xml
nmapxml --state=open scan.xml
nmapxml --open --open-filtered --exact scan.xml
nmapxml -c --closed scan.xml
nmapxml -U --reason='udp-response' scan.xml
nmapxml --reason-ttl='>0&&<200' scan.xml
nmapxml -T --service='ssh,http*' scan.xmlExpand nmap address expressions to concrete IPv4 addresses, or vice-versa.
usage: addrall [-r] [FILE ...]
positional arguments:
FILE
options:
-r, --collapse collapse ipv4 addresses to nmap address expressions (reverse mode)
Examples:
$ echo 192.168.0.0/16 | addrall | tee expanded.txt
192.168.0.0
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
...
192.168.255.251
192.168.255.252
192.168.255.253
192.168.255.254
192.168.255.255
$ addrall -r < expanded.txt
192.168.0.0/16
$ echo 192.168.0,5.-25,45,75 | addrall
192.168.0.0
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
...
192.168.5.23
192.168.5.24
192.168.5.25
192.168.5.45
192.168.5.75Install using a package manager like uv or pipx:
uv tool install git+https://github.com/crypt0lith/nmaputils.git