命令历史为什么会被关掉
命令历史是还原攻击者动作最直接的线索,因此常见手法是让历史不落盘:把 HISTFILE 指向 /dev/null,或设置 HISTSIZE=0、unset HISTFILE,命令执行完不留痕迹。检查点在两处——shell 启动文件里的相关赋值,以及仍在运行的 shell 进程环境里残留的设置。
基本信息
| 适用平台 | Linux/Unix(bash 及部分 sh) |
|---|---|
| 关键变量 | HISTFILE、HISTSIZE、HISTFILESIZE、HISTCONTROL |
| 用户级位置 | ~/.bashrc、~/.profile、~/.bash_profile |
| 系统级位置 | /etc/profile、/etc/bash.bashrc、/etc/profile.d/ |
| 运行态视角 | /proc/<PID>/environ 中的实际环境变量 |
| 局限 | 自动化脚本也会 unset 历史变量,需结合时间判断 |
典型使用场景
- 排查反取证痕迹:历史文件异常短或缺失时找原因
- 确认入侵者是否故意关闭了历史记录以掩盖操作
- 处置期间建立干净的 shell 环境,保证自己的操作有记录
- 生产主机加固巡检,确认没有遗留关闭历史的设置
- 用 .bash_history 的内容与大小判断某账号被使用的程度
- 对比多个账号的历史记录密度,识别只被入侵者使用过的账号
排查历史相关设置
排查历史相关设置
grep -rn 'HISTFILE\|HISTSIZE\|HISTCONTROL' /etc/profile /etc/bash.bashrc /etc/profile.d/ /root/.bashrc /root/.profile 2>/dev/null | head
for h in /home/*; do grep -Hn 'HISTFILE\|HISTSIZE' "$h/.bashrc" "$h/.profile" 2>/dev/null; done
tr '\0' '\n' < /proc/$(pgrep -u root -n bash)/environ 2>/dev/null | grep -i hist # 运行态设置
ls -la /root/.bash_history /home/*/.bash_history 2>/dev/null # 文件大小与时间
stat -c '%y %s %n' /root/.bash_history 2>/dev/null # 最后写入时间变量含义与异常信号
| 变量 | 含义 | 异常信号 |
|---|---|---|
| HISTFILE | 历史写入路径 | 指向 /dev/null 或为空即可疑 |
| HISTSIZE | 内存中保留条数 | 为 0 表示当前会话不记录 |
| HISTFILESIZE | 落盘保留条数 | 为 0 表示退出时不写文件 |
| HISTCONTROL | 忽略规则 | ignorespace 让以空格开头的命令不留痕 |
| .bash_history mtime | 最后修改时间 | 明显早于账号最近活动说明未记录 |
自动化脚本、CI 任务为降低噪音也会 unset 历史变量,必须结合文件修改时间和账号用途判断,不要单凭变量存在就定性。反过来,历史里出现与你无关的命令(下载、加用户、改防火墙)本身就是高价值线索,逐条核对比看变量更快出结论。
处置时先用一个历史记录正常的干净 shell:在被关闭历史的会话里排查,你自己的操作也不会留下记录,事后无法复盘。