They woke up to alerts screaming at 3:17 a.m. A production server was running rogue commands in Zsh, and every second mattered.
Zsh incident response demands speed, clarity, and precision. When a threat or failure hits a shell-based environment, the clock starts ticking. Attackers exploit hesitation. Systems bleed data. The only winning move is to see, understand, and act faster than the incident can spread.
Why Zsh Incidents Are Different
Bash dominates most incident playbooks, but Zsh has quirks that create unique challenges. Its advanced completion system, custom configurations, and plugin-driven workflows can be exploited in ways that standard Linux response teams overlook. Zsh aliases, functions, and sourced files can mask malicious activity in plain sight, making traditional command history review unreliable.
Core Steps for Zsh Incident Response
- Freeze the Scene – Lock down the affected system. Disconnect the network interface if remote command-and-control traffic is suspected.
- Preserve Evidence – Dump memory. Save
.zsh_history,.zprofile,.zshrc, and any custom plugin directories. - Audit Running Processes – Use
ps,lsof, andpstreeto catch in-memory payloads masquerading as legitimate processes. - Check Shell Hijacks – Inspect
$PATHchanges and replaced binaries; attackers often add trojaned scripts in user-specific bin directories. - Scan Environment Variables – Malicious commands can hide in exported variables used by Zsh hooks.
- Trace Persistence – Review crontabs, launch agents, and login scripts for re-entry points.
- Correlate with Logs – Cross-reference local shell activity with audit logs, system logs, and external telemetry.
These are not steps you do days later. They must run in sequence, in minutes. The aim is to get visibility without tipping off the attacker that you’re on to them.