Repository navigation
v2.0.0
What's Changed
Important
v2.0.0 is a full architectural overhaul. The PwnShell REPL, auth layer, module system, and output pipeline are not backward-compatible with v1.x configuration files or session artifacts.
Core Architecture — Multi-Session Manager & Jump Graph (session_mgr.py)
!session— Concurrent PSRP Runspace orchestration across heterogeneous targets: Prior to v2.0.0, PwnRM maintained a single activeRunspaceper process, requiring the operator to re-authenticate on context switches between pivots. The newSessionManagerholds an indexed pool ofpypsrp.RunspacePoolobjects keyed by session ID, each tagged with target metadata (hostname, auth type, auth material hash).!session listrenders the live pool with connection state;!session switch <id>performs a zero-reauth context switch by hot-swapping the activeRunspacePoolreference inPwnShell;!session exec-all <cmd>fans out a single command across all open sessions and aggregates structured results. Session metadata is serialized and persisted under~/.pwnrm/sessions/with strict0o700(POSIX) /icacls "%USERNAME%:(OI)(CI)F" /inheritance:r(Windows NTFS) permission enforcement, preventing multi-tenant credential leakage — consistent with the ACL hardening introduced in v1.2.1.
Tunneling — In-Band PSRP SOCKS5 Proxy & Port Forward Multiplexer (tunnel.py)
-
!socks— RFC 1928 compliant SOCKS5 server multiplexed through PowerShell streams: Conventional SOCKS pivoting requires a listener on the remote host (chisel, ligolo, etc.) and a firewall exception. PwnRM's SOCKS5 implementation runs a localasyncioserver bound to127.0.0.1:1080(configurable) and tunnels TCP frames through the existing PSRPstdout/stdinstream pair using a length-prefixed framing protocol. No listener socket is opened on the remote host; traffic appears as normal WinRMWSManFault-shaped XML fragments to network inspection. Implementation is RFC 1928 §3–§6 compliant:CONNECTmethod, IPv4/IPv6/FQDN address types, andAUTH_NONE/USERNAME_PASSWORDsub-negotiation (§4). -
!portfwd— Local-to-remote TCP port forwarding with lifecycle management:!portfwd <LPORT> <RHOST>:<RPORT>spawns anasyncioTCP listener onLPORTthat proxies connections through the active PSRP session toRHOST:RPORTon the target network segment.!portfwd listenumerates active forward rules with their bound port and target;!portfwd stop <id>cleanly drains theasynciotransport and closes the listener without disrupting the parent PSRP session.
Loot — Structured & Encrypted Loot Pipeline (loot.py)
!loot— Atomic loot ingestion with per-target namespacing: Credentials, Kerberos tickets (.ccache,.kirbi), certificates (.pfx,.pem), DPAPI master keys, and memory dumps are stored under~/.pwnrm/loot/<target>/in per-artifact-type subdirectories. File creation usesO_CREAT | O_EXCLatomic semantics to prevent TOCTOU overwrites, and all written files are immediatelychmod'd to0o600. The ingestion pipeline accepts raw bytes from any command module and performs MIME sniffing to auto-classify artifact type before persistence, removing the need for manual file-type specification per loot operation.
OPSEC — Profile & Jitter Engine (opsec.py)
!opsec— Behavioural profile switching with per-request timing jitter: Four operational profiles are implemented:stealth(high jitter, low throughput, legitimateMicrosoft WinRM ClientUser-Agent header, command fragment obfuscation),balanced(moderate jitter, no obfuscation),aggressive(minimal jitter, raw commands), andhybrid-cloud(tuned for Azure Arc / WinRM-over-HTTPS environments with cloud-specific User-Agent strings). Jitter is applied at the PSRP transport layer between requests using a per-profile(min_ms, max_ms)range sampled from a uniform distribution, making request cadence non-deterministic to timing-based EDR heuristics.
Modules — Pluggable Modular Engine (src/pwnrm/modules/)
BaseModule/ModuleManager— Hot-loadable plugin architecture: v2.0.0 introduces aBaseModuleabstract class exposingname,aliases,help_text,run(shell, args), and optionaltab_complete(shell, prefix)contract.ModuleManagerperforms filesystem discovery of*.pyfiles undersrc/pwnrm/modules/, imports them, and registers allBaseModulesubclasses into thePwnShellcommand dispatcher at startup. Third-party and user-authored modules drop into the modules directory with no changes to core — the loader handles registration, tab completion injection, and!helplisting automatically.
Exploitation — Full ADCS Engine ESC1–ESC16+ (adcs.py)
!adcs— Deep ADCS template vulnerability audit without dropping binaries: Implements in-memory LDAP enumeration of Certificate Authority configuration and certificate template ACLs to audit for ESC1 (enrollee-supplied Subject), ESC2 (Any Purpose EKU), ESC3 (Certificate Request Agent), ESC4 (template write ACL), ESC6 (EDITF_ATTRIBUTESUBJECTALTNAME2), ESC7 (CA officer ACL), ESC9/ESC10 (no-security-extension / weak certificate mapping), ESC13 (OID group link), ESC15 (schema version 1 + Application Policy EKU), ESC16 (disabledszOID_NTDS_CA_SECURITY_EXTglobally), and ESC17 (WSUS-to-ADCS abuse — enumeratesWUServerregistry value underHKLM\Software\Policies\Microsoft\Windows\WindowsUpdateto identify HTTP-only WSUS endpoints susceptible to MitM, where an attacker-controlled update package can trigger a certificate enrollment request to an internal CA under the machine account context, enabling domain privilege escalation). Enterprise CA discovery queriesCN=Certification Authorities,CN=Public Key Services,CN=Servicesin the configuration naming context. All enumeration runs through PowerShell LDAP queries on the active PSRP session; no SharpADCS, Certify, or Certipy binary is staged to disk.
Kerberos — Advanced Suite (kerberos.py)
!kerberos— AES-priority Kerberoasting, AS-REP roasting, Diamond Tickets, and Server 2025 dMSA/BadSuccessor inspection: Kerberoasting requests are issued withetype=18(AES256-CTS-HMAC-SHA1-96) preference before falling back to RC4, consistent with environments where RC4 is deprecated underMsds-SupportedEncryptionTypes. AS-REP roasting enumerates accounts withDONT_REQ_PREAUTHset via LDAP and pre-computes roastable target lists. Diamond Ticket workflow assistance provides step-by-step identity-swap guidance for environments where synthetic Golden/Silver Tickets trigger KDC anomaly detection on Defender for Identity. TheBadSuccessorinspection block enumeratesmsDS-ManagedAccount/ delegated Managed Service Account (dMSA) objects and surfaces misconfigured successor principal assignments introduced in Server 2025.
Cloud — Hybrid Entra ID / Azure AD PRT Pivot (entra.py)
!entra— Device join status inspection and WAM / Azure CLI / Az PowerShell credential cache extraction: Queriesdsregcmd /statusoutput via PSRP and parsesAzureAdJoined,DomainJoined, andEnterpriseJoinedfields to determine hybrid join topology. WhenAzureAdJoined: YES, the module enumerates Web Account Manager (WAM) token broker cache paths in the user profile forms-deviceidand PRT-adjacent token blobs. Azure CLI token cache (~/.azure/msal_token_cache.json) and Azure PowerShell credential cache (~\AppData\Roaming\Windows Azure PowerShell\TokenCache.dat) paths are identified and flagged for extraction via!loot.
Credential Hunting — Deep Credential & Token Hunter (creds.py)
!creds— DPAPI master key enumeration, browser credential store detection, and token privilege audit: Enumerates%APPDATA%\Microsoft\Protect\<SID>\for DPAPI master key files. Browser credential store detection covers Chrome, Edge, and BraveLogin Data(SQLite) andLocal State(AES-GCM key blob) paths under%LOCALAPPDATA%. Token privilege audit inspects the current runspace token forSeDebugPrivilege,SeImpersonatePrivilege, andSeTcbPrivilege, flagging each with its enable/disable state and a note on the relevant abuse primitive.
Evasion — Polymorphic Evasion & EDR Scout (evasion.py)
!evasion— Randomized polymorphic AMSI/ETW patching and EDR driver fingerprinting: AMSI bypass patchesAmsiScanBufferinamsi.dllusing a randomized stub (variable nop-sled length, randomized jmp displacement encoding) to avoid static signature matching on the patch bytes. ETW bypass patchesEtwEventWriteinntdll.dllwith aret/xor eax, eax; retstub selected at random. EDR driver detection queries\\.\device namespace and the SCM service list forcsagent.sys(CrowdStrike),SentinelAgent.sys(SentinelOne),WdFilter.sys(Windows Defender),CbDefenseW64.sys(Carbon Black), andcylance.sys(Cylance Protect), reporting detected products with their loaded driver path.
Reconnaissance — In-Memory BloodHound AD Graph Collector (bloodhound.py)
!bloodhound— 100% in-memory LDAP-based AD graph collection, BloodHound CE / v4–v5 compatible: Performs LDAP enumeration of Users, Computers, Domain Controllers, and High-Value Groups (Domain Admins, Enterprise Admins, Schema Admins, etc.) through the active PSRP session without staging SharpHound, AzureHound, or any binary to disk. Output is serialized to BloodHound CE / v4–v5 JSON format and ingested directly into the!lootpipeline. The collection scope mirrors SharpHound'sDefaultcollection method: ACLs, Group Memberships, ObjectProperties, and Trusts.
Lateral Movement — Subnet Scout & Dispatcher (lateral.py)
!lateral— In-memory subnet sweep targeting WinRM, SMB, and RDP: Issues PowerShellTest-NetConnectionfan-out jobs across the target's subnet (inferred from active NIC config or operator-supplied CIDR) probing ports 5985/5986 (WinRM HTTP/S), 445 (SMB), and 3389 (RDP). Results are returned as a structured host/port/state table. Reachable WinRM hosts can be immediately promoted to new sessions via!sessionintegration.
Automation — Declarative Playbook Runner (playbook.py)
!playbook— Structured multi-step automation with built-in red team playbooks: ThePlaybookRunnerparses a simple YAML DSL defining ordered steps (module name + args + conditionals). Built-in playbooks:default_triage(hostname, whoami, privilege, AV check, network adapters),ad_recon(domain info, SPNs, AS-REP candidates, ADCS quick scan),stealth_audit(switches tostealthOPSEC profile, runs triage + recon with jitter, loot ingestion). Custom playbooks load from~/.pwnrm/playbooks/*.yml.
Tests — Automated Regression & Security Unit Test Suite (tests/)
- 15 unit tests covering session integrity, tunnel correctness, loot atomicity, OPSEC profile switching, and module discovery: Test suite covers: session manager CRUD + state machine transitions, SOCKS5 handshake negotiation (RFC 1928
VER/METHOD/CONNECTframes), loot pipeline atomic write + permission assertions, OPSEC profile activation + jitter range bounds, module discovery +BaseModulecontract validation, and security guard checks (path traversal in loot keys,O_EXCLcollision handling, permission enforcement post-write). Run viapytest tests/ -v.
Changed
PwnShellREPL refactored with dynamic prompt status bar:PwnRM[S:<session_count>|<active_host>]|<cwd>>— session count and active target visible at all times.- ui.py banner, color scheme, and tab completion lists updated to reflect all v2.0 command surface.
- cli.py enforces UTF-8 console output reconfiguration at startup via
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')for cross-platform and Windows Terminal compatibility.
Full Changelog: v1.2.6...v2.0.0