Skip to content

Ryan-Frederick-Cyber/ModuScan

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

  __  __           _       _____
 |  \/  |         | |     / ____|
 | \  / | ___   __| |_   | (___   ___ __ _ _ __
 | |\/| |/ _ \ / _` | | | |\___ \ / __/ _` | '_ \
 | |  | | (_) | (_| | |_| |____) | (_| (_| | | | |
 |_|  |_|\___/ \__,_|\__,_|_____/ \___\__,_|_| |_|

ModuScan — Modular Vulnerability Scanner

A production-grade, plugin-based security scanner built in Python.
Port scanning · Web app testing · CVE enrichment · Multi-format reporting

Python License Code Style Security

Built by Silence · v1.0.0
For authorized penetration testing and security research only.


Table of Contents


Overview

ModuScan is a self-contained, modular vulnerability scanner written entirely in Python. It combines network-layer scanning (via nmap), web application testing (SQLi, XSS, LFI, CORS, security headers), CVE enrichment from the NIST NVD API, and professional multi-format reporting into a single cohesive tool with a polished CLI.

The project was designed from the ground up with a plugin architecture — every scanner capability is an independent module that can be enabled, disabled, or replaced without touching any other part of the codebase. This makes it easy to extend, easy to test, and practical to use in real assessments.

moduscan scan 192.168.1.100 --full --report pdf,html
moduscan scan 10.0.0.0/24 --top-ports 1000 --threads 100
moduscan scan https://example.com --web --no-ports --severity HIGH
moduscan report diff scan_before.json scan_after.json

Why I Built This

Most open-source vulnerability scanners fall into one of two categories: they are either overly complex frameworks that require significant setup, or simple scripts that do one thing but can't be composed into a full workflow. I wanted to build something that sat between those extremes — a tool that a security practitioner could actually use day-to-day, with clean output, proper rate limiting, real CVE data, and reports they could hand to a client.

The secondary goal was to build something that demonstrated the full stack of skills I use professionally: async Python, CLI design, REST API integration, HTML/CSS report generation, data modeling, and plugin system design — all in one coherent project.


Build Process & Architecture Decisions

This section documents how the project was actually built, the decisions made along the way, and why. This is the part that matters for understanding the code as a piece of engineering rather than just a tool.

Phase 1 — Project scaffolding and configuration (config.py, requirements.txt)

The first decision was how to handle configuration. Many tools hard-code values or use a flat config file. I chose Python dataclasses loaded from environment variables via python-dotenv. This gives:

  • Type safety — every setting has an explicit Python type, so passing a string where an int is expected fails loudly at startup rather than silently at runtime.
  • Composability — the top-level Config object contains nested sub-configs (NetworkConfig, WebScanConfig, APIConfig, etc.) that can be passed directly to the module that needs them. No module needs to know about settings it doesn't use.
  • 12-factor compliance — all secrets (API keys) come from the environment, never from committed files.
# config.py — each section is its own dataclass
@dataclass
class NetworkConfig:
    max_threads:   int   = int(os.getenv("MODUSCAN_THREADS", "50"))
    http_timeout:  float = float(os.getenv("MODUSCAN_HTTP_TIMEOUT", "10"))
    rate_limit_rps: float = float(os.getenv("MODUSCAN_RATE_LIMIT", "10"))

The master Config class composes all of these and runs post-init logic (e.g., auto-disabling the Shodan module when no API key is present).


Phase 2 — Shared utilities and the Finding model (modules/utils.py)

Before writing any scanner, I needed a shared data contract — a single Finding dataclass that every module returns, regardless of what it scanned. This was the most important architectural decision in the whole project.

@dataclass
class Finding:
    title:       str
    severity:    Severity       # CRITICAL / HIGH / MEDIUM / LOW / INFO
    description: str
    target:      str
    module:      str
    evidence:    str  = ""
    remediation: str  = ""
    cvss_score:  float = 0.0
    cve_ids:     list[str] = field(default_factory=list)
    references:  list[str] = field(default_factory=list)
    tags:        list[str] = field(default_factory=list)
    raw:         dict = field(default_factory=dict)

By standardising on this output format early, I could write the report generator, the CLI display logic, and the diff tool all against a stable interface — and add new scanner modules later without changing any of those downstream components.

The utils.py module also provides:

  • build_session() — pre-configured requests.Session with retry/backoff
  • build_async_client()httpx.AsyncClient for async scanning
  • run_tasks_with_semaphore() — bounded async concurrency primitive
  • classify_target() — detects whether input is IP, CIDR, domain, or URL
  • @with_retry, @rate_limited, timer() — reusable decorators

Phase 3 — Network scanner (modules/network_scanner.py)

The network scanner wraps python-nmap with several important additions:

Structured output types. Rather than returning nmap's raw dict, the scanner parses everything into typed ServiceInfo, PortResult, and ScanResult dataclasses. This means downstream code (the CVE lookup, the report generator) works with clean objects instead of fragile dict key lookups.

Banner grabbing. nmap's -sV flag does version detection but sometimes misses banners or returns incomplete data. The scanner also opens raw TCP connections and reads the first 1024 bytes, then parses those banners with regexes to fill in missing service info.

Vulnerability signature database. Rather than just listing open ports, the scanner checks detected service versions against a library of 15 VulnSignature rules — each with two regexes (service name pattern, version pattern) and full CVE metadata. A port only matches a rule when both regexes fire, keeping false-positive rates low.

@dataclass
class VulnSignature:
    service_re:  str       # matched against service name/product
    version_re:  str       # matched against full version string
    title:       str
    severity:    Severity
    cvss_score:  float
    cve_ids:     list[str]
    remediation: str

Thread pool design. Each host gets its own nmap.PortScanner() instance (they are not thread-safe when shared). The ThreadPoolExecutor is bounded by cfg.network.max_threads and uses as_completed() so results stream in as they finish rather than waiting for the slowest host.


Phase 4 — CVE lookup with rate limiting and caching (modules/cve_lookup.py)

The NIST NVD API has strict rate limits: 5 requests per 30 seconds without an API key, 50 with one. I built a token-bucket rate limiter as a thread-safe class that sleeps precisely the deficit duration when the bucket runs dry — no busy-waiting, no dropped requests.

class _TokenBucket:
    def consume(self, tokens: int = 1) -> None:
        with self._lock:
            # Refill based on elapsed time, then sleep deficit if needed
            self._allowance += elapsed * (self._rate / self._per)
            if self._allowance < tokens:
                sleep_s = deficit * (self._per / self._rate)
                time.sleep(sleep_s)

Every API response is written to a disk cache (.cve_cache/<key>.json) with a 24-hour TTL. Repeated scans against the same targets are instant and work offline.

The local CVE database (data/cve_db.json) ships with 7 seed entries for the most critical CVEs (Log4Shell, Spring4Shell, BlueKeep, EternalBlue, Heartbleed, etc.) and grows automatically as NVD responses are written back to it. This means the fallback database gets richer over time without any manual curation.

The query hierarchy is: disk cache → NVD API → local DB. The module degrades gracefully at every step.


Phase 5 — Web application scanner (modules/web_scanner.py)

The web scanner is built around a plugin system within a module. Every check (SQLi, XSS, LFI, etc.) is a CheckPlugin subclass with:

class CheckPlugin(abc.ABC):
    name:       str   # machine-readable ID
    enabled_by: str   # maps to a bool in WebScanConfig
    
    @abc.abstractmethod
    def run(self, ctx: ScanContext) -> list[Finding]: ...

Adding a new check is three steps: subclass, implement run(), append to REGISTRY. The orchestrator loops the registry automatically.

The crawler runs first. Before any injection checks, a BFS crawler walks the target site (bounded by cfg.web.crawl_depth), collecting all same-origin links and form definitions. Every subsequent check works against the full discovered surface, not just the root URL.

Payload design. Rather than random fuzzing, each check uses a curated payload list:

  • SQLi: 16 error-based payloads + 5 time-based sleep payloads (with 85% timing threshold to account for network jitter)
  • XSS: 14 payloads covering script injection, attribute injection, SVG handlers, and filter-bypass variants
  • LFI: 15 traversal encodings including plain, URL-encoded, double-encoded, and UTF-8 overlong sequences
  • Open redirect: 28 parameter names × 9 redirect payloads

Sensitive file probing uses HEAD requests first (no body, lower bandwidth) and only falls back to GET on 405. It runs inside a ThreadPoolExecutor so all 60+ paths are probed concurrently.

OWASP ZAP integration auto-activates when ZAP_API_URL is set in the environment — no code changes needed. The ZapCheck plugin spiders, passive-scans, and optionally active-scans through ZAP's proxy, then converts every ZAP alert into a Finding.


Phase 6 — Report generator (modules/report_generator.py)

Four output formats, all driven by a single ReportData value object:

HTML is a fully self-contained single file. All structural CSS is inlined; Bootstrap 5, Chart.js, and Tablesort load from CDN on open. The design is dark-themed with severity color-coding throughout. Key sections: hero with risk score gauge, metadata cards, Chart.js doughnut + bar charts, executive summary (auto-generated prose from stats), sortable findings table, per-finding accordion with evidence/remediation, module breakdown cards.

PDF is rendered by WeasyPrint directly from the HTML string with injected @page CSS — A4 sizing, page-number footer via CSS counters, all accordion panels forced open, charts hidden (canvas can't render to static PDF).

JSON is a full structured dump including scan metadata, severity summary, and all Finding objects — suitable for SIEM ingestion, CI/CD assertions, or the report diff command.

CSV is UTF-8 BOM encoded (Excel-compatible), one row per finding, list fields semicolon-joined.

The SeverityStats class computes a weighted risk score (0–100):

score = (CRITICAL × 10) + (HIGH × 6) + (MEDIUM × 3) + (LOW × 1)

This gives a single number that meaningfully reflects both the count and severity distribution of findings.


Phase 7 — CLI (main.py)

I chose Typer over argparse for three reasons:

  1. Native Rich integration — --help output is coloured and formatted automatically
  2. Annotated type hints serve as both validation and self-documentation
  3. count=True for -v/-vv/-vvv verbosity levels works correctly out of the box

The scan orchestrator is an asyncio event loop that runs (host × module) combinations in sequence per host, with a Rich Progress bar that updates its description live as each task starts. Each completed task prints a one-liner with emoji severity counts and elapsed time — giving the user real-time feedback without scrolling past pages of logs.

Exit codes are CI/CD-friendly: 0 = clean, 1 = HIGH findings, 2 = CRITICAL findings, 130 = interrupted.


Features

Feature Details
Network scanning nmap integration, service detection, OS fingerprinting, banner grabbing
Vuln signatures 15 built-in rules: vsftpd backdoor, EternalBlue, BlueKeep, Log4Shell-era services, and more
Web scanning SQLi (error + time-based), XSS, LFI, open redirect, 60+ sensitive paths, security headers, CORS
CVE enrichment NVD API v2 with token-bucket rate limiting, 24h disk cache, offline fallback DB
Reports Self-contained HTML (Bootstrap + Chart.js), PDF (WeasyPrint), JSON, CSV
Plugin system Every check is a CheckPlugin subclass — add new checks without touching existing code
OWASP ZAP Optional active/passive scan integration via ZAP_API_URL env var
CIDR scanning Automatically expands 10.0.0.0/24 into individual hosts
Rate limiting Per-host request rate limiting, NVD API token bucket, configurable everywhere
Rich CLI Typer + Rich: coloured output, live progress bars, severity-coded tables, panels
Exit codes 0 clean / 1 HIGH / 2 CRITICAL — suitable for CI/CD pipelines

Project Structure

ModuScan/
│
├── main.py                    ← Typer CLI — all commands and orchestration
├── config.py                  ← Typed dataclass config, env-driven
├── requirements.txt           ← All dependencies, pinned
├── .env.example               ← API key template (copy to .env)
│
├── modules/
│   ├── __init__.py
│   ├── utils.py               ← Finding, Severity, HTTP helpers, decorators
│   ├── network_scanner.py     ← nmap port scan, banner grab, vuln signatures
│   ├── web_scanner.py         ← Plugin-based web vuln checks + ZAP
│   ├── cve_lookup.py          ← NVD API, rate limiter, disk cache, local DB
│   └── report_generator.py   ← HTML, PDF, JSON, CSV renderers
│
├── data/
│   └── cve_db.json            ← Local CVE database (auto-seeded, grows over time)
│
├── reports/                   ← Generated reports (auto-created)
├── logs/                      ← Log files (auto-created, 7-day rotation)
└── .cve_cache/                ← CVE API response cache (auto-created, 24h TTL)

Installation

Requirements: Python 3.11+, nmap installed on the system.

# 1. Clone the repository
git clone https://github.com/YOUR_USERNAME/ModuScan.git
cd ModuScan

# 2. Create and activate a virtual environment (recommended)
python -m venv .venv
source .venv/bin/activate       # Linux/macOS
.venv\Scripts\activate          # Windows

# 3. Install Python dependencies
pip install -r requirements.txt

# 4. Install nmap (required for network scanning)
# Linux:
sudo apt-get install nmap
# macOS:
brew install nmap
# Windows: https://nmap.org/download.html

# 5. Configure API keys (optional — scanner works without them)
cp .env.example .env
# Edit .env and add your keys

Optional dependencies for enhanced features:

# PDF report generation
pip install weasyprint

# OWASP ZAP integration
pip install python-owasp-zap-v2.4

Quick Start

# Scan a single host with default modules (network, web, cve)
python main.py scan 192.168.1.100

# Full scan — all modules, PDF + HTML reports
python main.py scan 192.168.1.100 --full --report pdf,html

# Subnet scan — top 1000 ports, 100 threads
python main.py scan 10.0.0.0/24 --top-ports 1000 --threads 100

# Web-only scan — skip port scanning, show HIGH+ findings only
python main.py scan https://example.com --web --no-ports --severity HIGH

# Specific modules + custom output directory
python main.py scan example.com --modules web,cve --report html -o ./results

# Dry-run — validate inputs and print scan plan without executing
python main.py scan 10.0.0.1 --full --dry-run

# View a saved report in the terminal
python main.py report view ./reports/moduscan_example.com_20240101.json

# Compare two scans — highlights new and resolved findings
python main.py report diff scan_before.json scan_after.json

# Convert a JSON report to PDF
python main.py report convert scan.json --format pdf

# List available modules
python main.py modules

# Show current configuration
python main.py config

CLI Reference

moduscan scan

moduscan scan TARGET [OPTIONS]

Arguments:
  TARGET    IP address, CIDR range, domain name, or URL

Scope:
  --full                Run ALL available modules
  --web                 Include web application scanner
  --no-ports            Skip network/port scanning
  --modules, -m TEXT    Comma-separated module list
                        Available: network, web, cve, dns, ssl, whois, shodan

Port Options:
  --top-ports N         Scan the N most common TCP ports
  --ports, -p TEXT      Explicit ports: '80,443' or '1-1024'
  --all-ports           Scan all 65535 ports
  --udp                 Enable UDP scanning (requires root)

Output:
  --report, -r TEXT     Formats: html,pdf,json,csv (comma-separated)
  --output, -o DIR      Report output directory [default: ./reports]
  --severity, -s LEVEL  Min severity to display: INFO LOW MEDIUM HIGH CRITICAL

Performance:
  --threads, -t N       Thread pool size [default: 50]
  --timeout SECS        HTTP/connect timeout [default: 10]
  --rate-limit RPS      Requests per second per host [default: 10]
  --proxy URL           HTTP/HTTPS proxy URL

Behaviour:
  --dry-run             Print plan and exit without scanning
  --no-banner           Suppress ASCII banner
  --verbose, -v         Increase verbosity (repeat: -v -vv -vvv)

moduscan report

moduscan report view FILE [--severity LEVEL] [--full]
  View a JSON report in the terminal. --full shows evidence and remediation.

moduscan report diff BEFORE AFTER
  Compare two JSON reports. Exits 1 if new findings exist.

moduscan report convert FILE [--format FORMATS] [--output DIR]
  Re-render a JSON report to HTML, PDF, or CSV.

Other commands

moduscan modules [--verbose]    List available scanner modules
moduscan config [--show-keys]   Show current configuration
moduscan --version              Print version
moduscan --help                 Show help

Module Deep Dives

Network Scanner

Uses python-nmap with -sV (service detection) and -O (OS fingerprinting). For each open port, a raw TCP socket banner grab supplements nmap data. Service info is parsed into typed ServiceInfo, PortResult, and ScanResult dataclasses.

Built-in vulnerability signatures (15 rules):

Service CVE Severity
vsftpd 2.3.4 CVE-2011-2523 (backdoor) CRITICAL 10.0
Apache 2.4.49/50 CVE-2021-41773 / CVE-2021-42013 (RCE) CRITICAL 9.8
RDP exposed CVE-2019-0708 (BlueKeep) CRITICAL 9.8
Exim < 4.92 CVE-2019-10149 (root RCE) CRITICAL 9.8
SMB exposed CVE-2017-0144 (EternalBlue) HIGH 8.1
IIS 5–8 CVE-2017-7269 HIGH 8.1
MSSQL exposed Generic auth risk HIGH 7.2
VNC exposed Generic auth risk HIGH 7.5
Telnet Cleartext credentials HIGH 7.4
OpenSSH < 7.2 CVE-2016-6210 (user enum) MEDIUM 5.3
ProFTPD 1.3.x CVE-2009-0542 (SQLi) HIGH 7.5
Apache EoL End-of-life branch HIGH 7.5
MySQL exposed Exposure risk MEDIUM 5.9
nginx outdated Outdated version MEDIUM 5.3
FTP exposed Cleartext protocol MEDIUM 5.3

Web Scanner

Plugin-based architecture. Built-in plugins:

Plugin What it tests
SqlInjectionCheck Error-based (16 payloads, 15 DB error signatures) + time-based blind (5 sleep payloads) + form POST injection
XssCheck 14 reflected XSS payloads in GET params and form fields
DirectoryTraversalCheck 15 path traversal encodings (plain, URL-encoded, double-encoded, UTF-8 overlong)
OpenRedirectCheck 28 redirect param names × 9 external redirect payloads
SensitiveFilesCheck 60+ paths: admin panels, .env, git repos, backups, phpMyAdmin, Spring actuators, SSH keys
SecurityHeadersCheck 8 required headers (HSTS, CSP, X-Content-Type-Options, etc.) + leaky Server/X-Powered-By
CorsCheck Wildcard ACAO + arbitrary origin reflection with credential escalation
ZapCheck OWASP ZAP spider + passive + optional active scan (set ZAP_API_URL)

CVE Lookup

Query methods:

  • lookup_product(product, version) — keyword search against NVD
  • lookup_cpe(cpe_string) — exact CPE 2.3 URI match
  • lookup_cve_id(cve_id) — direct CVE-ID fetch
  • lookup_batch([(product, version), ...]) — multi-product batch
  • enrich_findings(cve_ids, target) — converts CVE-IDs to full Findings

NVD rate limits respected automatically:

  • Without API key: 5 req / 30s
  • With NVD_API_KEY: 50 req / 30s

Report Generator

SeverityStats.risk_score = (CRITICAL×10) + (HIGH×6) + (MEDIUM×3) + (LOW×1)
Capped at 100. Labels: CLEAN / LOW RISK / MEDIUM RISK / HIGH RISK / CRITICAL RISK

HTML report sections: hero with risk gauge, scan metadata cards, severity doughnut chart, findings-by-module bar chart, auto-generated executive summary, sortable findings table, per-finding accordion (description, evidence, remediation, CVE links, tags), module breakdown, footer.


Configuration

All settings are configurable via environment variables. Copy .env.example to .env and set values there, or export them in your shell.

Variable Default Description
MODUSCAN_THREADS 50 Thread pool size
MODUSCAN_HTTP_TIMEOUT 10 HTTP timeout (seconds)
MODUSCAN_DNS_TIMEOUT 5 DNS timeout (seconds)
MODUSCAN_RATE_LIMIT 10 Requests/sec per host
MODUSCAN_MAX_RETRIES 3 HTTP retry count
MODUSCAN_OUTPUT_DIR ./reports Report output directory
MODUSCAN_FORMATS json,html Default report formats
MODUSCAN_MIN_SEVERITY 0.0 Minimum CVSS score to report
MODUSCAN_LOG_LEVEL INFO Log level (DEBUG/INFO/WARNING)
MODUSCAN_CVE_CACHE_TTL_HOURS 24 NVD response cache TTL
NVD_API_KEY NIST NVD API key (increases rate limit 10×)
SHODAN_API_KEY Shodan API key
VIRUSTOTAL_API_KEY VirusTotal API key
SECURITYTRAILS_API_KEY SecurityTrails API key
ZAP_API_URL OWASP ZAP proxy URL (enables ZAP module)
ZAP_API_KEY ZAP API key
ZAP_ACTIVE_SCAN false Enable ZAP active scanning

Adding a Module

Every scanner module is a Python file in modules/ that exposes one async function:

# modules/my_scanner.py

from modules.utils import Finding, Severity
from config import Config

async def scan(target: str, cfg: Config) -> list[Finding]:
    findings = []

    # ... your scanning logic ...

    findings.append(Finding(
        title       = "Vulnerability Title",
        severity    = Severity.HIGH,
        description = "What was found and why it matters.",
        target      = target,
        module      = "my_scanner",
        evidence    = "Raw snippet or request/response",
        remediation = "How to fix it.",
        cvss_score  = 7.5,
        cve_ids     = ["CVE-2024-XXXXX"],
        references  = ["https://nvd.nist.gov/vuln/detail/CVE-2024-XXXXX"],
        tags        = ["my-tag", "category"],
    ))

    return findings

Then register it in main.py:

MODULE_REGISTRY["my_scanner"] = {
    "label":  "My Scanner",
    "desc":   "What it does in one sentence.",
    "import": "modules.my_scanner",
    "icon":   "🔎",
}

That's all. The CLI, progress bars, report generator, and diff tool all work automatically with any module that returns list[Finding].


Sample Output

Terminal (scan in progress):

  __  __           _       _____   ...
  ModuScan v1.0.0 · by Silence

 ╭─ Scan Plan ──────────────────────────────────────────╮
 │  Target   192.168.1.100  (ip)                        │
 │  Hosts    1                                          │
 │  Modules  🔌 network  🌐 web  🛡 cve                 │
 │  Ports    common ports                               │
 │  Output   ./reports                                  │
 ╰──────────────────────────────────────────────────────╯

 ──────────────────── Scanning ──────────────────────────

 ⠸ 🔌 network        192.168.1.100    ████████░░  4/6   0:00:12

  🔌 network        192.168.1.100     🔴 1  🟠 2  🟡 1   8.4s
  🌐 web            192.168.1.100     🟠 1  🟡 3          12.1s
  🛡 cve            192.168.1.100     🔴 2                 2.3s

 ──────────────────── Results  22.8s ─────────────────────

 ╭─────────────────────── Scan Summary ───────────────────────╮
 │          🔴 CRITICAL 3  🟠 HIGH 3  🟡 MEDIUM 4            │
 │                                                             │
 │            Risk Score  74 / 100  —  CRITICAL RISK          │
 ╰─────────────────────────────────────────────────────────────╯

Risk score output is a weighted sum: CRITICAL×10 + HIGH×6 + MEDIUM×3 + LOW×1, capped at 100.

Exit codes for CI/CD:

moduscan scan $TARGET --severity HIGH
echo $?   # 0 = clean, 1 = HIGH findings, 2 = CRITICAL findings

Technical Skills Demonstrated

Skill Where
Async Python (asyncio, httpx) orchestrate() in main.py, web_scanner.py, cve_lookup.py
Plugin / strategy pattern CheckPlugin base class in web_scanner.py
Data modelling (dataclasses) Finding, CveRecord, PortResult, ScanResult, all config classes
REST API integration NVD API v2 in cve_lookup.py
Rate limiting Token-bucket implementation in cve_lookup.py
Caching TTL disk cache in cve_lookup.py
Threading (ThreadPoolExecutor) network_scanner.py, web_scanner.py
CLI design (Typer) main.py — 7 commands, 20+ flags
Rich terminal UI Progress bars, panels, tables, coloured output throughout
HTML/CSS generation Bootstrap 5 report with Chart.js in report_generator.py
PDF generation WeasyPrint + CSS @page in report_generator.py
Network programming Raw socket banner grabbing in network_scanner.py
Security concepts SQLi, XSS, LFI, CORS, CVSS scoring, CVE data
Configuration management 12-factor env-var config with python-dotenv
Error handling Graceful degradation at every layer, no unhandled exceptions
Type hints Full PEP 526/585 annotations throughout

Roadmap

  • modules/ssl_auditor.py — TLS certificate and cipher audit (sslyze)
  • modules/dns_enum.py — DNS record enumeration and zone transfer
  • modules/subdomain_enum.py — Subdomain brute-force + cert transparency
  • modules/whois_lookup.py — WHOIS and ASN data
  • modules/shodan_lookup.py — Shodan host intelligence
  • Authenticated web scanning (cookie/token injection)
  • Nuclei template integration
  • CI/CD GitHub Actions example workflow
  • Docker image

Legal Disclaimer

ModuScan is for authorized security testing only.

Running this tool against systems you do not own or have explicit written permission to test is illegal in most jurisdictions and may result in criminal prosecution. The author assumes no liability for misuse. Always obtain proper authorization before scanning any target.


Built by Silence · Python · Security · Open Source

About

A modular, plugin-based vulnerability scanner built in Python. Combines nmap port scanning, web application testing (SQLi/XSS/LFI/CORS), NVD CVE enrichment, and professional HTML/PDF reporting into a single Typer CLI with Rich progress bars and CI/CD-ready exit codes.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages