Skip to content

kilma98/vulnerability-scanner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VulnScanner

A high-throughput network reconnaissance and vulnerability detection tool built in Python. Scans large IP ranges, fingerprints services via SSL certificates and HTTP responses, detects CVEs from response headers, and stores everything in a PostgreSQL database with a live dashboard.

Built as a personal research project to understand internet-scale attack surface mapping — the same technique used by Shodan, Censys, and professional red teams.


What It Does

IP ranges (GCP, AWS, Azure...)
        │
        ▼
   masscan sweep          → finds open ports at scale (10,000 pkt/s)
        │
        ▼
   SSL cert fetch         → extracts Common Name / domain from each IP
        │
        ▼
   HTTP/HTTPS requests    → grabs title, headers, body preview
   (with SSL fallback chain)
        │
        ▼
   CVE detection          → matches response headers against signature DB
        │
        ▼
   PostgreSQL + dashboard → live results, filterable by CVE, severity, IP

Architecture

vulnerability-scanner/
├── scanner/
│   └── scannerfinal.py       Async scanning engine (aiohttp + asyncio)
│
├── backend/
│   ├── main.py               FastAPI app — all routes + live dashboard UI
│   ├── database.py           Async SQLAlchemy engine (asyncpg driver)
│   ├── models.py             PostgreSQL ORM — scans, findings, scan_changes
│   ├── schemas.py            Pydantic request/response validation
│   ├── crud.py               All DB operations — insert, query, export
│   ├── detector.py           CVE detection engine + inline scoring
│   └── cve_signatures.py     CVE knowledge base (27 signatures)
│
├── requirements.txt
└── README.md

Technical Highlights

Async at every layer

The scanner uses asyncio.gather() to fetch thousands of SSL certificates and HTTP responses concurrently. The backend uses FastAPI + async SQLAlchemy 2.0 + asyncpg — database queries never block the event loop. The scanner and dashboard can run simultaneously without contention.

SSL fallback chain

Many servers on the internet run outdated TLS configurations. Rather than dropping them silently, the scanner tries four SSL contexts in order:

1. Modern      (TLS 1.2/1.3, standard)
2. Legacy TLS  (allows TLS 1.0 / 1.1 — found on IoT, embedded devices)
3. Permissive  (ALL:@SECLEVEL=0 — weak ciphers, legacy appliances)
4. Legacy + Permissive (worst-case configs)
5. Plain HTTP on port 443 (rare but real)

This recovers roughly 30–40% of hosts that would otherwise be silently dropped.

Inline CVE detection

Every scan row gets its CVEs computed at insert time — no separate detection pass needed. Signatures are split into three categories:

Category Meaning Effect on row
cve Signature backed by a real CVE ID Sets cve_ids[] + highest_severity
m-sec-h Missing security header (HSTS, X-Frame-Options, etc.) Sets missing_sec_headers = true
info Version disclosure, fingerprinting Stored in findings only

The m-sec-h flag is stored separately so missing headers never inflate the CVE-based severity rating of a host. A server with no CVEs but missing HSTS shows severity=null, missing_sec_headers=true — not severity=medium.

Change detection

On rescan, if a host's headers, CVEs or severity changed since the last scan, a ScanChange row is written with old and new snapshots. This lets you track when a server gets patched, changes software, or becomes newly vulnerable.


CVE Signatures (sample)

ID CVE Severity Trigger
apache-path-traversal-rce CVE-2021-41773, CVE-2021-42013 Critical Server: Apache/2.4.49
apache-log4shell-exposure CVE-2021-44228 Critical Any Apache server
php-eol-5x CVE-2019-11043 Critical X-Powered-By: PHP/5.*
laravel-debug-exposed CVE-2021-3129 Critical X-Powered-By: Laravel
springboot-actuator CVE-2022-22965 Critical X-Application-Context
tomcat-ghostcat CVE-2020-1938 Critical Server: Apache-Coyote
cors-wildcard High Access-Control-Allow-Origin: *
missing-hsts m-sec-h Strict-Transport-Security absent
missing-xframe-options m-sec-h X-Frame-Options absent

Interesting Findings From Real Scans

Scanning GCP and AWS IP ranges surfaces several recurring patterns that are valuable from a security research perspective:

Exposed internal systems Staging APIs, internal dashboards, and enterprise tools (CRMs, ticketing systems, VPN portals) accessible directly from the public internet without authentication walls. These represent misconfigured cloud deployments where 0.0.0.0/0 firewall rules were left open.

Ghost servers / subdomain takeover candidates Servers still running and accepting connections, but whose domains have expired or been decommissioned. The SSL certificate references a domain that no longer resolves to that IP, creating potential subdomain takeover opportunities.

Default installation pages Apache2 Ubuntu Default Page: It works, Welcome to nginx!, This is the default server vhost — fresh deployments where the application was never properly installed or the vhost configuration was removed while the server kept running.

End-of-life software stacks PHP 5.x, Apache 2.4.49, outdated nginx versions — software that stopped receiving security patches years ago, still actively serving traffic on cloud infrastructure.

Note: All scanning was conducted on public IP ranges for research purposes. No systems were exploited or accessed beyond reading publicly served HTTP responses.


Setup

Prerequisites

  • Python 3.9+
  • PostgreSQL 13+
  • masscan

1. Clone and install

git clone https://github.com/kilma98/vulnerability-scanner
cd vulnerability-scanner
pip install -r requirements.txt

2. Create the database

psql -U postgres -c "CREATE DATABASE scanner;"

3. Start the backend

cd backend
uvicorn main:app --host 0.0.0.0 --port 8000 --reload

Tables are created automatically on first startup.

4. Run the scanner

cd scanner
python scannerfinal.py

The scanner checks the backend is reachable before starting. Results appear in the dashboard in real time at http://localhost:8000.

Configuration

Override the database URL via environment variable:

export DATABASE_URL="postgresql+asyncpg://user:password@host:5432/scanner"

Key scanner parameters (in scannerfinal.py):

SSLChecker(
    masscan_rate=10000,    # packets/sec
    chunkSize=2000,        # IPs per batch
    semaphore_limit=70,    # max concurrent connections
    timeout=3,             # seconds per request
)

API Endpoints

Method Path Description
POST /insert Ingest scanner results (bulk insert with inline CVE detection)
GET /api/scans Paginated scan list — filter by IP, domain, CVE, severity, port
GET /api/findings CVE findings with false-positive management
GET /api/findings/stats Severity breakdown, top vulnerable IPs, top CVEs
GET /api/detail/{ip} Full detail for one IP including headers and body
GET /api/changes/{ip} Rescan change history for one IP
GET /api/stats Aggregate stats — total scans, unique IPs, CVE host count
GET /api/export Download all results as CSV
POST /api/detect Run full CVE detection pass (writes findings table)
GET / Live dashboard
GET /docs Swagger UI

Stack

Layer Technology
Scanner Python 3.9, aiohttp, asyncio, BeautifulSoup, pyOpenSSL
Backend FastAPI, SQLAlchemy 2.0 (async), asyncpg
Database PostgreSQL 13+
Port scanning masscan

Roadmap

  • Bug bounty mode — subdomain enumeration via crt.sh + DNS bruteforce
  • ASN lookup integration — get all IP ranges for a target company
  • Exposed paths scanner (/.env, /.git/config, /actuator/env)
  • PDF report generator for bug bounty submissions
  • Port expansion — Redis (6379), Elasticsearch (9200), MongoDB (27017)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages