Lion Cipher Lab
Catch new open ports: a Python Nmap-diff surface monitor
- Cyber / Security Engineer
- Intermediate
- ~50 min
- Free · no account required
Why it matters
A single nmap scan is a photograph, and a photograph of a busy host is noise — a wall of open ports you skim once and forget. The thing that actually matters for defence is the CHANGE. A port that is open today and was not open yesterday is, at best, new attack surface nobody told you about (a debug server left running, a container that published a port, a teammate's quick test that never got torn down) and, at worst, the visible tell of a compromise — a backdoor, a reverse shell's listener, a crypto-miner's control port. The signal is the diff, not the scan. But nobody re-runs nmap against…
What you'll learn
- running nmap with machine-readable XML output (-sV -oX) instead of grepping human text
- driving nmap from Python with subprocess and parsing its XML with xml.etree.ElementTree
- extracting open ports and service/version per host into a stable, comparable structure
- storing a baseline as JSON and diffing a fresh scan against it for NEW / CHANGED / closed ports
- returning a non-zero exit code when new ports appear so a scheduler or CI can act on it
- handling real messiness: a down/unreachable host (inconclusive, not 'all closed'), filtered vs open, and first-run
- scheduling the check with cron (Linux/macOS) and schtasks (Windows), including the PowerShell --% quoting gotcha
- judgment: why the diff is the signal, when a homegrown differ is enough, and when to graduate to a purpose-built surface tool
Steps in this lab
- The idea in one sentence: a scan is noise, the diff is the signal
- Authorised targets ONLY — this is the rule, not a footnote
- Scan into machine-readable XML — never grep the human output
- Write the differ — standard library only, no python-nmap
- Run it twice — the first run is the baseline, the second is the diff
- Handle the messiness a naive `diff` never survives
- Why -sV matters: a service swap on an unchanged port is invisible to a port-only diff
- Schedule it and turn the exit code into an alert
- When this is enough — and when to reach for a real surface tool instead