Repository navigation
v3.1.0
PowerShell / Windows Support
- Persistent pwsh worker (internal/rules/pwsh): dual-parse architecture runs every command through both the bash parser and the
PowerShell native AST when pwsh.exe/powershell.exe is available. This catches .NET static method calls
([System.Net.WebClient]::new()), instance method chains, & $var call-operator resolution, and expandable string args that the bash
parser misses entirely. - .NET API detection: [System.IO.File], [System.Net.WebClient], [System.Net.Sockets.TcpClient], Invoke-WebRequest,
Invoke-RestMethod, and 20+ other .NET types mapped to operations in commandDB. - ::new() constructor lookup: [Type]::new(path) now falls back to the base type name in commandDB after stripping the ::new
suffix. - -EncodedCommand replaced with temp file: avoids Windows command-line length limit (8191 chars) for long scripts.
- PSScriptAnalyzer compliance: bootstrap script passes PSScriptAnalyzer on Windows CI.
- Platform detection module (internal/platform): ShellEnv string enum (unix, wsl, windows-native, msys2, cygwin) with IsWindows(),
HasBash(), HasPwsh() helpers. PS heuristic fallback now also fires in MSYS2/Git Bash (HasPwsh()) where users can invoke pwsh.exe
from a bash-compatible shell.
Multi-Operation Command Classification
- CommandInfo.ExtraOps []Operation and ExtractedInfo.Operations []Operation: commands can now declare multiple operations (e.g.
socat → [OpExecute, OpNetwork], vim → [OpRead, OpWrite]). - Rule.HasAnyAction(ops []Operation): rule matching fires when any of a command's operations matches a rule's actions list.
- Host extraction gate updated: socat, nc, ncat, netcat with ExtraOps:[OpNetwork] now extract hostnames even though their primary
operation is OpExecute.
CommandDB Fixes & Additions
- Editors (vim, vi, nano, emacs, pico, ed, ex): ExtraOps:[OpWrite] — editors both read and write files.
- Decompression tools (gunzip, bunzip2, unlzma, unzstd, unlz4): ExtraOps:[OpWrite] — decompress reads compressed input and writes
decompressed output. - awk/gawk/mawk/nawk: added -f/--file to PathFlags for awk script files.
- sed: added -f/--file to PathFlags.
- find: primary OpRead (filesystem search) + ExtraOps:[OpExecute] (for -exec).
- xargs: removed incorrect PathArgIndex (arg0 is a command name, not a path); added -a/--arg-file to PathFlags.
- truncate: added -r/--reference to PathFlags.
- setfacl: moved -M/--modify-file and -X/--remove-file from SkipFlags to PathFlags.
- gdb, lldb: ExtraOps:[OpRead] — debugger executes target binary and reads it.
Bug Fixes
- normalizeParsedCmdName: removed spurious || strings.Contains(name, "-") condition that lowercased PowerShell Verb-Noun cmdlets,
breaking PSWorker tests. - extractHosts — FQDN trailing dot (nc A.): falls back to looksLikeHost(rawToken) when the dot-stripped normalized host fails the
check, so single-label FQDNs like A. are correctly extracted as a. - extractHosts — hex FQDN (nc 0X0.): fuzz invariant now checks normalizeIPHost(strippedHost) so 0x0. → 0x0 → 0.0.0.0 is found in
info.Hosts. - Source builtin UNC hang (. //0.//0): CallHandler returns early for ./source builtins, preventing scriptFromPathDir → os.Stat
from triggering a ~14s SMB timeout on Windows UNC-like paths. - extractor_commands.go: extracted scp/rsync, socat, tar, sed command-specific logic into a dedicated file; uses strings.Cut and
tagged switch.
Internal
- pwsh worker moved to internal/rules/pwsh subpackage.
- internal/platform package created as an independent reusable module.
- New fuzz targets: FuzzPSWorker_NoCrash, FuzzExtractor_PSCommand.
- Release workflow: Commit/BuildDate ldflags, SHA-256 checksums in release assets.