Bash History Clearing
Attackers unset HISTFILE or shred .bash_history to hide commands, but the shell, kernel, and disk all retain copies the wipe never reaches.
Clearing the shell history is one of the first things a Linux intruder does after gaining a foothold. The goal is to remove the per-user record of typed commands — package installs, wget of a second-stage payload, credential dumping — that ~/.bash_history would otherwise hand the responder on a plate. The technique is trivial, scriptable, and built into the shell, which is exactly why crypto-mining and worm operators bake it into their installers.
It is also unreliable as a cover-up. The history file is only one of several places a command leaves a trace, and the most common clearing methods either fire too late, miss the in-memory copy, or leave a conspicuous gap that itself flags the session as hostile.
How it works
The usual moves disable logging for the current shell and erase the on-disk file:
# Stop the current shell from ever writing history, then wipe the file
unset HISTFILE
history -c # clear the in-memory list
shred -u ~/.bash_history # overwrite and unlink the fileunset HISTFILE prevents the running shell from flushing its in-memory history on exit; history -c clears the current session buffer; shred -u overwrites and removes the file. Some actors instead export HISTSIZE=0 or symlink ~/.bash_history to /dev/null so nothing is ever recorded.
Detection & analysis
Static analysis:
- Inspect
~/.bash_historyfor an abrupt end-of-file gap: a file that stops mid-session or is zero-length while the account clearly logged in (perwtmp/last) indicates clearing. A symlink to/dev/nullor a file withHISTSIZE/HISTFILEoverrides in.bashrc/.bash_profileis a planted indicator. - Carve unallocated space and the journal for recoverable history fragments. Because
shredon a journaling or copy-on-write filesystem (ext4 with data journaling, btrfs, ZFS) does not reliably overwrite the original blocks, deleted history lines are frequently recoverable withphotorec,ext4magic, or rawgrepof the block device for known command strings. - Check shells beyond bash —
~/.zsh_history,~/.python_history,~/.mysql_history,~/.lesshst— which attackers routinely forget.
Dynamic analysis:
- Where
auditdor the kernelexecveaudit rule is configured, every command ran as a process and is captured in/var/log/audit/audit.logindependent of shell history.sysmon-for-linux(Event ID 1) and eBPF agents (Falco, auditbeat) provide the same execution record that nohistory -ccan reach. - Correlate process accounting (
/var/log/account/pacctviapsacct/acct) and any sudo activity in/var/log/auth.logto reconstruct the command sequence the cleared history was meant to hide.
Detection rule hint: Alert when a session writes HISTFILE, HISTSIZE=0, history -c, shred, or ln -s /dev/null .bash_history, and treat any ~/.bash_history that is zero-length or symlinked for an account with recent interactive logins as compromised. Always rebuild the command timeline from auditd/eBPF execution logs and carve the filesystem journal for the deleted lines — the shell history is the least authoritative source.