Evidence-first, credentialed Windows and network security posture assessment.
PostureKit reads a fixed set of security-relevant facts from authorized Windows hosts, records their hashes for later integrity checks, and evaluates them against a transparent rule set. It also folds in adjacent planes (patch state, wireless configuration, and network vulnerability scans) through importers. It identifies and reports; it does not exploit, and it never assigns severity on its own.
If you know HardeningKitty or PingCastle, PostureKit covers similar Windows and Active Directory security-configuration ground, for blue teams and assessors, with a hashed evidence trail behind every result and severity left to the analyst.
Read the full specification. Part VII of the companion Network Security Assessment Handbook explains every part of this tool in plain words and in detail: the design philosophy, the 45 evidence sources, the 45 rules, the patch engine, deployment adapters, evidence return and the validation status. Part V covers the wireless layers it implements. The handbook is free to read online or as a PDF.
Run python examples/offline_demo.py for a synthetic Pass / Fail / Unknown example using the real analyzer. It produces an HTML report and verifies its hashes; no host or network is contacted. View the worked demonstration.
Typeset from a verified run of the suite and the demonstration. Project page: abdullahzarshaid.github.io/posturekit.
Most host checks are either an opaque scanner you have to trust, or a pile of one-off scripts with no evidence trail. PostureKit is deliberately the opposite:
- Deterministic, no black box. Every result comes from a named check against a value the tool read from the host. There is no machine-learning guess in the evidence path.
- Integrity checks. Changed files fail verification against the retained SHA-256 manifest, and the analyzer refuses a batch whose ledger and evidence hashes disagree. Keep a trusted copy separately: hashes do not authenticate a manifest replaced alongside the evidence.
- Honest by design. A check that cannot be completed is recorded as inconclusive, never as secure. Severity is always left to an analyst. The tool distinguishes what was observed from what is inferred.
- No paid dependencies. Patch data comes from Microsoft's free feed and the CISA known-exploited list; network scanning uses the free Greenbone/OpenVAS. No commercial scanner licence is required.
| Plane | What it assesses |
|---|---|
| Windows host configuration | Firewall, SMB, RDP, UAC, LSA and credential-protection settings, listening services and connections, installed software and updates, account and audit policy, and more (45 evidence sources, 45 rules). |
| Active Directory | Domain policy, privileged groups (with SIDs and members), trusts, Kerberos ticket policy read from SYSVOL, applied GPOs and directory identity. Read from the domain controller; a member host reached through a remote session records the domain-level sources as not applicable, with the reason. |
| Wireless | Host-side 802.11 configuration (saved networks, encryption, cipher, auto-join, 802.1X server-certificate validation, PMF, pre-shared-key exposure), plus importers for over-the-air captures and wireless-controller configuration. |
| Patch state | Missing Microsoft updates with vendor CVSS scores and CISA known-exploited flags, from an offline catalog and Microsoft's free feed. |
| Network | Reachability and segmentation checks between vantage points (with liveness corroboration), and import of Greenbone/OpenVAS vulnerability reports. |
- Collect:
Code/Run.ps1launchesCode/Collect.ps1against a host named in your scope, locally or over WinRM. It reads a fixed set of facts read-only and writes them as a sealed, hashed evidence batch. - Seal and verify: each batch carries a
Manifest.txtof SHA-256 hashes.Code/VerifyManifest.pyconfirms nothing changed. - Analyze:
Code/Analyze.pyevaluates one or more batches againstCode/Rules.jsonand writes a normalized evidence set (Evidence.json,Tests.csv,Summary.html). Importers inExtensions/add the other planes.Extensions/ToFindings.pyverifies the analyzer output folder's manifest before it reads anything; a folder that fails the check yields a register with no findings, statusInputRejectedand exit code 2.
Every result carries the control it relates to (NIST SP 800-53 references), the evidence pointer and its hash, the method, and the outcome.
Windows 10, Windows 11, Server 2016, Server 2019 and Server 2022 (member and domain controller) in a six-machine virtual lab, including central collection over WinRM with Kerberos from one admin host to four servers in a single run, a live Greenbone Community Edition scan of the server segment imported and analyzed, a TP-Link Omada software controller's WLAN configuration reviewed through the controller importer, and a German-language Windows 11 client. The items that still need equipment or a real environment rather than code: over-the-air wireless capture, a real client controller export, and two-vantage segmentation across real network segments. See CHANGELOG.md for what the lab found and what changed.
- Windows PowerShell 5.1 on the machine you collect from (the collector is PowerShell).
- Python 3.10+ on the machine you analyze from (standard library only, no third-party packages).
git clone https://github.com/abdullahzarshaid/posturekit.git
cd posturekit
python Code/Tests.py
python -m unittest discover -s tests -vPrefer a fixed version? Download the zip attached to the latest release; its SHA-256 is printed in the release notes.
These tests use synthetic fixtures and do not contact hosts. Actual collection below requires a reviewed scope file and authorization; use an asset identifier declared in that scope.
# 1. Describe the target(s) in a scope file (see Code/ScopeWorkgroup.example.json; the three
# Code/ScopeU1*.example.json files show a central domain run, a workgroup host and a
# non-English host under one engagement with a corporate SSID list).
# 2. Collect locally on the host:
powershell -ExecutionPolicy Bypass -File Code\Run.ps1 -ScopePath scope.json -Mode Local -AssetId HOST01 -AuthorizedLabRun# 3. Analyze the sealed batch (off the host):
python Code/Analyze.py --batch Evidence/Raw/<batch-id> --output Reports/HOST01
# Several batches of the same engagement in one report (for example a central run plus one host collected locally):
python Code/Analyze.py --batch Evidence/Raw/<central-batch> --batch Evidence/Raw/<local-batch> --output Reports/All
# Optional: fold in other planes
python Code/Analyze.py --batch Evidence/Raw/<batch-id> \
--greenbone gvm.json --wireless-controller controller.json --output Reports/HOST01Verify a batch at any time:
python Code/VerifyManifest.py Evidence/Raw/<batch-id>Determine outstanding Microsoft updates for a batch (one internet fetch, then it works offline):
python Extensions/PatchCheck.py --batch Evidence/Raw/<batch-id> --output Reports/HOST01-Patch --months 60Code/ collector (Run.ps1, Collect.ps1, Common.ps1), analyzer (Analyze.py), evidence gate,
rule set (Rules.json), network tester, scope examples, manifest verifier, derived-folder
sealer, Python test suite and PowerShell fixture suite
Extensions/ importers and their runbooks: patch, wireless, network scan, software, findings draft
Templates/ blank intake templates for an engagement, including the review dispositions sheet
docs/ architecture diagram
The analyzer takes external inputs the same way for every plane: an importer normalizes a tool's output
into an evidence document, and Analyze.py folds it in through a flag (--greenbone, --wireless-air,
--wireless-controller, --nmap, --hardeningkitty, --cim). The existing importers in Extensions/
are the pattern to copy for a new one.
- It does not exploit, pivot, or prove exploitability. It identifies and evidences configuration and patch weaknesses.
- It does not discover hosts. It only touches machines named in the scope.
- A network scanner detects exposure, not confirmed exploitability, so scan results are treated as candidates an analyst confirms.
python Code/Tests.pyThe Python suite (225 tests) runs on synthetic data only: no PowerShell is executed and no host is contacted.
powershell -NoProfile -ExecutionPolicy Bypass -File Code\CollectorHelperTests.ps1The PowerShell fixture suite (97 checks) loads the pure wireless helpers out of Collect.ps1 and runs them
against fixture text. It needs Windows PowerShell 5.1 but no wireless adapter, no netsh call and no key.
Both suites, the manifest tests and the offline demonstration run on GitHub Actions for every push and pull request, on Linux and Windows with Python 3.10 and 3.12 (.github/workflows/tests.yml).
Issues and pull requests are welcome: new rule packs, additional importers, and coverage for more Windows versions are all good first contributions. Open an issue to discuss anything larger.
If PostureKit is useful to you, a star helps others find it.
Use the Cite this repository button on GitHub, or the entry in CITATION.cff. The release tag is the version to cite.
Released under the MIT License.

