Skip to main content

CLI-first Windows security misconfiguration auditor with weighted scoring, threat-intel enrichment, and multi-format reporting.

Project description

๐Ÿ›ก๏ธ WinSecAudit v2

A CLI-first Windows Security Misconfiguration Auditor

Weighted scoring ยท Threat intelligence enrichment ยท Multi-format reporting ยท Drift detection

Python Platform License Checks Tests


โœจ Overview

WinSecAudit v2 audits Windows 10/11 machines for common security misconfigurations, assigns a weighted risk score, enriches every finding with live CVE threat intelligence, and produces boardroom-ready reports in four formats. It's built as a plugin system โ€” every check is a self-contained class auto-discovered at runtime, so extending the suite requires zero wiring.

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  39 CHECKS   โ”‚ โ”€โ”€โ–ถ โ”‚   SCORING    โ”‚ โ”€โ”€โ–ถ โ”‚  THREAT INTELโ”‚ โ”€โ”€โ–ถ โ”‚   REPORTS    โ”‚
โ”‚ (PowerShell) โ”‚     โ”‚  (weighted)  โ”‚     โ”‚ NVD+EPSS+KEV โ”‚     โ”‚ PDF/DOCX/CSV โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ“š Table of Contents


๐Ÿš€ Quick Start

# 1. Clone & install
git clone https://github.com/KavyaJain321/winsecaudit-v2.git
cd winsecaudit-v2
pip install -r requirements.txt

# 2. Run your first audit (open an elevated PowerShell first)
python winsecaudit.py scan

# 3. Export a beautiful PDF report
python winsecaudit.py report --format pdf

๐Ÿ’ก Tip: The SQLite database and all caches are created automatically on first run inside data/. No setup scripts, no migrations.


โš™๏ธ Installation

Requirements

Requirement Version
Python 3.11 or newer
OS Windows 10 / 11 (elevated shell for most checks)
Dependencies See requirements.txt

Setup

git clone https://github.com/KavyaJain321/winsecaudit-v2.git
cd winsecaudit-v2
pip install -r requirements.txt

Optional

# Set your NVD API key to bump rate limit from 5 โ†’ 50 req/s
$env:NVD_API_KEY = "your-key-here"     # PowerShell
export NVD_API_KEY="your-key-here"     # Bash

๐Ÿงฐ Commands

WinSecAudit ships with 6 Typer-powered commands. Run python winsecaudit.py --help to see them all.

scan โ€” Run the full audit

python winsecaudit.py scan [OPTIONS]
Option Default Description
--profile basic Profile name (basic or hardened)
--output terminal Output mode: terminal or json
--no-threat-intel off Skip NVD / EPSS / CISA KEV enrichment

report โ€” Generate a formatted report

python winsecaudit.py report [OPTIONS]
Option Default Description
--scan-id latest Specific scan ID to report on
--format terminal terminal, pdf, docx, or csv

list โ€” List saved scans

python winsecaudit.py list [--machine HOSTNAME] [--limit N]

drift โ€” Compare two scans

python winsecaudit.py drift [--scan-a ID] [--scan-b ID]

