bash 历史文件的取证价值
~/.bash_history 记录交互式 shell 里执行过的命令,是判断「攻击者在主机上做过什么操作」最直接的一手材料。它的写入行为由 bash 控制:默认在会话结束时把本次命令追加进文件,运行中的会话内容还在内存里,尚未落盘。文件本身是纯文本,行序与执行顺序大体一致,是否带有时间戳取决于 HISTTIMEFORMAT 是否被设置过,这一点决定了它能否直接进时间线。
基本信息
| 文件路径 | ~/.bash_history;root 为 /root/.bash_history |
|---|---|
| 写入时机 | 默认会话退出时写入(shopt -s histappend 影响追加或覆盖行为) |
| 时间戳 | 仅在设置了 HISTTIMEFORMAT 时以 #epoch 行记录,否则无时间 |
| 相关变量 | HISTSIZE、HISTFILESIZE、HISTCONTROL(ignorespace/ignoredups)、HISTIGNORE |
| 权限 | 文件归用户所有,通常 600,读其他用户的历史需 root |
| 其他 shell | zsh 用 ~/.zsh_history,fish 用 ~/.local/share/fish/fish_history |
典型使用场景
- 还原攻击者在被入侵主机上的操作序列(下载、解压、提权、留后门)
- 确认落地文件来源:看 wget/curl 的完整 URL
- 判断工具是否被清理:命令执行过而文件已不在,说明有清理动作
- 核对管理员自述的操作与实际记录是否一致
- 找出横向移动命令(scp、ssh、for 循环批量执行)
- 定位持久化写入位置(crontab、systemd 单元、ssh 密钥目录)
采集与判读
采集与判读
# 先看文件属性与行数,属性变化本身也是线索
ls -la --time-style=full-iso /root/.bash_history /home/*/.bash_history 2>/dev/null
wc -l /home/*/.bash_history 2>/dev/null
# 逐行浏览内容(带行号便于在报告里引用)
nl -ba /root/.bash_history | tail -100
# 若启用了 HISTORYTIMEFORMAT,时间戳以 # 开头的 epoch 行出现
grep -n '^#' /root/.bash_history | head
# 采集时立刻做只读副本并记录哈希,后续分析针对副本
cp --preserve=all /root/.bash_history /evidence/history_root.txt
sha256sum /evidence/history_root.txt
# 与其他来源交叉:进程与连接快照往往能补上未落盘的命令
ss -tunap > /evidence/ss_before.txt; ps auxww > /evidence/ps_before.txt判读要点逐项
| 观察项 | 含义 | 异常表现 |
|---|---|---|
| 文件 mtime | 最后一次写入时间 | 与已知最早入侵时间矛盾,说明被改写或替换 |
| 行数与连续性 | 命令序列是否完整 | 行号处出现明显跳跃,提示被删改 |
| # epoch 行 | 命令执行时间 | 有 epoch 行说明曾设置过 HISTTIMEFORMAT,可用于对齐时间线 |
| 命令内容 | 实际执行动作 | 出现 history -c、unset HISTFILE、rm .bash_history,属典型反取证 |
| 多用户文件对比 | 各账号操作面 | 普通业务账号出现提权与扫描命令,需重点解释 |
采集前不要执行 history -c、history -w 或反复敲相关命令:交互式会话会把这些动作也写进文件,覆盖或污染原始记录。需要长时间排查时,先把文件复制出来在副本上分析。
运行中的进程内存里可能还留着尚未落盘的命令。若怀疑攻击者会话仍活跃,先做内存采集或直接读取 shell 进程环境与命令行(/proc/<pid>/cmdline),再考虑重启或关闭会话。