apotrope 0.1.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. apotrope-0.1.5/LICENSE +21 -0
  2. apotrope-0.1.5/PKG-INFO +392 -0
  3. apotrope-0.1.5/README.md +365 -0
  4. apotrope-0.1.5/pyproject.toml +51 -0
  5. apotrope-0.1.5/setup.cfg +4 -0
  6. apotrope-0.1.5/src/apotrope/__init__.py +4 -0
  7. apotrope-0.1.5/src/apotrope/__main__.py +6 -0
  8. apotrope-0.1.5/src/apotrope/checks/__init__.py +29 -0
  9. apotrope-0.1.5/src/apotrope/checks/accounts.py +305 -0
  10. apotrope-0.1.5/src/apotrope/checks/antivirus.py +177 -0
  11. apotrope-0.1.5/src/apotrope/checks/encryption.py +126 -0
  12. apotrope-0.1.5/src/apotrope/checks/firewall.py +118 -0
  13. apotrope-0.1.5/src/apotrope/checks/misc.py +417 -0
  14. apotrope-0.1.5/src/apotrope/checks/network.py +276 -0
  15. apotrope-0.1.5/src/apotrope/checks/os_info.py +344 -0
  16. apotrope-0.1.5/src/apotrope/checks/powershell.py +228 -0
  17. apotrope-0.1.5/src/apotrope/checks/rdp.py +180 -0
  18. apotrope-0.1.5/src/apotrope/checks/services.py +181 -0
  19. apotrope-0.1.5/src/apotrope/checks/smb.py +173 -0
  20. apotrope-0.1.5/src/apotrope/checks/startup.py +119 -0
  21. apotrope-0.1.5/src/apotrope/checks/uac.py +233 -0
  22. apotrope-0.1.5/src/apotrope/checks/updates.py +259 -0
  23. apotrope-0.1.5/src/apotrope/cis_map.py +213 -0
  24. apotrope-0.1.5/src/apotrope/cli.py +185 -0
  25. apotrope-0.1.5/src/apotrope/compare.py +184 -0
  26. apotrope-0.1.5/src/apotrope/exceptions.py +11 -0
  27. apotrope-0.1.5/src/apotrope/models.py +106 -0
  28. apotrope-0.1.5/src/apotrope/profile.py +154 -0
  29. apotrope-0.1.5/src/apotrope/reporter.py +751 -0
  30. apotrope-0.1.5/src/apotrope/scanner.py +281 -0
  31. apotrope-0.1.5/src/apotrope/scoring.py +134 -0
  32. apotrope-0.1.5/src/apotrope/templates/report.html.j2 +599 -0
  33. apotrope-0.1.5/src/apotrope/utils.py +267 -0
  34. apotrope-0.1.5/src/apotrope.egg-info/PKG-INFO +392 -0
  35. apotrope-0.1.5/src/apotrope.egg-info/SOURCES.txt +45 -0
  36. apotrope-0.1.5/src/apotrope.egg-info/dependency_links.txt +1 -0
  37. apotrope-0.1.5/src/apotrope.egg-info/entry_points.txt +2 -0
  38. apotrope-0.1.5/src/apotrope.egg-info/requires.txt +7 -0
  39. apotrope-0.1.5/src/apotrope.egg-info/top_level.txt +1 -0
  40. apotrope-0.1.5/tests/test_cli.py +282 -0
  41. apotrope-0.1.5/tests/test_compare.py +196 -0
  42. apotrope-0.1.5/tests/test_profile.py +130 -0
  43. apotrope-0.1.5/tests/test_reporter.py +285 -0
  44. apotrope-0.1.5/tests/test_scanner.py +238 -0
  45. apotrope-0.1.5/tests/test_scenarios.py +351 -0
  46. apotrope-0.1.5/tests/test_scoring.py +225 -0
  47. apotrope-0.1.5/tests/test_utils.py +392 -0
