Skip to content

Syslifters/smartscanner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SmartScanner

A resumable, plugin-based network scanner for penetration testing engagements.

SmartScanner wraps nmap with a stateful, interactive shell so you can fire off network sweeps, walk away, come back the next day, and pick up exactly where you left off. Discovered hosts and ports are persisted in a local SQLite database. As ports are discovered, protocol-specific plugins automatically run against them (HTTP headers, SSL certificates, SMB shares, SSH algorithms, RDP NLA, FTP anon, VNC, Telnet, screenshots, reverse DNS, ...). Everything can be streamed live into a SysReptor project.

Unlike a one-shot nmap invocation, it:

  • Keeps all state (network ranges, scan tasks, hosts, ports, plugin results) in a local SQLite database, so you can pause, exit, and resume scans across sessions.
  • Splits large CIDR ranges into manageable chunks (max /25) and runs them in parallel.
  • Performs a two-stage scan: a fast SYN sweep of the top 1000 TCP ports to identify live hosts, then a full -p- -sV -sC --script vuln,default,safe,discovery,auth scan against the hosts that were actually responsive.
  • Runs plugins automatically against discovered services (e.g. takes a screenshot of every HTTP service, dumps every SSL cert, lists SMB shares, flags weak SSH ciphers, ...).
  • Continuously syncs results to SysReptor as structured notes (one note per host, with screenshots inlined).

Table of Contents


Plugins

Plugins are auto-loaded on startup and hook into port discovery. Each plugin declares which ports/services it cares about and only runs when a matching port is found.

Plugin Trigger What it does
dns_reverse Every new host Reverse-DNS lookup for the host's IP
ftp_anon FTP ports (21, etc.) Tries anonymous login
http_headers HTTP/HTTPS ports (80, 443, 8080, 8443, 8000, 8888, 3000, 5000, 9090, or service contains http) Fetches response headers, page <title>, and fingerprints common tech (WordPress, Jenkins, Grafana, Tomcat, IIS, ...)
http_screenshot Same as http_headers plus 8843, 9443 Takes a headless Chrome screenshot of the IP and of every hostname found in the SSL cert SANs
rdp_nla RDP (3389) Checks whether Network Level Authentication is enforced
smb_info SMB (445, 139) NetBIOS name query, anonymous + authenticated SMB enumeration (OS, signing, shares, directory listing)
ssh_info SSH (22) Enumerates KEX / host-key / cipher / MAC algorithms and flags weak ones
ssl_info TLS-speaking ports Extracts CN, SANs, issuer, validity. Found hostnames feed back into http_headers and http_screenshot so they re-run per SAN.
telnet_info Telnet (23) Grabs the cleartext banner (and flags it as plaintext)
vnc_info VNC (5900+) Negotiates the RFB handshake and reports the supported auth types

If a plugin's dependencies are missing (e.g. paramiko for ssh_info, impacket for smb_info, Chrome for http_screenshot), it is disabled at startup and you will see a Plugin disabled: ... message — the rest of SmartScanner continues to work.


Installation

1. System requirements

  • Python 3.8+
  • nmap (must be in $PATH). On macOS: brew install nmap. On Debian/ Ubuntu: sudo apt install nmap. On Windows: install from https://nmap.org/download.html.
  • Chrome or Chromium (optional, only needed for the http_screenshot plugin). On macOS just install Google Chrome normally; Selenium 4 will manage the driver automatically.

2. Python dependencies

git clone <repo-url> smartscanner
cd smartscanner

# (optional) virtualenv
python3 -m venv venv
source venv/bin/activate

pip install -r requirements.txt

3. Run it

python -m smartscanner.main

You should see:

Initializing SmartScanner...
  nmap found: /opt/homebrew/bin/nmap
  Loaded plugin: dns_reverse
  Loaded plugin: http_headers
  Loaded plugin: http_screenshot
  ...
SmartScanner - Network Scanner
Type 'help' for commands.
SmartScanner>

Tip: SYN scans (-sS) require root/Administrator. SmartScanner automatically falls back to -sT (TCP connect) if nmap complains about privileges, so running unprivileged is fine — it's just a bit slower and more visible on the wire. For best results, run with sudo.


Quick Start

SmartScanner> set scan_speed aggressive
Scan speed set to 'aggressive' (nmap -T4)

SmartScanner> set max_parallel_tasks 8
Setting 'max_parallel_tasks' set to '8'

SmartScanner> add 10.0.0.0/24
Added network range: 10.0.0.0/24 (ID: 1)

SmartScanner> resume
Scanning resumed

SmartScanner> status
=== Scan Status ===
Networks: 1 total (0 pending, 1 scanning, 0 completed, 0 paused)
Tasks: 2 total (1 pending, 1 running, 0 completed, 0 failed)
Hosts: 0 total ...

When the basic scan finishes for a chunk, SmartScanner automatically queues a full scan for the same chunk, and plugins fire as ports come in. You can pause, quit, restart later, and resume — pending tasks are picked back up from the database.


Shell Commands

