Agent Persistence Mechanism Installation
This detects an AI coding or automation agent making a change that would let code or a user survive a reboot or logout — things like cron jobs, systemd services, shell startup files, launchd agents, or new admin accounts. It flags the action itself, not whether it was malicious, so every such change gets logged and can be reviewed.
How the attack works
An agent with shell or file-editing tools is asked, or decides on its own, to make something run automatically. It either writes directly to a known persistence location (cron files, systemd unit directories, shell init files, SSH authorized_keys, Startup folders, etc.), writes the full body of a systemd unit or launchd job even if placed somewhere unusual, or runs a command that installs persistence directly — crontab -e, systemctl enable, launchctl load, schtasks /create, useradd, reg add for a Run key, and similar. Any one of these three patterns alone is enough to match, since each is a complete persistence action by itself. Commands are matched carefully so that mentioning 'crontab' or 'useradd' in a comment or commit message does not trigger a false alarm.
Netzilo detection
Netzilo reports this behaviour when it is observed.
- Signature ID
- 7c3f9a41-2d5e-4b86-9f0a-1e6d4c8b52f3
- Severity
- High
Why it matters
An attacker who gets an agent to execute this kind of change gains a foothold that survives restarts and can run unattended — a backdoor account, a scheduled task, or a script that starts at every login. Even when the agent's user intended it, unreviewed persistence changes are a common way lateral movement or backdoors go unnoticed.
What you can do
- →Review any agent-initiated write to cron, systemd, launchd, shell init files, or authorized_keys before it ships, treating it like a code change to production.
- →Require explicit human approval for agent actions that create scheduled tasks, services, or new user accounts.
- →Keep an audit trail of agent tool calls that touch persistence-relevant paths so you can distinguish requested setup work from unexpected changes.
- →Exclude known-safe contexts (documentation, IaC templates, container build files) from alert fatigue, but still review home-directory rc file edits and direct shell commands.
Known benign look-alikes
- Developer environment setup - an agent asked to "add nvm/pyenv/rbenv to my shell" or "put this alias in my zshrc" writes .zshrc or .bashrc legitimately. Filtered only when the write targets a documentation or IaC path; a genuine home-directory rc edit will still report by design, since it is exactly the change an operator wants attributed.
- Packaging and infrastructure-as-code work - authoring a systemd unit inside an Ansible role, a Debian packaging tree, a Helm chart or a Dockerfile. Suppressed by filter_iac_path and filter_container_build.
- Documentation and runbook authoring - a README or runbook that shows a crontab line or a launchd plist. Suppressed by filter_doc_path (any .md/.rst/.adoc target and any docs/ examples/ testdata/ path) and by filter_teaching_text.
- Security training and detection-engineering content - writing this very Sigma rule, an ATT&CK write-up, or a purple-team exercise script. Suppressed by filter_teaching_text and filter_sigma_self.
- Diagnostics and inventory - systemctl status, crontab -l, launchctl list, schtasks /query, Get-ScheduledTask. Suppressed by filter_inspect_cmd.
- Cleanup and remediation - disabling a unit, unloading a launch agent, deleting a scheduled task or a user account. Suppressed by filter_removal_cmd.
- Container and VM provisioning - RUN useradd inside an image build, or a systemd unit written into a container rootfs. Suppressed by filter_container_cmd, filter_container_build and filter_ephemeral_path.
- CI job authoring - a systemd unit or cron entry written into a temporary build directory. Partially suppressed by filter_ephemeral_path; a write to a real /etc path from CI will report.