apotrope-0.1.5/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Apotrope Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,392 @@
1
+ Metadata-Version: 2.4
2
+ Name: apotrope
3
+ Version: 0.1.5
4
+ Summary: A portable Windows security posture auditor
5
+ Author: Apotrope Contributors
6
+ License: MIT
7
+ Keywords: windows,security,audit,posture,hardening
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: System Administrators
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: Microsoft :: Windows
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Security
16
+ Classifier: Topic :: System :: Systems Administration
17
+ Requires-Python: >=3.12
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: rich>=13.7
21
+ Requires-Dist: jinja2>=3.1
22
+ Requires-Dist: psutil>=5.9
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=8.0; extra == "dev"
25
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
26
+ Dynamic: license-file
27
+
28
+ # Apotrope
29
+
30
+ **Portable Windows security posture auditor.** Runs entirely on the machine it's
31
+ auditing, talks to no network, and hands back a scored terminal report — or a
32
+ self-contained HTML report you can send to someone who wasn't in the room.
33
+
34
+ [![Tests](https://github.com/hexorcist404/apotrope/actions/workflows/test.yml/badge.svg)](https://github.com/hexorcist404/apotrope/actions/workflows/test.yml)
35
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue.svg)](https://www.python.org/)
36
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
37
+
38
+ ---
39
+
40
+ ## Why Apotrope?
41
+
42
+ An *apotrope* is a charm that wards off harm. This one audits Windows.
43
+
44
+ Most posture tools want something before they'll help you: a cloud account, a
45
+ license key, an agent to install, your data shipped off to a dashboard somewhere.
46
+ Apotrope wants none of it. It's a single executable. Drop it on a USB stick, run it
47
+ on any Windows machine, and you get a 0–100 score plus a list of exactly what's
48
+ wrong and how to fix it — in plain English, not bare control IDs.
49
+
50
+ Run it as Administrator for the full picture. It works without admin too; a handful
51
+ of checks (BitLocker, some policy reads) just come back limited.
52
+
53
+ ---
54
+
55
+ ## Quick Start — Standalone Executable
56
+
57
+ No Python required.
58
+
59
+ 1. Download `apotrope.exe` from the [Releases](https://github.com/hexorcist404/apotrope/releases) page
60
+ 2. Open **Command Prompt** or **PowerShell** as Administrator
61
+ (Right-click the Start button → *Terminal (Admin)* or search for *cmd* → *Run as administrator*)
62
+ 3. Navigate to the folder where you saved the file — for example, if it's in Downloads:
63
+
64
+ ```
65
+ cd %USERPROFILE%\Downloads
66
+ ```
67
+
68
+ 4. Run:
69
+
70
+ ```
71
+ apotrope.exe
72
+ ```
73
+
74
+ For a full HTML report:
75
+
76
+ ```
77
+ apotrope.exe --html report.html
78
+ ```
79
+
80
+ Then open `report.html` in your browser.
81
+
82
+ ---
83
+
84
+ ## Terminal Output
85
+
86
+ **Standard scan (default view):**
87
+
88
+ ![Apotrope scan overview](assets/screenshots/scan-overview.png)
89
+
90
+ **Verbose mode (`--verbose`) — full details and remediation steps for every check:**
91
+
92
+ ![Apotrope verbose output](assets/screenshots/scan-verbose.png)
93
+
94
+ **Top issues summary (shown at the end of every scan):**
95
+
96
+ ![Apotrope top issues](assets/screenshots/scan-top-issues.png)
97
+
98
+ ---
99
+
100
+ ## Installation via pip
101
+
102
+ Requires Python 3.12+ and Windows 10/11 or Server 2019/2022.
103
+
104
+ Install from source:
105
+
106
+ ```bash
107
+ git clone https://github.com/hexorcist404/apotrope.git
108
+ cd apotrope
109
+ pip install -e .
110
+ apotrope
111
+ ```
112
+
113
+ PyPI package coming soon.
114
+
115
+ ---
116
+
117
+ ## Authorized Use Notice
118
+
119
+ > **Apotrope is a READ-ONLY auditing tool.** It does not modify any system
120
+ > settings, write to the registry, or make network connections. All data stays
121
+ > on the machine being audited.
122
+ >
123
+ > **Only run Apotrope on systems you own or have explicit written authorization
124
+ > to audit.** Unauthorized use may violate computer fraud laws in your jurisdiction.
125
+
126
+ ### How Apotrope queries your system
127
+
128
+ Apotrope uses PowerShell subprocesses with `-ExecutionPolicy Bypass` to read system
129
+ configuration. This flag is required so the tool can run on machines with any execution
130
+ policy setting — including the default `Restricted` policy — without requiring you to
131
+ permanently change your policy. **No scripts are written to disk.** Each command is a
132
+ read-only query passed directly to the PowerShell process; the bypass applies only to
133
+ that subprocess and does not change the machine's policy setting.
134
+
135
+ ---
136
+
137
+ ## Usage
138
+
139
+ ```
140
+ apotrope [OPTIONS]
141
+
142
+ Options:
143
+ --html PATH Save a self-contained HTML report to PATH
144
+ --json PATH Save a JSON report to PATH
145
+ --baseline FILE Save current scan as a JSON baseline for future comparisons
146
+ --compare FILE Compare current scan against a saved baseline
147
+ --profile FILE Load a custom check profile from a TOML file
148
+ --category CATS Comma-separated list of categories to audit
149
+ (e.g. firewall,encryption,patching)
150
+ --dry-run List check modules that would run without executing them
151
+ --verbose Show detail for every check, including PASSes
152
+ --no-color Disable Rich color output (for CI / log files)
153
+ --log-level LEVEL Logging verbosity: DEBUG, INFO, WARNING (default), ERROR
154
+ --version Show version and exit
155
+ -h, --help Show this help message and exit
156
+
157
+ Exit codes:
158
+ 0 Score >= 70 (passing)
159
+ 1 Score < 70 (failing)
160
+ 2 Fatal scan error
161
+ ```
162
+
163
+ ### Examples
164
+
165
+ ```bash
166
+ # Full audit, terminal only
167
+ apotrope
168
+
169
+ # Save HTML report
170
+ apotrope --html report.html
171
+
172
+ # Save JSON for automation / SIEM integration
173
+ apotrope --json report.json
174
+
175
+ # Audit only firewall and patching
176
+ apotrope --category firewall,patching
177
+
178
+ # Show pass/fail details for every check
179
+ apotrope --verbose
180
+
181
+ # Silent mode for scripts (exits 0 if score>=70, 1 if score<70, 2 on error)
182
+ apotrope --no-color --log-level ERROR
183
+ echo Exit code: %ERRORLEVEL%
184
+
185
+ # Save a baseline, then compare on the next run
186
+ apotrope --baseline baseline.json
187
+ apotrope --compare baseline.json
188
+
189
+ # Apply a custom check profile (e.g. for MSP clients)
190
+ apotrope --profile myprofile.toml
191
+
192
+ # List which checks would run without executing anything
193
+ apotrope --dry-run
194
+ ```
195
+
196
+ ### Custom Profiles (`apotrope.toml`)
197
+
198
+ Create a `apotrope.toml` in your working directory (or pass `--profile FILE`)
199
+ to customise scan behaviour:
200
+
201
+ ```toml
202
+ [profile]
203
+ name = "MSP-Baseline"
204
+
205
+ [disabled_checks]
206
+ # Skip checks irrelevant to this environment
207
+ checks = [
208
+ "SMBv1 Disabled",
209
+ "Firewall — Public Default Inbound Action",
210
+ ]
211
+
212
+ [severity_overrides]
213
+ # Downgrade noisy low-risk checks
214
+ "Defender Tamper Protection" = "LOW"
215
+
216
+ [thresholds]
217
+ # Allow 45 days between updates before warning (default: 30)
218
+ max_update_age_warn = 45
219
+ max_update_age_fail = 90
220
+ ```
221
+
222
+ ---
223
+
224
+ ## Scoring System
225
+
226
+ Apotrope calculates a **0–100 security score** by starting at 100 and
227
+ deducting points for failed and warned checks, weighted by severity:
228
+
229
+ | Outcome | Severity | Deduction |
230
+ |---------|----------|-----------|
231
+ | FAIL | CRITICAL | -15 |
232
+ | FAIL | HIGH | -10 |
233
+ | FAIL | MEDIUM | -5 |
234
+ | FAIL | LOW | -2 |
235
+ | WARN | CRITICAL | -7 |
236
+ | WARN | HIGH | -5 |
237
+ | WARN | MEDIUM | -2 |
238
+ | WARN | LOW | -1 |
239
+
240
+ The score is clamped to [0, 100].
241
+
242
+ **Grade scale:**
243
+
244
+ | Score | Grade | Label |
245
+ |--------|-------|-----------|
246
+ | 90-100 | A | Excellent |
247
+ | 80-89 | B | Good |
248
+ | 70-79 | C | Fair |
249
+ | 60-69 | D | Poor |
250
+ | 0-59 | F | Critical |
251
+
252
+ INFO and ERROR results do not affect the score.
253
+
254
+ ---
255
+
256
+ ## CIS Benchmark Mapping
257
+
258
+ Where applicable, findings are mapped to CIS Microsoft Windows Benchmark control
259
+ IDs. These references appear as blue badges in the HTML report's detailed findings
260
+ section, making Apotrope useful for compliance documentation and audit
261
+ preparation. Mappings are based on the CIS Microsoft Windows 11 Enterprise
262
+ Benchmark v5.0.0 and CIS Microsoft Windows 10 Enterprise Benchmark v4.0.0.
263
+ The correct version is selected automatically based on the OS build number at
264
+ scan time.
265
+
266
+ > **Attribution:** CIS Benchmarks are the registered trademarks of the Center
267
+ > for Internet Security, Inc. Apotrope is an independent tool that references
268
+ > CIS Benchmark recommendations for informational purposes. This project is not
269
+ > affiliated with, endorsed by, or sponsored by CIS. To obtain the official CIS
270
+ > Benchmarks, visit [cisecurity.org](https://www.cisecurity.org).
271
+
272
+ ---
273
+
274
+ ## Checks Performed
275
+
276
+ | Category | Check | Description |
277
+ |----------------|----------------------------------------|------------------------------------------------------------------------------------|
278
+ | Access Control | UAC Admin Consent Behavior | Checks the UAC consent prompt behavior for administrator accounts |
279
+ | Access Control | UAC Enabled | Checks whether User Account Control (UAC) is enabled |
280
+ | Access Control | UAC Secure Desktop | Checks whether UAC prompts are shown on the isolated secure desktop |
281
+ | Access Control | UAC Standard User Behavior | Checks the UAC consent prompt behavior for standard user accounts |
282
+ | Accounts | Built-in Administrator Account | Checks whether the built-in Administrator account is enabled or renamed |
283
+ | Accounts | Guest Account | Checks whether the built-in Guest account is disabled |
284
+ | Accounts | Local Administrators | Counts members of the local Administrators group (warns if > 2) |
285
+ | Accounts | Password Policy — Account Lockout | Checks whether account lockout is configured to deter brute-force attacks |
286
+ | Accounts | Password Policy — Complexity | Checks whether password complexity requirements are enforced |
287
+ | Accounts | Password Policy — Minimum Length | Checks minimum password length (fail < 8 chars, warn < 12 chars) |
288
+ | Antivirus | Defender Real-Time Protection | Checks whether Windows Defender real-time protection is active |
289
+ | Antivirus | Defender Signature Age | Checks whether virus definitions are less than 7 days old |
290
+ | Antivirus | Defender Tamper Protection | Checks whether Tamper Protection prevents unauthorised Defender changes |
291
+ | Antivirus | Registered AV Products | Lists antivirus products registered with Windows Security Center |
292
+ | Encryption | BitLocker — {drive} * | BitLocker encryption and protection status per fixed drive (one result per drive) |
293
+ | File Sharing | SMB Encryption * | Checks whether SMB encryption (EncryptData) is enforced |
294
+ | File Sharing | SMB Signing Required * | Checks that SMB message signing is required (mitigates NTLM relay attacks) |
295
+ | File Sharing | SMBv1 Disabled * | Checks that SMBv1 is disabled (mitigates EternalBlue/WannaCry/NotPetya) |
296
+ | Firewall | Firewall — Domain Default Inbound Action | Checks that the Domain profile does not explicitly allow all inbound connections |
297
+ | Firewall | Firewall — Domain Profile Enabled | Checks whether Windows Firewall is enabled for domain networks |
298
+ | Firewall | Firewall — Private Default Inbound Action | Checks that the Private profile does not explicitly allow all inbound connections |
299
+ | Firewall | Firewall — Private Profile Enabled | Checks whether Windows Firewall is enabled for private networks |
300
+ | Firewall | Firewall — Public Default Inbound Action | Checks that the Public profile does not explicitly allow all inbound connections |
301
+ | Firewall | Firewall — Public Profile Enabled | Checks whether Windows Firewall is enabled for public networks |
302
+ | Hardening | Audit Policy | Checks that key subcategories (Logon, Lockout, etc.) log success/failure events |
303
+ | Hardening | AutoPlay Disabled | Checks whether AutoPlay is disabled for all drive types |
304
+ | Hardening | Screen Lock Timeout | Checks that the screen automatically locks within 15 minutes of inactivity |
305
+ | Hardening | Speculative Execution Mitigations | Checks whether Spectre/Meltdown mitigations have been explicitly disabled |
306
+ | Hardening | WinRM Status | Checks whether the Windows Remote Management (WinRM) service is running |
307
+ | Network | IPv6 Status | Reports whether IPv6 is active on any network adapter (informational) |
308
+ | Network | LLMNR Disabled | Checks whether LLMNR is disabled (susceptible to poisoning/Responder attacks) |
309
+ | Network | Listening Port — {port}/{service} | Flags known-dangerous listening ports: FTP (21), Telnet (23), TFTP (69), RDP (3389) |
310
+ | Network | Listening Ports — Summary | Enumerates all TCP ports currently in LISTEN state (informational) |
311
+ | Network | NetBIOS over TCP/IP | Checks whether NetBIOS over TCP/IP is disabled on all network adapters |
312
+ | Patching | Last Windows Update | Checks when the most recent update was installed (warn > 30 days, fail > 60 days) |
313
+ | Patching | Pending Windows Updates | Counts Windows Updates that are available but not yet installed |
314
+ | Patching | Windows Update Service | Checks whether the Windows Update (wuauserv) service is running |
315
+ | Persistence | Scheduled Tasks | Enumerates non-Microsoft scheduled tasks (potential persistence points) |
316
+ | Persistence | Startup Programs | Enumerates programs configured to run at startup (registry Run keys + folders) |
317
+ | PowerShell | PowerShell Constrained Language Mode | Checks whether PowerShell Constrained Language Mode is active |
318
+ | PowerShell | PowerShell Execution Policy | Checks the LocalMachine execution policy (warns on Unrestricted/Bypass) |
319
+ | PowerShell | PowerShell Module Logging | Checks whether PowerShell module pipeline logging is enabled |
320
+ | PowerShell | PowerShell Script Block Logging | Checks whether Script Block Logging is enabled (critical for forensics/IR) |
321
+ | PowerShell | PowerShell v2 | Checks whether PowerShell v2 is installed (downgrade attack vector) |
322
+ | Remote Access | RDP Enabled | Checks whether Remote Desktop Protocol is enabled |
323
+ | Remote Access | RDP Network Level Authentication † | Checks whether NLA is required for RDP connections |
324
+ | Remote Access | RDP Port † | Reports the RDP listening port (informational) |
325
+ | Services | Risky Services / Risky Service — {name} | Flags known-dangerous services if running: Remote Registry, Telnet, SNMP |
326
+ | Services | Unquoted Service Paths | Detects services with unquoted executable paths containing spaces (privilege-escalation vector) |
327
+ | System | Domain Membership | Reports whether the machine is domain-joined or in a workgroup (informational) |
328
+ | System | OS End-of-Support Status | Checks whether the installed Windows build is still supported by Microsoft |
329
+ | System | OS Version | Reports the installed Windows version and build number (informational) |
330
+ | System | Secure Boot | Checks whether UEFI Secure Boot is enabled |
331
+ | System | System Uptime | Checks system uptime (warns if > 30 days, suggesting pending patch reboots) |
332
+ | System | TPM Status | Checks whether a TPM chip is present and functional |
333
+
334
+ \* Requires **Administrator** privileges for full results.
335
+ † Only emitted when RDP is enabled.
336
+
337
+ ---
338
+
339
+ ## Building the Executable
340
+
341
+ Prerequisites: Python 3.12+, `pip install pyinstaller pillow`
342
+
343
+ ```bash
344
+ python build_exe.py
345
+ ```
346
+
347
+ The exe will be at `dist/apotrope.exe`. To build without the custom icon:
348
+
349
+ ```bash
350
+ python build_exe.py --no-icon
351
+ ```
352
+
353
+ ---
354
+
355
+ ## Contributing
356
+
357
+ 1. Fork the repo and create a branch: `git checkout -b feat/my-change`
358
+ 2. Make your changes — each check module is self-contained in `src/apotrope/checks/`
359
+ 3. Add or update tests in `tests/`
360
+ 4. Run `pytest tests/ -q` — all tests must pass
361
+ 5. Open a pull request into `main`
362
+
363
+ ### Adding a New Check Module
364
+
365
+ Create `src/apotrope/checks/mycheck.py` with:
366
+
367
+ ```python
368
+ from apotrope.models import CheckResult, Severity, Status
369
+
370
+ CATEGORY = "MyCategory"
371
+ # REQUIRES_ADMIN = True # uncomment if elevation is needed
372
+
373
+ def run() -> list[CheckResult]:
374
+ # ... query the system ...
375
+ return [CheckResult(
376
+ category=CATEGORY,
377
+ check_name="My Check Name",
378
+ status=Status.PASS, # PASS | FAIL | WARN | INFO | ERROR
379
+ severity=Severity.HIGH, # CRITICAL | HIGH | MEDIUM | LOW | INFO
380
+ description="What this check verifies.",
381
+ details="What was found.",
382
+ remediation="", # empty string for PASS
383
+ )]
384
+ ```
385
+
386
+ The scanner auto-discovers all modules in `checks/` — no registration needed.
387
+
388
+ ---
389
+
390
+ ## License
391
+
392
+ MIT — see [LICENSE](LICENSE).