搜索全站

输入至少 2 个字符,查找相关内容。

↑↓ 选择 Enter 打开Esc 关闭

取证工件地图

Linux 取证最反直觉的一点是它没有集中入口。Windows 上 Security.evtx 一个文件就能回答「谁在什么时候登录了什么」,Linux 没有等价物:同样的信息被拆散在文本日志、文件时间戳、utmp 二进制库、shell 历史、包管理器账本,以及只有运行中才存在的 /proc 里。

最后更新 2026-10-09版本 v2.0维护 DigiForensics查看历史 1

一、概述

Linux 取证最反直觉的一点是它没有集中入口。Windows 上 Security.evtx 一个文件就能回答「谁在什么时候登录了什么」,Linux 没有等价物:同样的信息被拆散在文本日志、文件时间戳、utmp 二进制库、shell 历史、包管理器账本,以及只有运行中才存在的 /proc 里。

这个结构直接导致两种失败模式,而且都很隐蔽:

  • 只看日志会漏掉一半证据。 文件创建时间、SUID 位、用户 crontab、authorized_keys 里的公钥——这些不写在任何日志里。清理日志能挡住一部分攻击痕迹,但完全挡不住配置文件类的证据。
  • 只看文件时间戳会误判。 Linux 有四个时间戳,atime 还受挂载选项影响,「文件在某时被访问过」推不出「某人某天读过它」。

还有一个更隐蔽的错误:把 Debian 系的路径套到 RHEL 系上。/var/log/auth.log 在 CentOS 上根本不存在,去那里找认证日志会得到「这台机器没有日志」的错误结论——而真相是它叫 secure。

按「谁记录了它」可以把工件分成六类,下面这张速查表就是按这个维度组织的:

类别 典型路径 记录什么
系统服务记录 /var/log/、/var/log/journal/<machine-id>/、/run/utmp 谁登录过、哪个服务发生了什么
账户体系 /etc/passwd、/etc/shadow、/etc/group 账户清单与口令哈希(只复制不破解)
应用配置 /etc/ssh/sshd_config、/etc/cron.d/、/etc/systemd/system/ 服务如何被配置、如何被自动拉起
用户私有数据 /home/<user>/.bash_history、.zsh_history、.ssh/ 交互行为、登录凭据材料
包管理器账本 /var/lib/dpkg/status、/var/lib/rpm/、/var/log/apt/history.log 装过什么、什么时候装、哪些是手动装的
运行时状态 /proc/、/tmp/、/var/tmp/ 活系统才有的进程与连接快照

配套的判定信息有两处容易被忽略:/etc/os-release 与 /etc/machine-id 决定家族判定与 journal 子目录定位;/etc/fstab 决定 atime 是否可信。

关于 /etc/shadow:取证对它只做复制与哈希记录,不做破解。离线镜像里它就是一个普通文件,权限位记在 inode 里。

动手之前要先有东西可看。上游是镜像制作与接入——你得先有一份哈希可验证的镜像(见镜像制作),并以只读方式挂载(见只读挂载与安全接入),否则后面每一次「读一下」都会改掉你要证明的东西。这一步要产出三样:发行版家族判定、关键目录的存在性清点、接入未污染证据的验证。下游是按类展开的日志、持久化、SSH、包清单、Shell 痕迹与运行时状态,有了地图才知道哪个方向是空的、哪个方向有料。

「某目录不存在」本身就是结论,而且往往是重要结论。它可能意味着这台机器上从未配置过该服务、被清理过、或路径被人为改写。

答得出来的是这台机器属于哪个发行版家族、哪些关键工件实际存在、哪些路径的缺失本身值得追问、账户体系与自动启动机制的整体轮廓、以及一次接入操作有没有污染原始卷。

答不出来的同样明确:

  • 任何具体行为。 地图只告诉你「去 /var/log/apt/history.log 看装了什么」,不解释那行记录的含义。
  • 时间线的完整形态。 时间戳的语义、精度与可信度分层需要专门方法,见时间线重建。
  • 运行时状态。 /proc 在离线镜像里是空的,这不是「没有进程」,而是「这个证据形态不适用于离线分析」,见proc 虚拟文件系统取证。
  • 已删除内容。 /tmp 与 /var/tmp 里已经 unlink 的文件不再出现在目录中,地图层面看不见。
  • 跨主机的东西。 单台主机的地图无法回答「它连着谁」,那需要网络侧或服务器侧材料。

走这套流程需要已经完成镜像制作与完整性校验,知道为什么要先验证哈希再分析;能区分 Debian 系与 RHEL 系的基础差异,至少知道认证日志路径在这两族里不同;了解 ext4 的基本概念(inode、目录项、挂载选项),否则无法判断 atime 是否可信,见ext4 结构与 inode;

会使用只读挂载与 loop 设备,理解为什么「先复制再分析」和「直接挂载只读」是两种不同的操作。这份地图是清点清单性质的,具备基本的命令操作能力即可,不需要深度解析能力。

二、核心原理

2.1 Linux 证据按"记录者"分为六类

理解 Linux 取证的关键不是背路径,而是记住每类痕迹由谁写入、什么时候写入。这决定了它的可信度和清除难度。

类别 记录者 典型工件 清除难度
系统服务日志 rsyslog / journald /var/log/auth.log、/var/log/messages、journal ★★★ 可 truncate -s 0
文件系统元数据 内核 VFS 层 atime/mtime/ctime/crtime、SUID 位、目录 mtime ★★★★ 需改系统时间或卸载卷
用户行为痕迹 Shell 自身 ~/.bash_history、.viminfo、.mysql_history ★★ 用户一键 history -c
子系统账本 包管理器 / 登录记账 dpkg 状态、/var/lib/rpm、utmp/wtmp/btmp ★★~★★★ 需 root 且会留不一致
运行时状态 内核 /proc 进程命令行、环境变量、打开的 fd、网络连接 ★★ 进程退出即消失
配置与自启 管理员 / 攻击者 crontab、systemd unit、ld.so.preload ★ 攻击者不会清理自己

实战推论:反取证通常是从上往下清的——先 history -c,再清日志文件,最后删自启项。而篡改 ld.so.preload、在 crontab 里留后门的成本几乎为零,且不写任何日志。所以「配置与自启」这一类的价值密度最高,见第 04 篇。

2.2 关键目录速查表

这是本篇最实用的一张表。 拿到镜像后按图索骥:

路径 内容 取证价值 参见
/var/log/ 系统与服务日志 ★★★★★ 02
/var/log/journal/ systemd journal(二进制) ★★★★★ 02
/var/log/wtmp / /var/log/btmp 成功 / 失败登录记录 ★★★★★ 05
/run/utmp 当前在线会话(重启即清空) ★★★★ 05
/var/log/apt/history.log 谁在何时装/卸/升级了什么 ★★★★★ 07
/etc/passwd、/etc/shadow 账户与口令哈希 ★★★★★ 本篇 3.2
/etc/ssh/sshd_config SSH 服务端配置 ★★★★★ 05
/etc/cron.d/ 系统级 crontab 片段(无用户字段) ★★★★★ 04
/var/spool/cron/crontabs/<user> 各用户 crontab ★★★★★ 04
/var/spool/cron/atjobs/ at / batch 一次性任务队列 ★★★★ 04
/etc/systemd/system/ 管理员自定义 unit(含 .wants/) ★★★★★ 04
/etc/ld.so.preload 动态链接器劫持(存在即高度可疑) ★★★★★ 04
/home/<user>/.bash_history 命令历史(默认无时间戳) ★★★★★ 03
/home/<user>/.zsh_history zsh 历史(带时间戳) ★★★★★ 03
/home/<user>/.ssh/ authorized_keys、known_hosts、config ★★★★★ 05
/root/.ssh/authorized_keys root 的授权公钥(含密钥植入) ★★★★★ 05
/tmp/、/var/tmp/ 临时文件,/var/tmp 常驻盘 ★★★★★ 本篇 2.5
/proc/ 运行时快照,离线读不到 ★★★★★ 06
/var/lib/dpkg/status Debian 已安装软件清单 ★★★★★ 07
/var/lib/rpm/ RHEL 已安装软件清单 ★★★★★ 07

⚠️ /etc/shadow 只能以 root 读取。 离线分析时它只是一个普通文件,权限位记录在 inode 里;取证不需要破解它,只需要复制并记录哈希。在线取证用 sudo cp 而不要 cat,避免终端滚屏泄漏。

2.3 发行版差异:最常见的错误来源

拿到镜像第一件事是判断发行版家族。 判错会导致整条证据链走错目录。判定方法按可靠度排序:

  1. 读标识文件(最可靠):/etc/os-release 字段标准化,/etc/debian_version 与 /etc/redhat-release 各自明确。
  2. 看包管理器数据库:/var/lib/dpkg/ 存在即 Debian 系,/var/lib/rpm/ 存在即 RHEL 系。
  3. 看认证日志文件名:auth.log vs secure(辅助判据——管理员可自定义 rsyslog 位置,见第 02 篇)。
对比项 Debian / Ubuntu RHEL / CentOS / Rocky / Alma
认证日志 /var/log/auth.log /var/log/secure
系统总日志 /var/log/syslog /var/log/messages
包管理数据库 /var/lib/dpkg/status /var/lib/rpm/Packages
安装历史 /var/log/apt/history.log /var/log/dnf.log、/var/log/yum.log
init 脚本(遗留) /etc/init.d/ /etc/rc.d/init.d/(软链到 init.d)
安装器 apt / apt-get / dpkg dnf(8+)/ yum(7)/ rpm

