Shell Command-Line History Deletion Detected via Defend for Containers
This rule detects the deletion of shell command-line history files inside a container. The shell command-line history files are used to store the command-line history for the shell. Adversaries may delete these files to cover their tracks or evade detection.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2026/02/06"
3integration = ["cloud_defend"]
4maturity = "production"
5min_stack_comments = "Defend for Containers integration was re-introduced in 9.3.0"
6min_stack_version = "9.3.0"
7updated_date = "2026/02/06"
8
9[rule]
10author = ["Elastic"]
11description = """
12This rule detects the deletion of shell command-line history files inside a container. The shell command-line history
13files are used to store the command-line history for the shell. Adversaries may delete these files to cover their tracks
14or evade detection.
15"""
16from = "now-6m"
17index = ["logs-cloud_defend.file*", "logs-cloud_defend.process*"]
18interval = "5m"
19language = "eql"
20license = "Elastic License v2"
21name = "Shell Command-Line History Deletion Detected via Defend for Containers"
22note = """## Triage and analysis
23
24> **Disclaimer**:
25> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
26
27### Investigating Shell Command-Line History Deletion Detected via Defend for Containers
28
29This rule detects attempts during interactive sessions to delete, truncate, or disable shell command history files inside containers, a common tactic to erase evidence and impede investigations. An attacker uses kubectl exec to open an interactive bash shell in a running pod, then symlinks /root/.bash_history to /dev/null to prevent future commands from being recorded while performing reconnaissance or credential access.
30
31### Possible investigation steps
32
33- Correlate the container to its pod, namespace, and owning workload, and pull Kubernetes audit logs for exec/attach around the alert time to identify the caller identity, source IP, and user-agent and validate business justification.
34- Reconstruct the interactive session timeline by reviewing adjacent process telemetry before and after the history suppression to surface reconnaissance, credential access, data staging, or tooling downloads the actor may be hiding.
35- Examine shell configs and filesystem state for persistent history suppression (e.g., HISTFILE/HISTSIZE/HISTCONTROL in /etc/profile.d or .bashrc/.zshrc, or history files symlinked to /dev/null) and compare timestamps/owners to distinguish image defaults from live tampering.
36- Assess runtime context for impact by confirming the session’s user/UID, effective capabilities, mounted secrets or tokens, and writable volumes, and checking for privilege escalation or access to sensitive data.
37- If unauthorized, isolate the pod and capture volatile evidence (filesystem tarball, /proc, environment variables, shell rc files), rotate any exposed credentials, and hunt for similar events across pods/namespaces and the same source IP or identity.
38
39### False positive analysis
40
41- An authorized operator opens an interactive shell in a container for troubleshooting and intentionally clears or disables history (e.g., history -c, rm/truncate ~/.bash_history, or export HISTFILE=/dev/null) to avoid recording sensitive commands.
42- The container image’s interactive shell startup configuration automatically disables history (e.g., HISTFILESIZE=0, unset HISTFILE, or linking ~/.bash_history to /dev/null), so a normal debug login triggers the alert.
43
44### Response and remediation
45
46- Isolate the affected pod by applying a temporary NetworkPolicy to block egress, remove pods/exec and pods/attach permissions from the caller, and terminate any interactive shells that executed rm, history -c, or truncate on ~/.bash_history or linked it to /dev/null.
47- Eradicate changes by removing any ~/.bash_history symlink to /dev/null, recreating /root/.bash_history and /home/*/.bash_history with correct ownership and 600 permissions, and restoring HISTFILE/HISTFILESIZE/HISTCONTROL in /etc/profile.d, .bashrc, and .zshrc to expected values.
48- Recover by rebuilding and redeploying the workload from a trusted image, rotating any secrets or tokens accessed during the session (service account token, cloud provider credentials, SSH keys), and validating that new shells now persist command history.
49- Escalate to incident response if the exec caller identity is unknown or unauthorized, if privileged actions (kubectl with cluster-admin, sudo, or reading /var/run/secrets/kubernetes.io/serviceaccount) occurred after history deletion, or if multiple pods/namespaces show coordinated history suppression.
50- Harden by restricting kubectl exec/attach to break-glass roles via RBAC, enforcing admission controls to block images or init scripts that unset HISTFILE or link ~/.bash_history to /dev/null, and adding runtime policy to deny rm/truncate of history files and alert on history -c."""
51risk_score = 73
52rule_id = "cebabc1e-1145-4e39-b04b-34d621ee1e2c"
53severity = "high"
54tags = [
55 "Data Source: Elastic Defend for Containers",
56 "Domain: Container",
57 "OS: Linux",
58 "Use Case: Threat Detection",
59 "Tactic: Defense Evasion",
60 "Resources: Investigation Guide",
61]
62timestamp_override = "event.ingested"
63type = "eql"
64query = '''
65any where host.os.type == "linux" and event.category in ("file", "process") and process.interactive == true and container.id like "?*" and (
66 (event.category == "file" and event.type == "deletion" and file.name in (".bash_history", ".sh_history", ".zsh_history")) or
67 (event.category == "process" and event.type == "start" and event.action == "exec" and (
68 (
69 (
70 process.args in (
71 "rm", "/bin/rm", "/usr/bin/rm", "/usr/local/bin/rm",
72 "echo", "/bin/echo", "/usr/bin/echo", "/usr/local/bin/echo"
73 ) or
74 (process.args in ("ln", "/bin/ln", "/usr/bin/ln", "/usr/local/bin/ln") and process.args == "-sf" and process.args == "/dev/null") or
75 (process.args in ("truncate", "/bin/truncate", "/usr/bin/truncate", "/usr/local/bin/truncate") and process.args == "-s0")
76 ) and process.args like ("*.bash_history*", "*.sh_history*", "*.zsh_history*")
77 ) or
78 (process.name == "history" and process.args == "-c") or
79 (process.args == "export" and process.args in ("HISTFILE=/dev/null", "HISTFILESIZE=0")) or
80 (process.args == "unset" and process.args == "HISTFILE") or
81 (process.args == "set" and process.args == "history" and process.args == "+o")
82 )
83 )
84)
85'''
86
87[[rule.threat]]
88framework = "MITRE ATT&CK"
89
90 [rule.threat.tactic]
91 name = "Defense Evasion"
92 id = "TA0005"
93 reference = "https://attack.mitre.org/tactics/TA0005/"
94
95 [[rule.threat.technique]]
96 name = "Indicator Removal"
97 id = "T1070"
98 reference = "https://attack.mitre.org/techniques/T1070/"
99
100 [[rule.threat.technique.subtechnique]]
101 name = "Clear Command History"
102 id = "T1070.003"
103 reference = "https://attack.mitre.org/techniques/T1070/003/"
Triage and analysis
Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
Investigating Shell Command-Line History Deletion Detected via Defend for Containers
This rule detects attempts during interactive sessions to delete, truncate, or disable shell command history files inside containers, a common tactic to erase evidence and impede investigations. An attacker uses kubectl exec to open an interactive bash shell in a running pod, then symlinks /root/.bash_history to /dev/null to prevent future commands from being recorded while performing reconnaissance or credential access.
Possible investigation steps
- Correlate the container to its pod, namespace, and owning workload, and pull Kubernetes audit logs for exec/attach around the alert time to identify the caller identity, source IP, and user-agent and validate business justification.
- Reconstruct the interactive session timeline by reviewing adjacent process telemetry before and after the history suppression to surface reconnaissance, credential access, data staging, or tooling downloads the actor may be hiding.
- Examine shell configs and filesystem state for persistent history suppression (e.g., HISTFILE/HISTSIZE/HISTCONTROL in /etc/profile.d or .bashrc/.zshrc, or history files symlinked to /dev/null) and compare timestamps/owners to distinguish image defaults from live tampering.
- Assess runtime context for impact by confirming the session’s user/UID, effective capabilities, mounted secrets or tokens, and writable volumes, and checking for privilege escalation or access to sensitive data.
- If unauthorized, isolate the pod and capture volatile evidence (filesystem tarball, /proc, environment variables, shell rc files), rotate any exposed credentials, and hunt for similar events across pods/namespaces and the same source IP or identity.
False positive analysis
- An authorized operator opens an interactive shell in a container for troubleshooting and intentionally clears or disables history (e.g., history -c, rm/truncate ~/.bash_history, or export HISTFILE=/dev/null) to avoid recording sensitive commands.
- The container image’s interactive shell startup configuration automatically disables history (e.g., HISTFILESIZE=0, unset HISTFILE, or linking ~/.bash_history to /dev/null), so a normal debug login triggers the alert.
Response and remediation
- Isolate the affected pod by applying a temporary NetworkPolicy to block egress, remove pods/exec and pods/attach permissions from the caller, and terminate any interactive shells that executed rm, history -c, or truncate on ~/.bash_history or linked it to /dev/null.
- Eradicate changes by removing any ~/.bash_history symlink to /dev/null, recreating /root/.bash_history and /home/*/.bash_history with correct ownership and 600 permissions, and restoring HISTFILE/HISTFILESIZE/HISTCONTROL in /etc/profile.d, .bashrc, and .zshrc to expected values.
- Recover by rebuilding and redeploying the workload from a trusted image, rotating any secrets or tokens accessed during the session (service account token, cloud provider credentials, SSH keys), and validating that new shells now persist command history.
- Escalate to incident response if the exec caller identity is unknown or unauthorized, if privileged actions (kubectl with cluster-admin, sudo, or reading /var/run/secrets/kubernetes.io/serviceaccount) occurred after history deletion, or if multiple pods/namespaces show coordinated history suppression.
- Harden by restricting kubectl exec/attach to break-glass roles via RBAC, enforcing admission controls to block images or init scripts that unset HISTFILE or link ~/.bash_history to /dev/null, and adding runtime policy to deny rm/truncate of history files and alert on history -c.
Related rules
- Encoded Payload Detected via Defend for Containers
- Suspicious Interactive Process Execution Detected via Defend for Containers
- System Path File Creation and Execution Detected via Defend for Containers
- Kubeconfig File Creation or Modification
- Potential Impersonation Attempt via Kubectl