系统时间被恶意篡改后如何通过 last / wtmp / utmp 找入侵痕迹
系统时间被恶意篡改后,last命令可能因wtmp日志污染而显示混乱时间。此时需交叉验证多个日志源。utmp记录当前会话,其时间戳基于系统启动时间,相对可靠。btmp记录失败登录,其时间戳不依赖系统时钟,是重要突破口。此外,可结合journalctl日志或进程状态进行关联分析,以发现隐藏会话并锁定真实入侵时间。

当系统时间被恶意回拨或大幅跳变,常规的审计命令如 last 可能会输出混乱的时间信息,比如显示“Thu Jan 1 00:00:00 1970”或大量登录记录集中在某一天。这并非命令本身出错,而是其读取的日志文件已被污染。攻击者常通过修改系统时间并干扰审计日志来掩盖行踪。面对这种情况,如何穿透迷雾,找到真实的入侵痕迹?关键在于理解不同日志文件的特性并进行交叉验证。
last 命令输出时间混乱?先确认 wtmp 文件是否被篡改
如果 last 显示的登录时间严重失真,问题根源通常在于 /var/log/wtmp 文件。这个文件记录了所有登录和注销事件,但其内部的时间戳依赖于写入时的系统时间。一旦系统时间被恶意修改,后续写入的时间戳自然就是错误的。
更狡猾的攻击者会直接清空或覆盖 wtmp 文件,试图抹除证据。如何判断 wtmp 是否可信?一个快速有效的方法是比对文件的磁盘修改时间与其中记录的最后登录时间。
具体操作如下:
- 使用
stat /var/log/wtmp命令查看文件的mtime,即最后一次被写入磁盘的真实时间。 - 运行
last -n 1查看wtmp中记录的最新一条登录时间。
如果文件的 mtime 远早于 last 显示的“最新登录时间”(比如相差数小时甚至数天),这就强烈暗示 wtmp 文件很可能被替换或重写过。此时,last 命令的时间排序已不可信,但文件中残留的原始记录条目可能依然存在,只是时间戳错乱了。
绕过时间戳,用 utmp + 进程状态交叉验证活跃会话
当 wtmp 的历史记录不可靠时,我们可以转向另一个关键文件:/var/run/utmp。它记录了当前在线的用户会话,并且有一个重要特性——其时间戳由内核写入,使用的是单调递增的启动时间(boot-time),而非易受篡改的墙上时钟(wall-clock)。这意味着,即使系统时间被回拨,只要会话尚未退出,w 命令(读取 utmp)仍能准确反映真实的在线用户状态。
不过,这里有个陷阱。攻击者常用的非交互式登录(例如执行 ssh user@host /bin/bash)不会在 utmp 中留下记录,因此 w 命令也看不到。这正是许多隐蔽后门采用的手法。
如何揪出这些“隐形”会话?需要结合进程状态进行交叉验证:
- 运行
w命令查看当前在线用户。 - 同时,执行
ps aux | grep “sshd:” | grep -v “sshd:”来查找所有 SSH 守护进程派生的子进程。 - 如果发现存在
sshd:进程,但w命令中没有对应的用户,那么极有可能是一个无 TTY 的(no-tty)会话。 - 进一步,可以用
lsof -i :22 -sTCP:ESTABLISHED检查所有已建立的 SSH 连接,并核对其进程 PID 在ps输出中是否显示为notty或缺少 TTY 字段。
对于使用 systemd 的系统,loginctl list-sessions 命令也是一个有力的补充工具。它基于内核的 session ID,比 utmp 更难被完全绕过。
btmp + lastb 是唯一不受系统时间欺骗的失败登录证据
在所有登录相关的日志中,/var/log/btmp 文件(记录失败登录尝试)堪称“铁证”。它的写入由 PAM 模块触发,最关键的是,其时间戳的生成不依赖系统墙上时钟。内核会使用 CLOCK_MONOTONIC 或基于启动时间的偏移来写入时间字段。
这意味着,哪怕攻击者把系统时间调回到 1970 年,lastb 命令输出的时间戳依然是相对可信的(通常会表现为自系统启动以来的秒数偏移)。使用 lastb -i 选项可以强制解析并显示这些相对时间。
因此,在时间被篡改的场景下,btmp 是寻找入侵线索最可靠的突破口之一:
- 执行
lastb -n 20快速浏览最近的失败登录,特别关注那些显示为invalid user或来自单一 IP 地址的高频尝试。 - 使用命令
lastb | awk ‘{print $3}’ | sort | uniq -c | sort -nr | head -5可以统计出撞库攻击中最常见的源 IP 地址。 - 如果发现
btmp文件大小为 0 或已被删除,别忘了检查是否有日志轮转留下的备份文件,例如btmp-20260128。攻击者常常会忽略这些轮转后的旧日志。
需要注意的是,lastb 命令默认需要 root 权限才能执行。另外,部分 Linux 发行版(如 CentOS 7 及以上版本)默认可能不开启 btmp 记录。可以检查 /etc/audit/rules.d/audit.rules 文件中是否存在 -w /var/log/btmp -p wa 这条审计规则来确认。
当 wtmp 不可靠时,用 journalctl 回溯认证事件原始时间
对于现代的 Linux 发行版(如 RHEL 8+ 或 Ubuntu 20.04+),SSH 的认证事件不仅会写入传统的 /var/log/secure(或 /var/log/auth.log),还会被 systemd-journald 捕获。Journal 日志的优势在于它使用独立的单调递增时间戳,不受系统时间修改的影响,并且精度高达纳秒级。
直接查询 journal 日志,往往比依赖已被污染的 wtmp 更可靠:
- 使用命令:
journalctl _COMM=sshd -S “2026-01-28 00:00:00” –no-hostname -o short-iso | grep -E “(Accepted|Failed)”。这里的-S参数指定起始的绝对时间,journald 会按照日志的真实写入顺序返回结果,完美规避系统时间错乱的问题。 - 如果 journal 日志也被清空,那么可以转而检查
/var/log/secure文件本身的修改时间(stat命令),然后使用像sed -n ‘/Jan 28.*sshd/p’ /var/log/secure这样的命令,根据日志行内的日期字符串进行手动提取。攻击者要批量替换日志文件中所有的时间字符串,难度会大得多。
这里有一个重要提醒:避免使用像 journalctl –since “2 hours ago” 这样的相对时间查询,因为它仍然会受到当前系统时间的影响。务必使用绝对的 ISO 时间格式。
说到底,最难以伪造的是多源日志在时间上的一致性。例如,如果发现 btmp 中有一条失败记录,几秒后 journalctl 里出现了对应的成功登录日志,同时 ps 命令显示该用户会话进程依然存活,那么这三者共同指向的时间窗口,就基本可以锁定真实的入侵发生时刻。这种跨日志的关联分析,是应对高级隐匿手段的终极武器。


