Command Description
add <cidr> Add a network range to scan (e.g. add 192.168.1.0/24). Gets split into /25 chunks.
status Show counts of networks / tasks / hosts / ports.
tasks [all|pending|running|failed|completed] [N] List scan tasks. With no arg shows non-completed ones.
task <id> Show full details of a single scan task, including error output.
hosts List discovered hosts.
ports <host_ip> List open ports for a host.
plugins [executions] List loaded plugins and per-plugin execution summary. Add executions to see every execution row.
retry [scan|plugin] [id] Re-queue failed tasks / plugin executions. With no arg retries everything that failed.
rerun scan <id|all|basic|full> Force-rerun successful scan tasks.
rerun <plugin_name> [port_id] Force-rerun a plugin (optionally on a specific port).
rerun execution <id> Force-rerun a single plugin execution by ID.
rerun all Force-rerun every completed plugin execution.
pause Pause all scans (workers stop pulling new tasks; current ones finish).
resume Resume paused / pending scans and plugin executions.
clear [completed|failed|all] Delete finished task rows. Default = completed only.
fixstatus Recalculate host statuses (discoveredbasic_scan_donefull_scan_doneplugins_done) from actual scan data.
settings Print all current settings.
set <key> <value> Update a setting (see Settings Reference).
export <json|csv|xml> [file] Dump results to disk. Default filename is smartscanner_export_<timestamp>.<ext>.
sync [full] Push data to SysReptor. Default is a delta sync (only changed hosts); sync full re-pushes everything.
quit / exit Shut down gracefully.

Settings Reference

Settings persist in the database. Set them with set <key> <value> and view them with settings.

Scan engine

Key Type / Allowed values Default Meaning
scan_speed paranoid / sneaky / polite / normal / aggressive / insane normal Maps to nmap -T0..-T5.
nmap_min_rate int 010000 300 nmap --min-rate packets/sec. 0 disables.
nmap_host_timeout int seconds, 086400 0 nmap --host-timeout per host (full scans only). 0 disables.
nmap_script_timeout int seconds, 086400 0 nmap --script-timeout per NSE script. 0 disables.
nmap_version_intensity int 09 0 nmap --version-intensity. 0 uses nmap's default (7).
disable_ping true / false false Skip the basic top-1000 sweep, jump straight to the full scan with -Pn.
chunk_size int 165536 256 Reserved; chunks are currently capped at /25 (≤128 hosts) by nmap_wrapper.py.
max_parallel_tasks int 132 4 Number of concurrent nmap scan workers.
max_parallel_plugins int 116 2 Number of concurrent plugin worker threads.
plugin_timeout int seconds, 103600 300 Soft per-plugin timeout.
auto_resume true / false true Reserved (no longer auto-runs at startup; use resume).

SMB authentication (used by the smb_info plugin)

Key Type Default Meaning
smb_user str Username for authenticated SMB enumeration.
smb_password str Password for authenticated SMB enumeration.
smb_domain str Domain / workgroup. Leave empty for local accounts.

If left empty, smb_info will still try anonymous / null sessions and report shares it can list that way.

SysReptor integration

Key Type / Allowed values Default Meaning
reptor_server URL e.g. https://reptor.example.com
reptor_token str SysReptor API token (see SysReptor → User → API Tokens).
reptor_project_id UUID The project ID to write notes into.
reptor_background_sync true / false false When true, a control thread pushes changed hosts every ~30 seconds.
reptor_background_sync_threads int 116 2 Number of subprocesses that perform background sync in parallel.
reptor_sync_timeout int 6036000 600 Hard timeout for a single sync subprocess invocation (seconds).

Example: End-to-End Pentest Workflow with SysReptor

This is the typical engagement workflow. The SysReptor side is set up once, then SmartScanner streams its findings into the project for you.

Step 1 — Prepare the SysReptor project

