NetRecon
Concurrent TCP port scanner with banner grabbing — the network discovery workhorse of the toolkit.
Overview
NetRecon probes TCP ports across a target using a fixed worker pool with atomic work-stealing. Each probe performs a timed connect plus an optional banner read. Results are printed as they are found and can be emitted as JSON-lines for pipeline integration.
Key design points:
- Fixed worker pool (default 128 threads) with a shared
Mutex<VecDeque>work queue TcpStream::connect_timeout— no OS-level connect hangs- Deterministic service-name mapping for 50+ well-known ports
- Best-effort banner grab: sends a bare
\r\n, reads up to 200 bytes of the reply (works for HTTP, SMTP, FTP, SSH, and more)
Usage
netrecon <target> [ports] [--threads N] [--timeout MS] [--json]
ARGUMENTS:
target IP address, hostname, or CIDR (e.g. 10.0.0.0/24)
ports comma list and/or ranges (default 1-1024)
OPTIONS:
--threads N worker threads (default 128)
--timeout MS connect timeout ms (default 1000)
--top N scan the N most common ports (nmap-style preset)
--json JSON-lines output (includes detected product)
Banner-based product detection is built in: HTTP Server: headers,
SSH-2.0 implementation strings, and SMTP/FTP greetings are parsed and
reported for every open port (plain table and --json).
Examples
# Scan localhost for common services
netrecon 127.0.0.1 22,80,443
# Scan a /24 subnet's top ports with 64 threads
netrecon 192.168.1.0/24 1-1024 --threads 64
# Quick sweep: the 50 most common ports with product detection
netrecon 10.0.0.7 --top 50
# Hostname resolution
netrecon example.com 80,443
# JSON output for jq pipelines
netrecon 10.0.0.5 22,80,443,3306 --json | jq .
Target expansion
| Input | Expansion |
|---|---|
| Single IP | 127.0.0.1 → one address |
| Hostname | example.com → resolved via ToSocketAddrs (all returned addresses) |
| CIDR | 10.0.0.0/24 → 256 addresses |
| CIDR guard | /0–/7 refused (more than 16M hosts is impractical) |
| IPv6 | Not supported for CIDR (explicit error) |
Port parsing
Ports accept comma-separated lists and lo-hi ranges:
22,80,443 → 22, 80, 443
1-1024 → 1..=1024
22,80,8000-8100 → mixed list and range
Banner grabbing
After a successful connect, NetRecon:
- Sets read timeout (1.5 s) and write timeout (500 ms)
- Sends a generic
\r\nprobe - Reads up to 512 bytes, keeps the first 200 as UTF-8 (lossy), trims
- Reports the banner alongside the service name
Output
Human-readable:
10.0.0.5:22 ssh OpenSSH_9.2p1 Debian-2+deb12u1
10.0.0.5:80 http
10.0.0.5:443 https
JSON-lines (--json):
{"addr":"10.0.0.5","port":22,"service":"ssh","banner":"OpenSSH_9.2p1"}
Service map (selection)
ftp (20/21) · ssh (22) · smtp (25) · dns (53) · http (80) ·
pop3 (110) · msrpc (135) · netbios-ssn (139) · imap (143) ·
snmp (161/162) · ldap (389) · https (443) · microsoft-ds (445) ·
mysql (3306) · rdp (3389) · postgresql (5432) · redis (6379) ·
kubernetes (6443) · mongodb (27017) and 40+ more.
Implementation notes
parse_cidrguards against shift overflow and OOM for huge prefixes- Results are sorted by (address, port) before printing
- The banner field escapes
"for safe JSON embedding