首页/安全/取证与溯源速查/历史命令时间戳还原(HISTTIMEFORMAT)
Linux 取证135 条

历史命令时间戳还原(HISTTIMEFORMAT)

设置 HISTTIMEFORMAT 后,bash 会在历史文件中写入以 # 开头、后接 Unix 秒数的时间标记行,据此可把命令还原到时间线。

取证与溯源速查安全更新于 2026-10-13

历史命令时间戳还原

bash 默认只在历史文件里写命令文本、不写时间。开启 HISTTIMEFORMAT 之后,bash 每次写入历史时会先落一行以 # 开头、后接 Unix 秒数的标记,再写对应命令,因此可以把历史命令还原到秒级时间点。对 Linux 主机而言,这是少数带时间、又直接反映人工操作的痕迹来源。

基本信息

时间行格式#<Unix 秒数>,紧跟其后的那一行就是它对应的命令
生效方式HISTTIMEFORMAT 由 /etc/bashrc、~/.bashrc 或 /etc/profile 设置
换算命令date -d @<秒数>(GNU date);BSD 系用 date -r <秒数>
默认行为未设置该变量时历史文件中完全没有时间行
时间含义命令被键入那一刻的秒数,取值受主机系统时钟影响

典型使用场景

  • 还原主机上命令执行的先后顺序与相互间隔
  • 判断某条命令处于入侵窗口内,还是日常运维的遗留记录
  • 与认证日志的登录时段对照,确认命令归属哪个会话
  • 发现历史文件被整体重写或伪造的迹象
  • 导出带时间的历史清单,作为报告中的行为证据附件

解析成时间线

解析成时间线
grep -n '^#' /root/.bash_history | head            # 先看时间行的分布
sed -n '1,20p' /root/.bash_history                # 时间行与命令行交替出现
date -d @1697012345 '+%F %T %Z'                   # 单个时间行换算(GNU date)
awk '/^#/{t=substr($0,2); next} {print t" "$0}' /root/.bash_history | head -20   # 把时间挂到命令前
stat -c '%y %n' /root/.bash_history               # 历史文件自身时间,作为时间区间旁证

历史行读法

行内容含义注意点
#1697012345在其之后的命令被键入的时刻Unix 秒数,需按主机时区换算
普通命令文本行被执行过的命令不含输出,也不含被 HISTCONTROL 跳过的命令
空行与手工注释人为整理或工具写入的痕迹与时间行不成对时优先怀疑被改写
HISTCONTROL 会改变记录范围:ignorespace 跳过以空格开头的命令,ignoredups 合并连续重复命令,所以历史里的条目数并不等于命令的实际执行次数,统计时要把这一点写进说明。
历史文件可被任意改写,也是攻击者最常动手的位置;时间行没有任何校验机制,单凭它下结论风险很高,需与认证日志、审计记录或文件时间互证后才能采信。

易错点

  • 没确认 HISTTIMEFORMAT 是否生效,就把历史文件当无时间信息处理而放弃线索
  • 把时间行的秒数直接按 UTC 换算,跨时区主机上时间点整体偏移
  • 忽略 HISTCONTROL 的过滤规则,把历史条目数当作命令执行次数
  • 只看时间行不看相邻命令,配对一旦错位整段时间线一起失真

数据来源与参考

  • GNU Bash 手册(HISTTIMEFORMAT)
  • man 1 date(GNU coreutils)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