Skip to content

v3.1.0

Choose a tag to compare

@cyyever cyyever released this 05 Mar 13:28
· 246 commits to main since this release
1cf9773

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.