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.0.6.tar.gz (125.4 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.0.6-py3-none-any.whl (168.2 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for winsecaudit-1.0.6.tar.gz
Algorithm Hash digest
SHA256 e6b6f280405a97e586ec676df38312e82aabe1812a9940311d3380cc342792ad
MD5 a060ff7a2893fb7919f81dc8169bf454
BLAKE2b-256 f6d2767984ca7f3dd8d6b4d92f5b7b2abf5e191606180cdc2fb70401c0c50bd0

See more details on using hashes here.

File details

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

File metadata

  • Download URL: winsecaudit-1.0.6-py3-none-any.whl
  • Upload date:
  • Size: 168.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.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 fea49379be9cc734bf154584d465493a8b35c2dd35c744f1e7e230bb47b5352e
MD5 c7e1450d5c1ef41e7823810380a671c7
BLAKE2b-256 1576b30b30cf2608aa223551343a59f2e00a3da07cfbfa7937106c47383802e1

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