In your SysReptor instance:

  1. Create a new project for the engagement (or open an existing one).
  2. Note the project ID from the URL: https://<sysreptor>/projects/<PROJECT_ID>/...
  3. Create an API token: click your user → API TokensCreate token → copy it (you'll only see it once).

The first sync will create a root note called Smartscanner in that project, with Hosts → Hosts - Open Ports and Hosts → Hosts - No Open Ports as sub-notes. Each scanned host becomes its own note underneath, titled by IP, with an emoji indicating scan progress (❓ → 🔍 → 🧠 → ✅).

Step 2 — Configure SmartScanner

Start SmartScanner and set the SysReptor credentials:

SmartScanner> set reptor_server https://sysreptor.example.com
Setting 'reptor_server' set to 'https://sysreptor.example.com'

SmartScanner> set reptor_token sR_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Setting 'reptor_token' set to 'sR_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

SmartScanner> set reptor_project_id 8f3c2b1a-0d4e-4a1c-9b7e-6f9a2c1d3e4f
Setting 'reptor_project_id' set to '8f3c2b1a-0d4e-4a1c-9b7e-6f9a2c1d3e4f'

Verify with:

SmartScanner> settings

Step 3 — Tune the scan for the engagement

For a typical internal pentest where you want to be quick but not too noisy:

SmartScanner> set scan_speed aggressive
SmartScanner> set max_parallel_tasks 6
SmartScanner> set max_parallel_plugins 4
SmartScanner> set nmap_min_rate 500
SmartScanner> set nmap_host_timeout 1800
SmartScanner> set nmap_script_timeout 120

If the network drops ICMP and you know hosts are alive anyway:

SmartScanner> set disable_ping true

This skips the basic ping/top-1000 sweep and goes directly to the full -Pn -sS -sV -sC --script vuln,default,safe,discovery,auth -p- scan.

If you have domain credentials and want SMB share enumeration to be authenticated:

SmartScanner> set smb_user pentest
SmartScanner> set smb_domain CORP
SmartScanner> set smb_password 'Sup3rSecret!'

Step 4 — Enable live background sync (optional but recommended)

SmartScanner> set reptor_background_sync true
SmartScanner> set reptor_background_sync_threads 3

A control thread now wakes up every ~30s, picks up every host whose version is greater than its synced_version, and pushes it to SysReptor via 3 worker subprocesses. Screenshots are uploaded to SysReptor's file store and embedded inline in the host note.

Note: any content you write outside of the <!-- SMARTSCANNER_START:... --> / <!-- SMARTSCANNER_END:... --> markers in a managed note is preserved across syncs. Anything inside the markers will be overwritten on the next sync.

Step 5 — Add the in-scope ranges and let it run

SmartScanner> add 10.10.0.0/16
Added network range: 10.10.0.0/16 (ID: 1)

SmartScanner> add 192.168.50.0/24
Added network range: 192.168.50.0/24 (ID: 2)

SmartScanner> resume
Scanning resumed

You can now leave it running. Use status, tasks, hosts, and plugins to keep an eye on progress.

Step 6 — Inspect results as they roll in

SmartScanner> hosts
=== Discovered Hosts ===
IP Address         Hostname                  Status         Ports
----------------------------------------------------------------------
10.10.4.17         dc01.corp.local           plugins_done   12
10.10.4.42         fileserver.corp.local     full_scan_done 5
...

SmartScanner> ports 10.10.4.17
=== Ports for 10.10.4.17 ===
Port     Protocol   Service         Version              State
---------------------------------------------------------------------------
53       tcp        domain          -                    open
88       tcp        kerberos-sec    -                    open
389      tcp        ldap            -                    open
445      tcp        microsoft-ds    -                    open
...

Step 7 — Manual sync at the end (or any time)

Background sync runs continuously, but you can also force a sync:

SmartScanner> sync          # delta sync (only changed hosts)
SmartScanner> sync full     # full re-push of every host

Step 8 — Export raw data for the appendix

SmartScanner> export json results.json
SmartScanner> export csv  results.csv
SmartScanner> export xml  results.xml   # nmap-compatible XML

More Examples

Stealthy external scan

SmartScanner> set scan_speed sneaky
SmartScanner> set nmap_min_rate 0
SmartScanner> set max_parallel_tasks 2
SmartScanner> set max_parallel_plugins 1
SmartScanner> add 198.51.100.0/24
SmartScanner> resume

-T1 plus a single scan worker keeps packet rates very low.

Fast lab sweep (you control the network)

SmartScanner> set scan_speed insane
SmartScanner> set nmap_min_rate 5000
SmartScanner> set max_parallel_tasks 16
SmartScanner> set max_parallel_plugins 8
SmartScanner> set disable_ping true
SmartScanner> add 172.16.0.0/22
SmartScanner> resume

Re-running a plugin after fixing its config

You configured SMB credentials after the SMB hosts were already scanned. Re-run smb_info on everything:

SmartScanner> set smb_user pentest
SmartScanner> set smb_password 'Sup3rSecret!'
SmartScanner> rerun smb_info

Or re-run it for one specific port (look up the port ID with plugins executions):

SmartScanner> rerun smb_info 42

Retrying everything that failed (e.g. a flaky link)

SmartScanner> tasks failed
SmartScanner> retry

Cleaning up before a new engagement

The database lives in ~/.smartscanner/. To start completely fresh:

rm -rf ~/.smartscanner

This deletes the database, screenshots, and the Selenium driver cache.


Data Storage

Path Purpose
~/.smartscanner/smartscanner.db SQLite DB (hosts, ports, tasks, plugin results, settings)
~/.smartscanner/screenshots/ PNGs taken by http_screenshot
~/.smartscanner/selenium-cache/ Selenium Manager's driver cache

You can override the DB path with the SMARTSCANNER_DB_PATH environment variable, e.g. one DB per engagement:

SMARTSCANNER_DB_PATH=/data/engagements/acme/scan.db python -m smartscanner.main

Building a Standalone Binary

A PyInstaller spec is included. From the repo root:

pip install pyinstaller
pyinstaller smartscanner.spec
# → dist/smartscanner (single-file executable)

The binary still requires nmap to be installed on the target machine, and Chrome/Chromium if you want screenshots.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages