Skip to content

v2.1.0

Latest

Choose a tag to compare

@uziii2208 uziii2208 released this 30 Aug 17:59
· 2 commits to master since this release

What's Changed

This release expands PwnRM from a post-exploitation shell into an elite operator platform — 5 new specialized attack modules, in-memory credential extraction bypassing EDR process creation telemetry, multi-vector coerced authentication, Server 2025 LAPS hunting, DACL privilege escalation analysis, polymorphic PowerShell AST obfuscation, hardened SOCKS5 multiplexing, 3 targeted security fixes, and a completely custom self-contained GitHub Actions CI/CD Security Audit Pipeline with zero third-party SAST dependencies.


New Modules — 5 Specialized Attack Capabilities


!vss — In-Memory VSS Shadow Copy Extractor [modules/vss.py]

Direct WMI / CIM reflection via [wmiclass]"Win32_ShadowCopy" to locate and copy active SAM, SYSTEM, and NTDS.dit credential hives from Volume Shadow Copies without invoking vssadmin.exe, ntdsutil.exe, or any other subprocess that generates EDR process creation telemetry. After extraction, the shadow copy is immediately deleted via .Delete() to eliminate forensic artifacts. This is the difference between an operator that leaves a smoking gun in Windows Event Log 4688 and one that doesn't.


!coerce — Multi-Vector Coerced Authentication Engine [modules/coerce.py]

Triggers NTLM authentication coercion from the remote target back to an operator-controlled listener (Responder / ntlmrelayx) via four distinct protocol vectors — all executed in-memory through the active PSRP session without staging any binary. Vectors: WebDAV HTTP UNC path (\\listener@80\share\dummy.txt) bypassing SMB signing requirements for ADCS ESC8 Web Enrollment relay attacks; MS-RPRN Print Spooler (\pipe\spoolss); MS-EFSR PetitPotam (\pipe\efsrpc); MS-DFSNM (\pipe\netdfs). Operator selects the appropriate vector based on available services and SMB signing posture on the target.


!laps — Windows LAPS & Server 2025 Hunter [modules/laps.py]

In-memory LDAP query covering both Legacy LAPS and Modern LAPS schemas in a single pass. Legacy LAPS: reads ms-Mcs-AdmPwd (cleartext local admin password) and ms-Mcs-AdmPwdExpirationTime (expiration timestamp) from DirectorySearcher. Modern LAPS (Windows Server 2025 / Windows 11 Azure-joined): queries msLAPS-Password, msLAPS-EncryptedPassword, and msLAPS-PasswordHistory — covering both cleartext and AES-256-CBC encrypted password blobs alongside full history. Results surface directly in the operator console and are ingested into the !loot pipeline.


!acl — Active Directory DACL Privilege Escalation Scout [modules/acl.py]

Audits discretionary access control lists on Tier-0 Active Directory objects: AdminSDHolder, Domain Admins, Domain Controllers, krbtgt, and linked GPOs. For each object, enumerates principals holding high-risk access rights — GenericAll, WriteDacl, WriteOwner, GenericWrite, User-Force-Change-Password — and flags them as privilege escalation vectors. All enumeration runs in-memory via DirectoryServices LDAP queries on the active PSRP session; no SharpACLs, BloodHound collection, or additional binary is staged.


!token — Process Token Hunter & In-Memory Impersonation [modules/token.py]

Enumerates process tokens across active logon sessions and performs privilege escalation triage by inspecting SeImpersonatePrivilege, SeAssignPrimaryTokenPrivilege, SeDebugPrivilege, and SeBackupPrivilege — flagging each with its current enabled/disabled state and the corresponding abuse primitive. Token duplication via DuplicateTokenEx reflection and named pipe client token coercion are surfaced as impersonation pathways, without requiring any binary drop to disk.


OPSEC & Core Improvements

Polymorphic PowerShell AST Command Obfuscation [core/opsec.py]

Added obfuscate_cmd() — a dynamic backtick and whitespace splitter for PowerShell cmdlet names that activates under stealth and hybrid-cloud OPSEC profiles. The function inserts randomized backtick sequences between cmdlet name characters (Invoke-Expression) while preserving variable names, parameters, and argument structure, defeating static ScriptBlockLogging signatures without breaking execution. Jitter sleep timing calculations across all profiles are now seeded from secrets.randbelow() rather than time.sleep(random.uniform(...)), making inter-request timing non-deterministic to statistical network anomaly detectors. OPSEC profile table updated with the new obfuscation column.

Thread-Safe SOCKS5 Proxy & Port Forwarding [core/tunnel.py]

Hardened Socks5Server and PortForwarder with threading.Lock() mutex guards on all connection tracking and socket descriptor operations, preventing race conditions during concurrent multi-session switches. Socket timeout guards are now applied on both ends of the relay preventing orphaned socket descriptors from accumulating in process memory on abrupt client disconnects.

WebSocketTransport — Public API Export [core/__init__.py, __init__.py]

WebSocketTransport is now exported from pwnrm.core and pwnrm package top-level __all__, making it accessible as a library transport for consumers integrating PwnRM programmatically.

bump_version.py — Hardened Repo Root Detection [src/release/bump_version.py]

Refactored find_repo_root() to check both __file__ parent and Path.cwd() as starting points, and tightens the root detection predicate to require both pyproject.toml and src/pwnrm/ to exist before declaring a match — eliminating false positives when the script is run from nested directories or via CI. cleanup_build_artifacts() now uses ignore_errors=True consistently and guards __pycache__ removal behind is_dir(). TARGETS expanded to include README.md Changelog badge for atomic version synchronization.


Security Hardening (Auditor Pass)

CWE-918 — SSRF / Proxy MitM via Ambient Environment [core/transports.py]

Enforced session.trust_env = False across all Transport base class instantiations. Previously, Python requests would honour HTTP_PROXY / HTTPS_PROXY environment variables, allowing a compromised operator environment to silently reroute WinRM traffic through an attacker-controlled proxy. With trust_env = False, ambient proxy configuration is fully ignored regardless of execution context.

CWE-208 / CWE-385 — Timing Side-Channel in CredSSP pubKeyAuth Verification [core/transports.py]

Replaced standard equality comparison (==) on the CredSSP Server-To-Client Binding hash verification with hmac.compare_digest() — a constant-time comparison that eliminates the byte-by-byte early-exit timing oracle that could leak information about the expected hash to an active MitM attacker.

CWE-532 — Credential Identifier Leakage into Logs [core/api.py]

Sanitized logging.info() call sites in create_transport() to remove raw credential variable references from structured log output. Transport authentication method is now logged descriptively without serializing any object that may hold credential material.

CWE-200 / CWE-522 — Expanded History Exclusion Pattern [shell/pwnshell.py]

HISTORY_EXCLUDE_PATTERN regex expanded to automatically suppress offensive tooling and credential keywords from .pwnrm_history: mimikatz, secretsdump, lsass, ccache, kirbi, dpapi — added alongside the existing -p, -H, --hash, --pfx-pass, password, secret, token patterns.


Custom CI/CD Security Audit Pipeline [.github/]

A fully self-contained GitHub Actions security audit pipeline with zero dependency on third-party SAST tools. All analysis is implemented directly in Python using ast, re, and subprocess.

Workflow (.github/workflows/security_audit.yml) — 5-job pipeline: setup → unit_and_regression (fail-fast) → custom_security_audit + dependency_audit (parallel) → report_and_annotate (always runs). Triggers: push to master/main/dev/release/*, pull request, weekly cron (Monday 03:00 UTC), and manual dispatch with audit_level input.

PowerShell Injection Auditor (.github/scripts/audit_ps_injection.py) — AST data-flow analyzer walking all ast.JoinedStr f-string nodes and string concatenations that feed into run_sync(), run_with_interrupt(), and run_command(). Traces variable origin up to 3 assignment hops and flags server-returned or user-supplied values that reach PS string interpolation without _pde(), _pse(), or str_b64() wrapping. Known-safe patterns (build_amsi_patch() output, secrets.token_hex() identifiers) are allowlisted.

Cryptographic Hygiene Auditor (.github/scripts/audit_crypto.py) — CryptoAuditVisitor AST walker validating CSPRNG usage (secrets vs random), secrets.randbelow() argument bounds (must be > 1), secrets.token_bytes() entropy floor (≥ 16 bytes), Fernet _SESSION_KEY lifecycle (no disk write, no log), and MD5 usage discrimination (file integrity = INFO, auth context = HIGH).

Filesystem & Permissions Auditor (.github/scripts/audit_filesystem.py) — Enforces atomic O_CREAT | O_EXCL file creation patterns for all writes under _PWNRM_DIR, verifies 0o600 chmod follows within 5 lines of os.open(), detects tempfile.mktemp() TOCTOU usage, checks __pycache__ git-tracking via git ls-files, and verifies symlink attack guard on history file creation.

XML Deserialization Safety Auditor (.github/scripts/audit_xml_safety.py) — Confirms defusedxml monkey-patches ET.fromstring and ET.parse on import, verifies defusedxml>=0.7.1 pinning in requirements.txt, and checks all ET.fromstring() call sites are wrapped in exception handlers catching defusedxml-specific exceptions.

Secret & Credential Exposure Auditor (.github/scripts/audit_secrets_exposure.py) — Regex scan across .py and .ps1 files for hardcoded credential patterns, sensitive variable logging at INFO level and above, HISTORY_EXCLUDE_PATTERN completeness against all CLI flags, and git history scan for credential patterns in committed diffs — including in files removed from HEAD.

Network & Transport Security Auditor (.github/scripts/audit_network.py) — Verifies max_redirects=0 and trust_env=False on every Session() instantiation, allow_redirects=False on all session.send() calls, hmac.compare_digest() for constant-time authentication comparisons, WebSocketTransport header correctness, and CSPRNG usage for WebSocket key generation.

Report Builder (.github/scripts/audit_report.py) — Aggregates all auditor JSON output into audit_report.json with per-auditor breakdown and overall pass/fail determination, generates a self-contained dark-mode audit_report.html with collapsible findings and inline code snippets (no external dependencies), and emits ::error:: / ::warning:: GitHub Actions annotations for inline PR diff view.

Master Orchestrator (.github/scripts/run_all_audits.py) — Runs all 6 custom auditors sequentially, renders a universal ASCII summary table, and enforces exit code semantics: 0 when CRITICAL == 0 and HIGH == 0, 1 otherwise. AUDIT_ALLOW_HIGH=1 environment override available for accepted-risk branches.


Test Suite

  • 41 automated unit and security regression tests passing at 100% — up from 26 in v2.0.1.
  • 5 new dedicated test modules: test_vss.py, test_coerce.py, test_laps.py, test_acl.py, test_token.py.

Full Changelog: v2.0.1...v2.1.0