What Warnings Does witr Generate for Suspicious Process Behavior? Full Detection Guide

witr generates 14 categories of warnings for suspicious process behavior, covering service instability, dangerous process states, resource exhaustion, privilege escalation, network exposure, and tampering indicators.

witr is an open-source process inspection tool that analyzes process ancestry and flags anomalous or high-risk characteristics. Its warning system, implemented in internal/source/detect.go, evaluates runtime signals to surface security-relevant conditions that administrators might otherwise miss.

How witr Detects Suspicious Process Behavior

The core detection logic resides in the Warnings() function at internal/source/detect.go. This function accepts a slice of model.Process structs, a restart count, and a source type, then returns a []string of human-readable warnings.

Each warning corresponds to a specific condition checked against process metadata fields defined in pkg/model/process.go, including Health, Sockets, User, Capabilities, WorkingDir, ContainerHealthcheck, Service, Command, ExeDeleted, and Env.

Service Instability Warnings

Excessive Service Restarts

witr flags services that have restarted more than 5 times. This indicates potential crash loops, resource contention, or unstable deployments.

  • Warning: Service has restarted <n> times
  • Location: detect.go lines 60-61
// Example: Triggering the restart warning
warnings := source.Warnings(ancestry, 7) // 7 restarts
// Output includes: "Service has restarted 7 times"

Missing Service Supervisor

On non-Windows systems, witr warns when no recognized service manager (systemd, upstart, sysvinit, launchd, etc.) supervises the process. This suggests ad-hoc execution or potential persistence mechanisms.

  • Warning: No known supervisor or service manager detected
  • Location: detect.go lines 99-105

Service/Binary Name Mismatch

When the declared service name differs from the actual process executable name, witr raises a correlation warning. This can indicate masquerading or misconfigured services.

  • Warning: Service name and process name do not match
  • Location: detect.go lines 124-140

Process State Warnings

Zombie Processes

Defunct processes that have terminated but remain in the process table consume PID space and may indicate parent process bugs or resource leaks.

  • Warning: Process is a zombie (defunct)
  • Location: detect.go lines 65-67

Stopped Processes

Processes in the stopped state (T state) are suspended, often via SIGSTOP, which can indicate debugging activity or manipulation attempts.

  • Warning: Process is stopped (T state)
  • Location: detect.go lines 68-70

Resource Exhaustion Warnings

High CPU Utilization

witr warns when a process has accumulated more than 2 hours of total CPU time, flagging potentially runaway computation or cryptomining activity.

  • Warning: Process is using high CPU (>2h total)
  • Location: detect.go lines 70-72

High Memory Consumption

RSS (Resident Set Size) exceeding 1 GB triggers a memory warning, helping identify memory leaks or unexpectedly resource-intensive processes.

  • Warning: Process is using high memory (>1GB RSS)
  • Location: detect.go lines 72-74

Extended Uptime

Processes running longer than 90 days may indicate neglected services, missed security patches, or stale deployments.

  • Warning: Process has been running for over 90 days
  • Location: detect.go lines 107-112

Privilege and Security Warnings

Root Execution

witr explicitly warns when processes run as root, highlighting increased blast radius from potential compromises.

  • Warning: Process is running as root
  • Location: detect.go lines 79-81

Dangerous Capabilities

Linux capabilities beyond standard sets (CAP_SYS_ADMIN, CAP_NET_RAW, etc.) are flagged with the specific capability list attached.

  • Warning: Process has dangerous capabilities: <list>
  • Location: detect.go lines 82-90

Network Exposure Warnings

Public Interface Binding

Processes listening on public network interfaces (0.0.0.0, ::, or external IPs) rather than localhost receive network exposure warnings.

  • Warning: Process is listening on a public interface
  • Location: detect.go lines 75-77

Execution Environment Warnings

Suspicious Working Directory

witr checks if the working directory is /, /tmp, or /var/tmp—common staging directories for exploits and temporary payloads.

  • Warning: Process is running from a suspicious working directory: <dir>
  • Location: detect.go lines 114-117

Deleted Binary Execution

When /proc/<pid>/exe points to a deleted file (indicated by (deleted) suffix), witr warns of potential library injection or in-flight updates without replacement.

  • Warning: Process is running from a deleted binary (potential library injection or pending update)
  • Location: detect.go lines 142-145

Missing Container Healthcheck

Container environments without configured healthchecks receive operational warnings, as this limits runtime visibility into service health.

  • Warning: Container has no healthcheck configured
  • Location: detect.go lines 119-122

Dynamic Library Injection Warnings

The envSuspiciousWarnings() helper (lines 38-50 and 93-45 in detect.go) inspects environment variables for injection vectors:

Variable Pattern Warning
LD_PRELOAD Process sets LD_PRELOAD (potential library injection)
DYLD_* Process sets DYLD_* variables (potential library injection): <keys>

These checks target Unix preload mechanisms and macOS dynamic link editor variables used in supply chain attacks and runtime tampering.

// Environment warning inspection
envWarns := source.Warnings([]model.Process{proc}, 0)
for _, w := range envWarns {
    if strings.Contains(w, "LD_PRELOAD") || strings.Contains(w, "DYLD") {
        // Handle injection indicator
    }
}

Using witr Warnings Programmatically

The Warnings() function signature in internal/source/detect.go:

func Warnings(p []model.Process, restartCount int, srcType model.SourceType) []string

Parameters:

  • p: Ancestry slice from oldest parent to target process
  • restartCount: Service manager restart counter
  • srcType: Enum indicating detection source (systemd, docker, etc.)

Return: Ordered slice of warning strings; empty if no conditions match.

Test Coverage and Verification

Unit tests in internal/source/warnings_test.go validate each warning condition against controlled model.Process inputs. Output formatting for CLI display is handled by internal/output/standard.go.

Summary

witr's warning system provides comprehensive coverage of suspicious process behavior:

  • Service health: Restart storms, missing supervisors, name mismatches
  • Process states: Zombies, stopped processes, extreme uptime
  • Resource abuse: CPU >2h, memory >1GB RSS
  • Privilege risks: Root execution, dangerous capabilities
  • Network exposure: Public interface binding
  • Execution anomalies: Suspicious working directories, deleted binaries
  • Container gaps: Missing healthchecks
  • Injection vectors: LD_PRELOAD and DYLD environment variables

All warnings source from internal/source/detect.go and operate on the model.Process struct defined in pkg/model/process.go.

Frequently Asked Questions

How does witr detect deleted binary execution?

witr examines the ExeDeleted boolean field in the model.Process struct, populated by checking if /proc/<pid>/exe resolves to a path marked (deleted). This addresses attacks where malware executes from unlinked files to evade disk forensics.

Can witr warnings be customized or suppressed?

The current implementation in detect.go uses fixed thresholds (5 restarts, 2h CPU, 1GB memory, 90 days uptime). Customization requires modifying source constants; runtime configuration is not yet exposed. The []string return format allows downstream filtering by consumers.

What triggers the DYLD warning specifically?

Any environment variable starting with DYLD_ (macOS dynamic linker prefixes) triggers the warning, including DYLD_INSERT_LIBRARIES, DYLD_LIBRARY_PATH, and DYLD_FRAMEWORK_PATH. The warning lists all matching keys found in the process environment.

Does witr run on Windows?

Most warnings apply to Linux and Unix-like systems. The "no known supervisor" warning explicitly excludes Windows (srcType != model.SourceWindows), as Windows service detection follows different patterns not covered by the current warning set.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →