Skip to main content

Open-source Windows image security analyzer suite (17 analyzers)

Project description

Rectify

rectify-oss

Audit Windows golden images before they ship to your fleet.

The open-source Windows image security analyzer suite. 17 production analyzers, mounted any Windows disk format, JSON output, designed for CI.

License: Apache 2.0 Python 3.11+ Status: stable Platform: Linux

Find it. Expose it. Rectify it.

Install · Quick start · Analyzers · CI integration · Contributing


What it does

rectify-oss is a Linux-based static security analyzer for mounted Windows disk images. Point it at the root of a mounted WIM, VHD, VHDX, VMDK, AMI, or Azure managed disk — it produces a structured JSON report of security findings.

It is designed to gate Windows golden images in CI before they ship to your fleet, but you can also run it ad-hoc on any image you have on disk.

                          BUILD                    DEPLOY                    RUNTIME
                            │                        │                          │
  Build pipelines  ──►  [ rectify-oss ]  ──►  (deployment)  ──►  [ EDR / vuln scanners / SIEM ]
                            │                                                   │
                  Catches issues here                  They catch issues here (after the bad image is on every endpoint)

If you've ever shipped a Windows image and later discovered it had:

  • Memory.dmp left in C:\ with cleartext credentials in it
  • A PSReadLine_history.txt in C:\Users\Default that every new profile inherits
  • TLS 1.0 still enabled in the Schannel registry
  • An RDP listener with NLA disabled
  • A WSUS pointing to an old HTTP URL
  • 50,000 endpoints inheriting one bad audit policy

rectify-oss catches that at build time.


Install

From source (recommended for now)

git clone https://codeberg.org/rectify-security/rectify-oss.git
cd rectify-oss/analyzers
pip install -e ".[dev]"

From PyPI

Rectify on PyPI

Ubuntu via PPA

Rectify on Launchpad

Requires Python 3.11 or later. Linux only (uses dissect and libguestfs).


Quick start

# 1. Mount your Windows image read-only via libguestfs
sudo guestmount -a windows-image.vhdx -i --ro /mnt/image

# 2. Run the analyzer suite
rectify-oss /mnt/image my-scan-001 win11-corp-gold --output-file report.json

# 3. Read the findings
jq '.analyzer_results[].findings[] | select(.severity == "high" or .severity == "critical")' report.json

# 4. Clean up
sudo guestunmount /mnt/image

That's the entire workflow. JSON in, structured findings out. No agents, no infrastructure, no licence server.


Example output

A single finding looks like this:

{
  "id": "ART-002:Memory.dmp",
  "analyzer": "artifact_leakage",
  "severity": "critical",
  "title": "Kernel memory dump left in image",
  "description": "Memory.dmp found at C:\\Memory.dmp (4.2 GB). Kernel dumps may contain cleartext credentials, BitLocker keys, and other sensitive material.",
  "evidence": {
    "path": "C:\\Memory.dmp",
    "size_bytes": 4505812992
  },
  "remediation": "Delete C:\\Memory.dmp before sealing the image. Disable automatic memory dump creation via System Properties > Advanced > Startup and Recovery > Settings.",
  "references": [
    "https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-system"
  ]
}

Every finding is Pydantic-validated against a stable schema (see schema.py).

See examples/sample-report.json for a complete real scan report.


What's included

17 production analyzers across two tiers.

Foundation v1 — 8 analyzers

Analyzer Checks
installed_software Inventory from registry uninstall keys (CVE-matchable)
patch_level KB rollup currency vs known security patches
defender_posture Microsoft Defender state, AMSI, real-time protection
persistence_surface Run/RunOnce, Services, Image File Execution Options, AppInit
secret_scanning Cleartext credentials in image artifacts
account_hygiene Local users, password-never-expires, last-login flags
smb_config SMBv1, signing, anonymous access, null sessions
driver_analysis Vulnerable drivers (LOLDriver project), unsigned kernel modules

Tier 1 — Hardening baseline — 9 analyzers

Analyzer Checks
firewall_posture Windows Firewall profile state, allow-rules audit
audit_policy Advanced audit policy subcategory coverage
powershell_hardening Constrained Language Mode, ScriptBlock logging, Module logging
wsus_config WSUS server URL, HTTPS-only, TLS posture
ntp_config Time source, drift bounds, NT5DS vs NTP
rdp_config NLA, MinEncryptionLevel, idle timeout, listener state
lsa_protection LSASS RunAsPPL, Credential Guard, WDAC integration
tls_schannel Schannel ciphers/protocols (TLS 1.0/1.1 disabled)
schannel_apps Application-side TLS configuration in registry

CI/CD integration

The most valuable use of rectify-oss is gating image builds in CI. Here's a typical pattern for Forgejo Actions:

# .forgejo/workflows/image-audit.yml
name: Audit golden image
on:
  push:
    paths: ['images/**']