Defaults to comparing the two most recent scans. Under the hood, drift emulates a FULL OUTER JOIN with two LEFT JOINs + UNION ALL (SQLite doesn't support full outer joins natively).

fix โ€” List or apply remediations

python winsecaudit.py fix --list                      # show all remediable checks
python winsecaudit.py fix --check "Check Name"        # apply the fix

dashboard โ€” Launch the FastAPI read-only dashboard

python winsecaudit.py dashboard
# Opens http://localhost:8080

๐Ÿ” Security Checks

39 checks across 8 categories, all auto-discovered via CheckRegistry.discover():

Category # Sample Checks
๐Ÿ” Authentication 6 Password complexity, min length, account lockout, guest account, admin rename
๐Ÿšช Access Control 5 UAC level, admin shares, AutoRun, WSH, PowerShell execution policy
๐ŸŒ Network 6 SMBv1 disabled, LLMNR, NetBIOS, WPAD, RDP NLA, NTLMv1
โš™๏ธ Services 5 Print Spooler, Telnet, SNMP, FTP, WinRM
๐Ÿงฌ Kernel 4 Secure Boot, DEP, ASLR, Kernel DMA Protection, VBS/HVCI
๐Ÿ–ฅ๏ธ System 5 BitLocker, Defender, Firewall, Windows Update, Secure Boot
๐Ÿ“ Logging 4 Audit policy, PowerShell module logging, script-block logging, Sysmon
๐Ÿ”‘ Credentials 4 Credential Guard, LAPS, WDigest disabled, cached logons

Each check emits an immutable CheckResult with CVE IDs, MITRE ATT&CK technique, CIS benchmark ID, severity, weight, and a ready-to-run remediation command.


๐ŸŽ›๏ธ Profiles

Profiles live in profiles/*.yaml and control three levers:

Key Effect
relaxed_checks Named checks whose FAIL is flipped to PASS (with a note). Use for controls intentionally disabled on a machine class.
weight_overrides Override the default weight of any check by name.
required_checks (Reserved) Checks that must pass for the scan to succeed.

Bundled Profiles

Profile Target Relaxations
basic Workstations, developer machines BitLocker, Secure Boot, NTLMv1, PS exec policy, Kernel DMA
hardened Servers, high-security workstations None โ€” all checks enforced with higher weights on crypto/creds

๐Ÿ“Š Scoring & Grading

score = (earned_weight / max_possible_weight) ร— 100
Status Contribution
โœ… PASS earns full check weight
โŒ FAIL / ERROR earns 0
โญ๏ธ SKIPPED excluded from numerator and denominator

Edge case: if every check is skipped โ†’ score = 100.0

Grade Bands

Grade Score Range Meaning
๐ŸŸข A โ‰ฅ 90 Excellent โ€” hardened baseline met
๐ŸŸข B โ‰ฅ 75 Good โ€” minor gaps
๐ŸŸก C โ‰ฅ 60 Acceptable โ€” remediation recommended
๐ŸŸ  D โ‰ฅ 40 Poor โ€” significant exposure
๐Ÿ”ด F < 40 Critical โ€” immediate action required

๐ŸŒ Threat Intelligence

Every CVE associated with a failed check is enriched from three sources:

Source Data Rate Limit Cache TTL
NIST NVD CVSS score, severity, description 5/s anon ยท 50/s with key 7 days
FIRST EPSS Exploitation probability (0.0โ€“1.0) None documented 7 days
CISA KEV Known-exploited flag + ransomware use Bulk download 24 hours

Caches live in data/cve_map.json and data/cisa_kev_cache.json. Enrichment degrades gracefully โ€” a 429 from NVD does not crash the scan; affected CVEs simply ship without TI metadata.


๐Ÿ“„ Output Formats

Format File Highlights
๐Ÿ–ฅ๏ธ Terminal (stdout) Rich-rendered tables ยท ANSI colour ยท live progress
๐Ÿ“• PDF output/<scan_id>.pdf Cover page ยท executive summary ยท category breakdown ยท failure deep-dive ยท "Page N of M" footer
๐Ÿ“˜ DOCX output/<scan_id>.docx Word-native styles ยท FAIL rows bold + italic
๐Ÿ“— CSV output/<scan_id>.csv UTF-8 BOM ยท scan metadata denormalised per row (SIEM-friendly)

๐Ÿงช Testing

python tests/smoke_test.py

10 standalone tests cover: imports, check discovery, profile loading, scoring math, grade thresholds, DB round-trip, profile relaxation, TI offline cache, CLI entry point, and the full pipeline. No pytest required โ€” exits 0 on success.

WinSecAudit v2 โ€” Smoke Tests
========================================
  PASS  01 Import health
  PASS  02 Check discovery
  PASS  03 Profile loading
  PASS  04 Scoring correctness
  PASS  05 Grade thresholds
  PASS  06 DB round-trip
  PASS  07 Profile relaxation
  PASS  08 TI cache offline-safe
  PASS  09 CLI entry point
  PASS  10 Full pipeline
========================================
Results: 10/10 passed

โš ๏ธ Known Limitations

  • ๐Ÿ”’ Elevation required โ€” Most PowerShell checks call secedit, auditpol, or protected registry paths. Run from an elevated terminal.
  • ๐ŸชŸ Windows-only checks โ€” All checks are PowerShell/Windows-specific. The DB, scoring engine, and exporters are cross-platform.
  • ๐Ÿ“‰ NVD rate limit โ€” Without an API key, NVD allows 5 req/s. Set NVD_API_KEY to raise this to 50 req/s.
  • ๐Ÿ“ฅ CISA KEV download โ€” First scan of the day downloads ~5 MB from cisa.gov. Subsequent scans within 24 h use the cache.

๐Ÿ“‚ Project Structure

winsecaudit-v2/
โ”œโ”€โ”€ winsecaudit.py          # Entry point โ€” forces UTF-8 stdout/stderr on Windows
โ”œโ”€โ”€ requirements.txt
โ”‚
โ”œโ”€โ”€ checks/                 # ๐Ÿ” Security check plugins (auto-discovered)
โ”‚   โ”œโ”€โ”€ base.py             #    BaseCheck, CheckResult, CheckRegistry
โ”‚   โ”œโ”€โ”€ auth/               #    Authentication (6)
โ”‚   โ”œโ”€โ”€ access/             #    Access control (5)
โ”‚   โ”œโ”€โ”€ network/            #    Network (6)
โ”‚   โ”œโ”€โ”€ services/           #    Services (5)
โ”‚   โ”œโ”€โ”€ kernel/             #    Kernel/hardware (4)
โ”‚   โ”œโ”€โ”€ system/             #    System config (5)
โ”‚   โ”œโ”€โ”€ logging/            #    Audit & logging (4)
โ”‚   โ””โ”€โ”€ credentials/        #    Credential protection (4)
โ”‚
โ”œโ”€โ”€ engine/                 # โš™๏ธ Core orchestration
โ”‚   โ”œโ”€โ”€ runner.py           #    Parallel check execution
โ”‚   โ”œโ”€โ”€ scorer.py           #    Weighted scoring
โ”‚   โ”œโ”€โ”€ comparator.py       #    Profile loading & adjustment
โ”‚   โ”œโ”€โ”€ risk.py             #    Grade assignment & priority
โ”‚   โ””โ”€โ”€ threat_intel.py     #    NVD / EPSS / CISA KEV pipeline
โ”‚
โ”œโ”€โ”€ db/                     # ๐Ÿ’พ Persistence
โ”‚   โ”œโ”€โ”€ database.py         #    SQLAlchemy Core layer
โ”‚   โ””โ”€โ”€ schema.sql          #    Reference DDL
โ”‚
โ”œโ”€โ”€ cli/                    # ๐Ÿงฐ CLI surface
โ”‚   โ”œโ”€โ”€ main.py             #    Typer commands
โ”‚   โ””โ”€โ”€ output.py           #    Rich rendering
โ”‚
โ”œโ”€โ”€ dashboard/              # ๐ŸŒ FastAPI read-only dashboard
โ”‚   โ”œโ”€โ”€ app.py
โ”‚   โ”œโ”€โ”€ models.py
โ”‚   โ””โ”€โ”€ static/index.html
โ”‚
โ”œโ”€โ”€ exporters/              # ๐Ÿ“„ Report generators
โ”‚   โ”œโ”€โ”€ pdf.py              #    reportlab Platypus
โ”‚   โ”œโ”€โ”€ docx_export.py      #    python-docx
โ”‚   โ””โ”€โ”€ csv_export.py       #    csv module
โ”‚
โ”œโ”€โ”€ profiles/               # ๐ŸŽ›๏ธ YAML profiles
โ”‚   โ”œโ”€โ”€ basic.yaml
โ”‚   โ””โ”€โ”€ hardened.yaml
โ”‚
โ”œโ”€โ”€ data/                   # ๐Ÿ—ƒ๏ธ Runtime data (gitignored)
โ””โ”€โ”€ tests/
    โ””โ”€โ”€ smoke_test.py       # โœ… 10 standalone smoke tests

๐Ÿค Contributing

Adding a new check is a three-step affair:

  1. Create a file under the appropriate checks/<category>/ directory.
  2. Subclass BaseCheck and set the class attributes (name, category, weight, severity, cve_ids, mitre_technique, cis_id, remediation_cmd, remediation_supported).
  3. Implement run() -> CheckResult. That's it โ€” CheckRegistry.discover() picks it up on the next scan.
from checks.base import BaseCheck, CheckResult, CheckStatus, Severity, run_powershell

class MyNewCheck(BaseCheck):
    name = "My New Check"
    category = "System"
    weight = 5
    severity = Severity.HIGH
    remediation_cmd = "Set-ItemProperty ..."
    remediation_supported = True

    def run(self) -> CheckResult:
        value = run_powershell("Get-Something")
        return CheckResult(
            check_name=self.name,
            category=self.category,
            status=CheckStatus.PASS if value == "expected" else CheckStatus.FAIL,
            system_value=value,
            expected_value="expected",
            severity=self.severity,
            weight=self.weight,
            cve_ids=(),
            mitre_technique="",
            cis_id="",
            remediation_cmd=self.remediation_cmd,
            remediation_supported=self.remediation_supported,
        )

Built with โค๏ธ for defenders.

Report Bug ยท Request Feature ยท View Changelog

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

winsecaudit-1.1.1.tar.gz (165.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

winsecaudit-1.1.1-py3-none-any.whl (208.2 kB view details)

Uploaded Python 3

File details

Details for the file winsecaudit-1.1.1.tar.gz.

File metadata

  • Download URL: winsecaudit-1.1.1.tar.gz
  • Upload date:
  • Size: 165.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for winsecaudit-1.1.1.tar.gz
Algorithm Hash digest
SHA256 58c422327bc1d0ec38795def1a4f22f54662ce1ce51bda78ce1f2b1005218302
MD5 76556ff7a34c9b095a69398db290a097
BLAKE2b-256 e195771df154a51f7c4258f340475365ae25ff77d7f5e5b7d553085f3943792b

See more details on using hashes here.

File details

Details for the file winsecaudit-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: winsecaudit-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 208.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for winsecaudit-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7e5cc9dd7080dab57c7480aca17d7da6cbd0b002649f510aff003760c9ac87db
MD5 7e7fe5bf0c6926efe3ffafc456400903
BLAKE2b-256 e4eb2a98f311fe6cdc59aac88a1427106c2e1fa4e796a1b45b4b0cc88b9319e8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page