Skip to main content

Overview

pyndiff (pronounced pin-diff) easily generates human-readable ndiff output when comparing 2 Nmap XML scan files. It is great for determining what ports have open/closed or had their services change between Nmap scans and presenting it in a visually appealing and consumable way for humans. Unfortunately, both the diff and XML output from ndiff are unreadable and unusable for a large number of targets with many changes. pyndiff has been used to compare two different 40 MB Nmap XML files in 13 seconds!

This library is used in Scantron, the distributed Nmap / masscan scanning framework, to email out Nmap scan diffs (coming soon!).

pyndiff is developed and maintained by @opsdisk as part of Rackspace's Threat and Vulnerability Analysis team.

What is ndiff?

https://nmap.org/book/ndiff-man.html

Ndiff is a tool to aid in the comparison of Nmap scans. It takes two Nmap XML output files and prints the differences
between them. The differences observed are:

* Host states (e.g. up to down)
* Port states (e.g. open to closed)
* Service versions (from -sV)
* OS matches (from -O)
* Script output

Ndiff, like the standard diff utility, compares two scans at a time.

Installation

Using pip:

pip install pyndiff

From GitHub:

git clone https://github.com/rackerlabs/pyndiff.git
cd pyndiff
virtualenv -p python3.6 .venv  # If using a virtual environment.
source .venv/bin/activate  # If using a virtual environment.
python setup.py install

Notes

See Nmap's PR-1807 for a Python3 compatible ndiff. Until PR-1807 is merged into master, the individual ndiff.py found below is used:

https://github.com/nmap/nmap/pull/1807/files#diff-876b1aeeb590be439b50702351985b633655e89e78f6b520f321ce84076c6b32

with one slight modification. Line 1208 is commented out to ignore script output when comparing scans. See https://github.com/rackerlabs/pyndiff/issues/3 for more information.

    "state": self._start_state,
    "service": self._start_service,
    # "script": self._start_script,
    "osmatch": self._start_osmatch,
    "finished": self._start_finished,
}

Helpful Options

--uof - Optionally ignore UDP "open|filtered" port state changes because they aren't definitive.

-d - Stop processing after every diff to validate results only when the -v switch is used.

-v - Print verbose data for troubleshooting. Helpful when used in with -d

Run as script

Human readable

Generate a human-readable overview of the changes.

pyndiff -f1 test-scans/random-1.xml -f2 test-scans/random-2.xml

pyndiff_script.png

Classic text output

Classic ndiff --text output, not human-readable for large scans.

pyndiff -f1 test-scans/random-1.xml -f2 test-scans/random-2.xml -t txt

pyndiff_script_classic.png

pyndiff as a module

import pyndiff

# XML
diff = pyndiff.generate_diff("test-scans/random-1.xml", "test-scans/random-2.xml", ignore_udp_open_filtered=False)

print(diff)

# TXT
diff = pyndiff.generate_diff(
    "test-scans/random-1.xml",
    "test-scans/random-2.xml",
    ignore_udp_open_filtered=False,
    output_type="txt"
)

print(diff)

pyndiff_module.png

test-scans directory

The test-scans directory contains the same test scans found in Nmap's repo found here:

https://github.com/nmap/nmap/tree/master/ndiff/test-scans

Support

This code is supplied as-is and you should not expect to receive support for it. Use it at your own risk.

License

License is Apache License Version 2.0.

Metadata

Release files for pyndiff 1.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyndiff 1.0.2
File Size Uploaded
pyndiff-1.0.2.tar.gz 22.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyndiff 1.0.2
File Interpreter ABI Platform
pyndiff-1.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 46.1 kB

Release files / pyndiff-1.0.2.tar.gz

Download URL pyndiff-1.0.2.tar.gz
Size 22.5 kB
Tags Source
SHA-256 checksum
How to use checksums
8a519b18a7bbb315c043d4543719ce9fb6db8098bfcdd04cb8054b276cc91368
BLAKE2b-256 checksum
How to use checksums
833bfb13918710c4fba40367140f22e3449998f4f66869a7564d0e547ad99ef8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.1 importlib_metadata/3.10.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.6.9

Release files / pyndiff-1.0.2-py3-none-any.whl

Download URL pyndiff-1.0.2-py3-none-any.whl
Size 23.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
92b0a635d0c1aa327ce69f5ad8c84eb570a1ef0a040fb3a9717bac84d134b474
BLAKE2b-256 checksum
How to use checksums
9076ab2ef535cac2f1fb74a9b8dd0c174d0e13134427d6e5c4d66471d1d06b20
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.1 importlib_metadata/3.10.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.6.9

Release history Release notifications | RSS feed

This release

1.0.2 This release

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page