jobs:
  audit:
    runs-on: docker
    steps:
      - uses: actions/checkout@v4
      - run: sudo apt install -y libguestfs-tools python3-pip
      - run: pip install -e ./rectify-oss/analyzers
      - name: Mount image
        run: |
          sudo mkdir -p /mnt/image
          sudo guestmount -a images/win11-corp.vhdx -i --ro /mnt/image
      - name: Run audit
        run: rectify-oss /mnt/image $FORGEJO_SHA win11-corp --output-file findings.json
      - name: Fail on high/critical findings
        run: |
          python -c "
          import json, sys
          report = json.load(open('findings.json'))
          findings = [f for r in report['analyzer_results'] for f in r['findings']]
          critical = [f for f in findings if f['severity'] in ('high', 'critical')]
          if critical:
              for f in critical: print(f\"[{f['severity'].upper()}] {f['id']}: {f['title']}\")
              sys.exit(1)
          "
      - run: sudo guestunmount /mnt/image
        if: always()

The same pattern works with GitLab CI, Jenkins, Drone, or any CI system that can run Bash.


Architecture

The framework is small and the contract is stable:

┌─────────────────────────────────────────────────────────┐
│  rectify-oss CLI                                        │
│   └─ runner.py                                          │
│        ├─ Loads 17 analyzers                            │
│        ├─ Runs each in crash isolation                  │
│        └─ Serializes ScanReport JSON                    │
├─────────────────────────────────────────────────────────┤
│  Plugin framework (analyzers/base.py)                   │
│   └─ class Analyzer:                                    │
│         name: str                                       │
│         version: str                                    │
│         def run(mount_root: Path) -> list[Finding]:     │
├─────────────────────────────────────────────────────────┤
│  Schema (analyzers/schema.py)                           │
│   └─ Finding, ScanReport — Pydantic-validated           │
└─────────────────────────────────────────────────────────┘

Each analyzer mounts the Windows image read-only, inspects registry hives via regipy or dissect.target, and produces validated Finding objects. The framework handles crash isolation — one analyzer's failure never breaks the scan.

See docs/analyzer-development.md for the plugin contract.


Writing your own analyzers

from pathlib import Path
from winaudit_analyzers.base import Analyzer
from winaudit_analyzers.schema import Finding, Severity

class MyAnalyzer(Analyzer):
    name = "my_analyzer"
    version = "0.1.0"

    def run(self, mount_root: Path) -> list[Finding]:
        findings = []
        # Inspect mount_root, parse what you need
        # Return Pydantic-validated Finding objects
        return findings

Drop the file in winaudit_analyzers/plugins/ and add an import + entry to runner.py. The framework handles crash isolation, schema validation, and stable finding IDs.


What this is NOT

  • ❌ Not an EDR. Rectify analyzes images, not running endpoints.
  • ❌ Not a runtime BAS tool. Rectify is image-time, not attack simulation.
  • ❌ Not a Linux image scanner. Rectify v1 is Windows-only.
  • ❌ Not a vulnerability-scanner replacement. Use Tenable/Qualys for the running fleet; use Rectify to gate the build.

About the commercial product

rectify-oss is the open-core layer of a larger Rectify product that is currently under active development. The commercial product will add additional analyzers (Tier 2 / Tier 3 / Tier 4), a platform UI with multi-tenancy, curated rule data, and managed deployment options.

It is not yet available for purchase. The open-source distribution stands on its own — install it, run it, contribute to it. The commercial product will be announced separately when it is ready for design partners.

If you're interested in early access as the commercial product develops, open a discussion on this repo and we'll follow up directly.


Contributing

Pull requests welcome. See CONTRIBUTING.md.

Before opening a PR:

  1. Sign the CLA — instructions in CONTRIBUTING.md
  2. Run pytest from analyzers/
  3. Run ruff check . && mypy src
  4. Open the PR with a clear description of what changed and how you tested it

Security reports go to a different place — see SECURITY.md.

We will not relicense to anything more restrictive than Apache 2.0 without 12 months' public notice.


Project status

Metric Status
Analyzers registered 17/17
Schema tests 7/7 passing
Stable API since v1.0.1
Distribution source on Codeberg; PyPI and Ubuntu PPA coming soon
Issue tracker Codeberg Issues

License

Apache License 2.0 — see LICENSE.

Copyright © 2026 Rectify.

The name "Rectify" is a trademark of the project entity. Apache 2.0 does not grant trademark permission. Forks are welcome to use any name except "Rectify" — this protects users from version confusion.

See NOTICE for required Apache 2.0 attribution.


Find it. Expose it. Rectify it.

Issues · Contributing · Security · 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

rectify_oss-1.0.1.post2.tar.gz (53.4 kB view details)

Uploaded Source

Built Distribution

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

rectify_oss-1.0.1.post2-py3-none-any.whl (61.1 kB view details)

Uploaded Python 3

File details

Details for the file rectify_oss-1.0.1.post2.tar.gz.

File metadata

  • Download URL: rectify_oss-1.0.1.post2.tar.gz
  • Upload date:
  • Size: 53.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for rectify_oss-1.0.1.post2.tar.gz
Algorithm Hash digest
SHA256 7ba61216c38f0d98735f93a27841c1ff8c16c2f1c70d1efdc47e1bde5d804883
MD5 a3645df0029262518376734451253916
BLAKE2b-256 8d7ce51891148a66926449468aa6e8b2385817bbce5af23dd9965c3384072f8d

See more details on using hashes here.

File details

Details for the file rectify_oss-1.0.1.post2-py3-none-any.whl.

File metadata

File hashes

Hashes for rectify_oss-1.0.1.post2-py3-none-any.whl
Algorithm Hash digest
SHA256 5c16bb91131590e36fa98db41ef036a9958f21bdc728ecfc6c1a49e78b8cfc56
MD5 235025bffb850696be710695c6b016ee
BLAKE2b-256 f4b9156ba13be8892727a75871ade579d4c4aac04f6596b12e163998c3640b79

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