β‘ A modern, blazing-fast TUI port scanner built with Textual.
Auto-selects the best backend available β Nmap β Scapy β raw sockets β so it works everywhere, root or not.
Install β’ Quick Start β’ Features β’ Backends β’ Keybindings β’ Exports β’ CLI β’ Architecture
Warning
Authorized-use only. pacPortScanner is built for legitimate security testing, CTFs, and learning on your own infrastructure. Scanning networks you do not own or have written permission to test is illegal in most jurisdictions.
|
|
|
|
βββ β pacPortScanner βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Target: 192.168.1.0/24 β HOST PORT STATE SERVICE β
β Ports : top1000 β 192.168.1.1 22/tcp open ssh β
β Profile: vulnerability β 192.168.1.1 80/tcp open http β
β [β] ping sweep β 192.168.1.5 443/tcp open https β
β [β] banner grab β 192.168.1.5 3306 open mysql β 3 β
β [β] CVE lookup β 192.168.1.7 22/tcp open ssh β
β β β
β βΆ Start scan (s) β β
βββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββ€
β backend: nmap Β· ports/s: 842 Β· open: 12 Β· elapsed: 4.2s Β· ββββββββ 74% β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π οΈ From source
git clone https://github.com/demirgitbuh/pacPortScanner.git
cd pacPortScanner
pip install -e ".[full]"πͺ Windows (PowerShell)
git clone https://github.com/demirgitbuh/pacPortScanner.git
cd pacPortScanner
pip install -e ".[full]"
pacportscannerOn Windows, the Scapy backend requires Npcap with WinPcap API compatibility enabled.
# launch the TUI
pacportscanner
# prefill a target and profile
pacports scanme.nmap.org -p top1000 --profile vulnerability
# force a specific backend
pacports 10.0.0.0/24 --backend socket --no-cveπ Step-by-step
- Launch with
pacportscanner. - Enter a target in the left panel (IP, hostname, or CIDR).
- Pick a port preset or type a custom spec (e.g.
22,80,443or1-1024). - Choose a profile and press
sto start. - Results stream into the table in real time. Press
Enteron a row for full detail. - Press
eto export β three reports land in./data/.
On startup, pacPortScanner probes available backends in priority order:
| # | Backend | Needs | SYN | UDP | OS Detect | Root |
|---|---|---|---|---|---|---|
| 1 | Nmap | python-nmap + nmap binary |
β | β | β | optional |
| 2 | Scapy | scapy |
β | β | β | β required |
| 3 | Socket | stdlib only | β (connect) | β | β | β not needed |
flowchart LR
A[Start] --> B{Nmap available?}
B -- yes --> N[π Nmap backend]
B -- no --> C{Scapy + root?}
C -- yes --> S[π Scapy backend]
C -- no --> K[π Socket backend]
N --> R[(Streaming results)]
S --> R
K --> R
The active backend is shown in the status bar β or force one with --backend.
| Profile | Ports | Techniques |
|---|---|---|
π₯· stealth |
top 100 | SYN (if available) Β· slow timing |
β‘ fast |
top 100 | Connect scan Β· aggressive timing |
π¬ full |
1β65535 | Connect scan Β· service + banner grab |
π‘οΈ vulnerability |
top 1000 | Full + OS detect + CVE lookup |
| Key | Action |
|---|---|
| s | Start / stop the current scan |
| e | Export results (JSON + CSV + HTML) |
| p | Cycle scan profile |
| d | Toggle detail drawer |
| l | Toggle live log panel |
| Enter | Open detail drawer on selected row |
| Tab | Cycle focus between widgets |
| ? | Show help overlay |
| q | Quit |
Pressing e writes three files to a data/ folder in your working directory:
data/
βββ pacportscanner_20260418_142301.json # structured, every field
βββ pacportscanner_20260418_142301.csv # spreadsheet-friendly
βββ pacportscanner_20260418_142301.html # styled standalone report
β¨ The HTML report is self-contained (inline CSS, no external assets) β safe to email, attach, or archive.
π JSON shape
{
"tool": "pacPortScanner",
"generated_at": "2026-04-18T14:23:01Z",
"backend": "nmap",
"config": { "targets": ["192.168.1.0/24"], "profile": "vulnerability" },
"summary": { "total": 24, "open": 12, "closed": 8, "filtered": 4, "with_cves": 3 },
"results": [
{
"host": "192.168.1.5",
"port": 3306,
"state": "open",
"service": "mysql",
"version": "MySQL 5.7.32",
"banner": "5.7.32-0ubuntu0.18.04.1",
"cves": ["CVE-2021-2144", "CVE-2021-2154", "CVE-2021-2166"]
}
]
}pacportscanner [target] [options]
positional:
target Prefill target (IP, hostname, or CIDR)
options:
-p, --ports SPEC Port spec (top100 / top1000 / all / 1-1024 / 22,80,443)
--profile PROFILE stealth | fast | full | vulnerability
--backend BACKEND auto | nmap | scapy | socket
--no-cve Disable CVE lookup
--version Print version
-h, --help Show help
Drop a config at ~/.config/pacportscanner/config.toml:
[defaults]
profile = "fast"
timeout = 1.5
concurrency = 500
ping_sweep = true
[cve]
enabled = true
api = "https://cve.circl.lu/api"pacportscanner/
βββ π scanner/ backend ABC + engine + nmap/scapy/socket implementations
β βββ engine.py auto-fallback + streaming AsyncIterator[PortResult]
β βββ nmap_backend.py
β βββ scapy_backend.py
β βββ socket_backend.py
βββ π¨ ui/ Textual App, screens, widgets, and TCSS theme
β βββ screens/
β βββ widgets/
β βββ pacportscanner.tcss
βββ π‘οΈ cve/ async CVE lookup (cve.circl.lu + NVD fallback)
βββ π¦ export/ JSON / CSV / HTML exporters
βββ main.py CLI entry point
𧬠Every backend implements a common
ScannerBackendabstract base class and yieldsPortResultobjects through anAsyncIteratorβ so the UI streams results as they arrive instead of blocking on a full batch.
Caution
CVE data is fetched from public APIs (cve.circl.lu, nvd.nist.gov) and is best-effort. Matches may be incomplete, outdated, or version-mismatched. Never treat a clean scan as proof of security. Always verify findings manually.
Contributions welcome! Please:
- π΄ Fork the repo and create a feature branch
- β¨ Keep changes focused; add a test for any fix
- π¨ Run
ruff check pacportscannerbefore submitting - π Open a PR with a clear description
pip install -e ".[dev]"
ruff check pacportscanner
mypy pacportscanner
pytestReleased under the MIT License β use it, ship it, break it, fix it.
pacPortScanner is intended for authorized security testing, CTF competitions, and learning on your own infrastructure only. Unauthorized scanning is illegal in most jurisdictions. The authors accept no liability for misuse.