登录成功/失败账本(wtmp/btmp/utmp)与自定义 unit 目录(/etc/systemd/system/)两系相同。其他家族:Arch/Alpine(/var/log/messages、apk)、SUSE(/var/log/messages、zypper)。以 /etc/os-release 为准,不要靠猜。

2.4 时间戳在 Linux 上的特殊性

Linux 有四个时间戳,Windows 只有三个:

时间戳 含义 什么时候变
atime 访问/读取时间 文件被读时(受 relatime/noatime 影响)
mtime 内容修改时间 文件数据被写时
ctime inode 状态变更 权限、属主、链接数、mtime 任一变化时
crtime 创建时间(ext4 特有) 文件创建时写入,此后不变

取证含义:

  • ctime 变不等于内容被改。chmod、chown 都会更新它——改权限不改内容会留下 ctime 但不动 mtime,这是识别该手法的判据。
  • atime 的可信度受挂载选项支配:relatime 下若 atime 与 mtime/ctime 相差超过 24 小时则不更新;noatime 下完全不更新。读一次 stat 就可能改掉证据。详见第 08 篇。

2.5 /tmp 与 /var/tmp:两个都要查

/tmp 可能是 tmpfs(内存),systemd-tmpfiles 会按 age 清理;若是 tmpfs,重启即全部丢失。/var/tmp 通常是磁盘,同样受 tmpfiles age 约束,但重启不丢,是更常见的持久暂存地。

判定 /tmp 是否为 tmpfs(离线镜像上从 /etc/fstab 判断,不能靠「通常是内存」的经验):

grep -E ' /tmp | /var/tmp ' /mnt/df/etc/fstab

tmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0 ← 内存,重启丢失

/var/tmp 无独立行 → 属根分区,持久

/tmp 的 mode=1777(world-writable + sticky bit)意味着任何用户可写。这使它成为恶意载荷的首选暂存地,也是「文件属主为 root 但 mtime 很新」这类异常的高发区。

2.6 取证环境准备:dd 后的只读挂载

镜像制作完成后,第一步是建立只读接入环境。 挂载本身会写盘(更新 atime、可能回放 journal),必须控制住。

步骤 1:确认 ext4 分区起始扇区(示例:Slot 03, Start 1181696)

mmls /work/DigiForensics.dd

步骤 2:只读挂载——ro / noload / noatime 三项缺一不可

sudo mkdir -p /mnt/df sudo mount -o loop,ro,offset=1181696,noload,noatime /work/DigiForensics.dd /mnt/df

│ │ │ │ └─ 禁止更新 atime(否则 stat 本身就在改证据)

│ │ │ └─ 禁止回放 ext journal,保持崩溃现场原始状态

│ │ └─ 只读

└──────┴─ 建立 loop 设备

步骤 3:验证 + 记录镜像哈希(证据链要求)

findmnt -no OPTIONS /mnt/df sha256sum /work/DigiForensics.dd | tee /evidence/evidence.sha256

为什么 noload 是关键:ext4 有 journal,操作系统挂载时会回放未提交事务以修复文件系统——这会改变 inode 时间戳和目录结构。取证要的是原始的崩溃现场,不是修复后的整洁状态。

需求 方式 说明
完整浏览(首选) mount -o ro,noload,noatime 看不到已删 inode,但目录树完整
查已删除 inode debugfs 离线,不挂载 直接读镜像,见《ext4 结构与 inode》
需要 inode 号对照 fls / istat 直接读镜像 不挂载,inode 号天然对应

⚠️ 绝不使用 mount -o rw 或 debugfs -w。也不要用 GUI 文件管理器浏览挂载点——它会生成缩略图、访问文件(改 atime)。


三、操作步骤

3.1 第 1 步:确认发行版家族(决定后续所有路径)

已挂载到 /mnt/df

grep -E '^(NAME|VERSION_ID|ID)=' /mnt/df/etc/os-release ls /mnt/df/etc/*release /mnt/df/etc/debian_version 2>/dev/null

包管理器侧交叉验证(两条命令只有一条会成功)

ls -d /mnt/df/var/lib/dpkg 2>/dev/null && echo "→ Debian 系" ls -d /mnt/df/var/lib/rpm 2>/dev/null && echo "→ RHEL 系"

认证日志路径由上一步决定

ls -l /mnt/df/var/log/auth.log 2>/dev/null # Debian 系 ls -l /mnt/df/var/log/secure 2>/dev/null # RHEL 系

3.2 第 2 步:账户与口令材料清点

账户清单(含 UID、GECOS、登录 shell)—— 非敏感,可直接读

cut -d: -f1,3,4,6,7 /mnt/df/etc/passwd

口令哈希文件(只记录元数据与哈希,不尝试破解)

stat -c '%n size=%s mtime=%y mode=%a' /mnt/df/etc/shadow sha256sum /mnt/df/etc/shadow /mnt/df/etc/passwd | tee /evidence/acct-hash.txt

UID 0 的账户 —— 除 root 外出现即异常

awk -F: '$3==0 {print