
An educational Python toolkit for authorized penetration testing: threaded port scanner, subdomain & directory enumeration, banner grabber and host discovery, with a rich CLI.
A lightweight, educational Python toolkit that automates common reconnaissance and enumeration tasks used in authorized penetration testing. Built as a learning project for cybersecurity / ethical-hacking practice.
This toolkit performs active scanning and enumeration. Running it against systems you do not own or lack explicit written permission to test can be a crime in most jurisdictions.
The authors accept no liability for misuse.
What changed from v1 → v2: modular package, argparse CLI with subcommands,
threaded scanners, a rich-powered UI (ASCII banner, live progress bars and
result tables), input validation, an authorization gate, unit tests and a
GitLab CI pipeline.
# install virtualenv and activate
python3 -m venv venv
. venv/bin/activate
# install packages
pip3 install -r requirements.txt
# run (always from the project root)
python3 main.py --help
python -m venv venv
. .\venv\Scripts\activate # (PowerShell)
. venv/scripts/activate # (Git Shell)
pip install -r requirements.txt
python main.py --help
Always run from the project root via python main.py … (the src package
contains modules named http and dir, so running scripts from inside src/
could shadow the standard library).
# Port scan with a custom port set / range
python main.py portscan 192.168.1.10 --ports 22,80,443
python main.py portscan 192.168.1.10 --ports 1-1024
# Banner grab
python main.py banner 192.168.1.10 22
# Directory enumeration (default or custom wordlist)
python main.py dirscan http://target.local
python main.py dirscan http://target.local --wordlist admin login backup api
# Subdomain discovery
python main.py subdomains example.com
# Live-host discovery on a subnet
python main.py netscan 192.168.1.0/24
# HTTP response inspection
python main.py httpprobe http://target.local
# Credential test against a lab login form (authorization required)
python main.py logincheck http://target.local/login \
--users admin user --passwords admin 1234 password
# Global options
python main.py --threads 100 --timeout 1.5 -v portscan 192.168.1.10
# Skip the interactive prompt in scripted, pre-scoped engagements
python main.py --i-am-authorized netscan 10.0.0.0/24
pip install -r requirements-dev.txt # runtime + pytest + ruff
pytest -v # run tests
ruff check . # lint
Runtime dependencies live in requirements.txt; test/lint tools live in
requirements-dev.txt (which pulls in the runtime ones), so end users never
install pytest.
The GitLab pipeline (.gitlab-ci.yml) runs lint + tests on every push.
simple-pentesting/
├── main.py # entry point (run from here)
├── src/ # the package
│ ├── __init__.py
│ ├── cli.py # argparse CLI
│ ├── config.py # defaults & Settings
│ ├── utils.py # validation helpers
│ ├── ui.py # rich UI: banner, progress, tables, auth prompt
│ ├── port_scanner.py # one file per feature ↓
│ ├── banner.py
│ ├── dir.py
│ ├── subdomain.py
│ ├── netscan.py
│ ├── http.py
│ └── login_check.py
├── tests/ # offline unit tests
├── .gitlab-ci.yml
├── requirements.txt # runtime deps
├── requirements-dev.txt # + pytest, ruff
├── LICENSE
└── .gitignore
| Command | What it does |
|---|
portscan | Concurrent TCP connect scan of a host |
banner | Grab a service banner from an open port |
dirscan | Enumerate web paths from a wordlist |
subdomains | Resolve candidate subdomains |
netscan | Discover live hosts across a CIDR range |
httpprobe | Inspect an HTTP response (status, headers, preview) |
logincheck | Lab-only demo of weak/default credential risk (rate-limited) |