凌晨 02:17,EDR 报告一台 Linux 生产服务器上的 root 进程从 /dev/shm/.cache/ 启动,连接陌生公网地址;同一时间,云审计日志出现异常角色调用,另一台内网主机也使用相同 SSH 公钥登录。
攻击者已经拥有 root 权限,可能控制多台主机,能够读取本机凭据、篡改日志和安全工具,并可能正在横向移动或外传数据。
此时最危险的错误,不是漏查一个目录,而是仍把它当成单机病毒:值班人员登录主机逐个杀进程、删除文件、临时改密码;攻击者则通过另一条持久化继续观察处置、窃取新密码并转移到其他系统。
处置必须从单机运维切换为组织级响应。受害主机默认不可信,本机保存的凭据默认可能泄露,与它存在管理或信任关系的资产全部进入排查范围。
本文不提供一份机械的 Linux 命令大全,而是建立一套完整调查方法:
1 | 建立指挥面 → 隔离与保全 → 采集易失证据 → 还原攻击链 → 确认影响面 |
全文只针对 Linux 服务器,适用于物理机、虚拟机、云主机和 Linux 容器宿主机。命令兼顾 Debian/Ubuntu 与 RHEL/Rocky Linux;不同发行版的日志路径和服务名称可能略有差异。
文中命令以使用 systemd 的主流 Linux 发行版为基础,需要经过授权并由具备 root 权限的响应人员执行。lsof、pstree、crictl、debsums 等工具不一定默认安装;不要在失陷主机上临时联网安装工具,应使用事先验证的响应工具包或从外部控制面完成等效采集。涉及服务停止、unit mask、容器缩容的命令会改变现场,必须先保存证据并记录操作。
核心原则:攻击者可能仍在线,证据可能被篡改,影响范围暂时未知。先阻止损失扩大,再通过独立证据还原攻击链,为后续清场、凭据轮换和可信重建提供依据。
一、先建立指挥面:决定谁做什么,而不是所有人一起登录
1.1 建立事件假设和响应边界
响应开始时采用以下假设,直到证据能够逐项排除:
| 默认假设 | 立即产生的行动 |
|---|---|
| root 已被控制 | 不信任本机命令、日志、包数据库和安全工具输出 |
| 攻击者仍有访问能力 | 从外部控制面限制会话,不在受害主机上轮换密码或零散清理 |
| 本机可访问凭据已泄露 | 盘点 SSH 密钥、Token、证书、云角色和服务账号,准备从干净终端撤销 |
| 攻击者已尝试横向移动 | 检查同账号、同公钥、同网段、同镜像和所有管理目标 |
| 数据可能已经外传 | 保存 DNS、代理、流量、对象存储和云审计记录 |
| 日志可能被清理或伪造 | 以集中日志、网络设备、云控制面、内存和离线磁盘交叉验证 |
| 同源部署可能批量中招 | 暂停相关流水线、镜像发布和自动化任务,核验供应链 |
这种响应基线可以避免遗漏仍存活的访问路径。多排查几台关联主机的成本,远低于让攻击者保留一条未发现的回连或信任通道。
1.2 建立三个角色和一份决策记录
即使只有三个人,也应明确角色:
- 事件负责人:确定优先级、批准隔离、协调业务和对外沟通;
- 技术调查人:采集证据、建立假设、还原攻击链;
- 记录人:记录时间、操作者、命令、结果、哈希和每次决策。
避免多人同时登录同一主机。新建 shell、读取文件、运行工具、安装软件和操作服务都可能写入认证或审计日志、更新文件访问时间、改变缓存或产生新文件。没人记录的操作,之后很难与攻击者活动区分。
调查记录应把三种内容分开:
| 类型 | 示例 |
|---|---|
| 事实 | 02:17:43,PID 18422 从 /dev/shm/.cache/kd 运行并连接 203.0.113.10:443 |
| 假设 | 该进程可能是下载器或 C2 客户端 |
| 决定 | 立即从业务网络隔离,仅保留受控取证通道,并并行创建快照和采集内存 |
这种写法可以防止团队把猜测写成结论,也能解释为什么某个时间点隔离主机、撤销凭据或扩大排查范围。
1.3 隔离、快照和取证必须并行启动
处置不能等待完整调查后再隔离。事件负责人应同时启动三个工作流:
- 控制损失:从负载均衡摘除节点,在云安全组、交换机或防火墙侧阻断互联网出口和横向访问,仅保留来源固定、全程审计的取证通道;
- 保全证据:创建云盘或虚拟机快照,采集内存、会话、连接、进程和打开文件,保存集中日志与原始告警;
- 控制身份与供应链:冻结高风险自动化任务,阻断被盗账号的新会话,盘点待轮换凭据,但不把新凭据下发到旧主机。
如果正在加密、删库、擦盘或攻击身份系统,应立即完全断开网络,不为采集等待。若破坏行为暂时稳定,可以保留一个严格限制的取证通道,但不能继续允许业务流量、任意公网出口或对内管理访问。
不要在失陷主机上临时安装大量工具或手工堆叠防火墙规则。外部控制面更可信,也更容易回滚。没有带外通道时,应接受主机暂时失联,而不是为了方便调查继续暴露整个网络。
二、黄金 60 分钟:按照证据消失速度行动
NIST SP 800-86 强调易失数据会随时间变化,采集顺序直接影响调查结果。实际 Linux 响应中,可以把第一个小时拆成三个阶段。
2.1 0—5 分钟:隔离受害面并冻结高风险变更
立即执行:
- 从负载均衡摘除确认失陷的 Linux 节点;
- 在网络或云控制面阻断其公网出口和对内横向访问;
- 对同一异常账号、公钥、镜像或行为链命中的关联主机立即分级;高置信度命中直接隔离,其余限制横向访问并优先调查;
- 暂停向相关主机发布的 CI/CD、配置管理和自动扩缩容任务;
- 保护备份系统,阻止受害账号删除快照或修改保留策略;
- 创建磁盘/虚拟机快照,并保留实例、卷、网卡和安全组元数据;
- 建立独立通信与记录渠道,避免在可能受控的平台讨论驱逐计划。
与此同时,从主机外部保存不易被攻击者控制的数据:
- EDR/NDR 原始告警;
- 防火墙、DNS、WAF、负载均衡和 VPC Flow Logs;
- 云控制面、堡垒机、VPN、统一身份和 CI/CD 审计日志;
- 资产信息、实例 ID、镜像版本、部署记录和最近变更;
- 同一 IP、域名、账号、哈希在其他主机上的命中情况。
然后记录主机时间与身份,避免后续时间线错位:
1 | date --iso-8601=ns |
注意比较主机时间、日志平台时间和告警平台时间。若时间偏移 8 分钟,应在记录中保留这个偏差,不要直接修改系统时钟;改时间本身会污染时间线。
2.2 5—20 分钟:采集最容易消失的现场
建议从可信的只读介质或已验证工具包执行命令,并把输出写到外部证据盘或远端接收端。不要为了排查在受影响主机上临时安装一整套软件,它会新增包、文件、网络连接和日志。以下示例假设 /mnt/ir 是已挂载的可信证据盘:
1 | EVIDENCE_DIR="/mnt/ir/$(hostname)-$(date +%Y%m%dT%H%M%S)" |
第一轮采集关注会话、网络、进程、打开文件和 namespace:
1 | who -a |
这里加入 lsns、systemd-cgls 和 findmnt 很重要。Linux 恶意进程可能位于独立 PID 或 mount namespace 中,宿主机上看到的路径、进程树和容器内并不一致;只检查宿主机默认视图,可能遗漏容器或隐藏挂载中的活动。
若组织具备内存取证能力,应在这一阶段采集内存。内存中可能保留已经删除的可执行文件、解密后的配置、网络会话、命令参数和纯内存载荷。采集工具必须与内核版本兼容,并提前在同类环境验证;不要在事故现场第一次尝试未经验证的内核模块。
2.3 20—60 分钟:建立攻击者证据包并启动全网狩猎
不要立刻全盘扫描。先围绕告警给出的 PID、IP、账号、文件或时间点形成“小而完整”的证据包。
已知可疑 PID 时:
1 | PID=<可疑PID> |
需要同时记录:
- PID、PPID、真实用户、登录 UID、启动时间和父进程;
- 完整命令行、环境变量、工作目录和根目录;
- 可执行文件、映射库、打开文件和网络连接;
- 所属 cgroup、容器和 namespace;
- 文件哈希、包归属、签名或可信基线差异。
若 /proc/<PID>/exe 指向的文件带有 (deleted),说明磁盘目录项已删除,但进程仍持有可执行对象。终止进程前可保留副本:
1 | sudo cp --dereference /proc/$PID/exe "$EVIDENCE_DIR/suspect-$PID.bin" |
environ 可能包含口令、Token 和云凭据,输出必须进入访问受控的证据目录,不要直接粘贴到聊天或工单。样本只在隔离分析环境中处理,不要在生产主机上直接执行。哈希查询、反病毒扫描和沙箱上传还应遵守组织的数据分类要求,内部程序可能包含敏感信息。
2.4 自动化采集:UAC 为主,rkhunter 补充
如果希望“运行一次,把可能与后门有关的现场统一记录下来”,可以使用开源的 UAC(Unix-like Artifacts Collector)。UAC 无需安装,支持 Linux 等 Unix-like 系统,可以按配置文件自动采集运行进程、无磁盘文件的进程、可执行文件哈希、系统与用户配置、日志和文件元数据,并按照易失性顺序执行采集。UAC 官方文档提供了 ir_triage、full 和自定义 artifact 等模式。
UAC 的定位是证据采集器,不是“后门判定器”。它可以把 systemd、cron、SSH、进程、网络、日志和可疑文件等线索收集到同一个归档,但不会证明某个文件一定恶意,也不能证明没有发现结果就代表系统干净。
建议事先在干净环境中下载并验证固定版本,把完整工具目录放入只读响应介质。事故现场不要使用 curl 或 git clone 临时从互联网获取最新版。以可信证据盘 /mnt/ir 为输出目录时,先执行 UAC:
1 | cd /mnt/ir-tools/uac |
其中 ir_triage 适合首轮快速采集,-H 会计算已采集文件的哈希,案件编号、证据编号和采集人会写入采集上下文。完成后还应对最终归档单独计算 SHA-256,并把哈希保存到案件记录:
1 | sha256sum /mnt/ir/uac-* > /mnt/ir/uac-archives.sha256 |
使用时注意:
- 首轮不要启用
--enable-modifiers,它允许执行会改变系统状态的 artifacts; full配置采集量更大,可能产生明显 I/O,应在主机隔离且确认磁盘空间后使用;- 输出必须写到外部证据盘、网络证据库或其他受控位置,不要默认写入受害主机的
/tmp; - UAC 仍通过受害系统执行命令。若存在 Rootkit,输出可能被欺骗,必须与内存、离线磁盘和网络侧日志交叉验证;
- 在投入事故现场前,先在同类 Linux 版本上测试耗时、输出大小和 artifact 覆盖范围。
rkhunter:补充扫描并保存告警
UAC 采集完成并固定归档哈希后,再按需运行 rkhunter。rkhunter(Rootkit Hunter)用于寻找已知 Rootkit 和恶意软件特征、被修改的系统命令与启动文件,以及可疑监听程序等迹象。它只做补充扫描,不代替进程、持久化、内存和离线磁盘分析。
如果 rkhunter 已在事发前部署,或组织的只读响应介质中保存了经过验证的版本和数据文件,可以把完整日志直接写入证据目录:
1 | sudo rkhunter --check --skip-keypress --report-warnings-only --nocolors --nomow --logfile "$EVIDENCE_DIR/rkhunter.log" |
扫描结果中的 Warning 只表示需要继续核实,并不等于已经发现 Rootkit。软件更新、自定义内核、容器环境、特殊权限和管理员修改都可能产生告警,应与发行版软件包、可信镜像和变更记录比较。
事故现场不要执行以下操作:
1 | rkhunter --propupd |
--propupd 会把当前文件属性写入 rkhunter 数据库;如果系统已经失陷,相当于把攻击者修改后的文件登记成新的“正常基线”。--update 会联网并修改本地数据文件,也会污染现场。基线更新只能在已确认干净的系统上进行。rkhunter 手册也明确指出,该工具只能报告文件发生变化,不能判断变化原因,文件是否可信仍由响应人员确认。不要把 rkhunter 的“未发现”结果当作安全证明。
三、不要按目录排查,要沿攻击链追问
一个健全的调查流程不应止于“有没有可疑进程”。应该沿攻击者必须完成的步骤逐段验证:如何进入、如何执行、如何提权、如何驻留、如何取证书和密钥、如何横向移动、如何外传,以及如何掩盖活动。
3.1 初始入口:攻击者第一条可执行路径在哪里
Linux 服务器常见入口可以归为四类:
- SSH、VPN、堡垒机或云控制台凭据被盗;
- 对外服务漏洞、错误配置或 Web 应用命令执行;
- CI/CD、软件包、镜像或自动化账号供应链失陷;
- 已失陷的内网主机使用信任关系横向进入。
SSH 与身份入口
1 | who -a |
Debian/Ubuntu 常见认证日志为 /var/log/auth.log,RHEL 系常见为 /var/log/secure。需要同时检查轮转文件、集中日志、堡垒机和身份提供商记录。
关注登录成功时间、来源地址、账号、认证方式、会话持续时间,以及登录后是否立即发生 sudo、下载、解码或外连。last 依赖的 wtmp 可以被删除或篡改,不能单独作为“无人登录”的证明。
对外服务与 Web 入口
如果可疑 shell 的父进程是 nginx、apache2、httpd、php-fpm、java、python、node 或数据库进程,应反向检查同一秒附近的访问日志、错误日志、反向代理日志和应用审计日志:
1 | 可疑进程启动时间 |
仅仅找到 Webshell 不是根因。还要确认它通过文件上传、模板注入、反序列化、插件漏洞、弱口令还是供应链发布进入,否则清除后仍会复发。
软件包、镜像与自动化入口
检查事故时间窗内的软件安装与部署记录:
1 | # RHEL/Rocky Linux |
主机已失陷时,本机包数据库和历史文件也可能被篡改,因此还要核对镜像摘要、部署流水线、制品仓库下载记录、配置管理平台和自动化密钥使用记录。若同一镜像创建的多台 Linux 主机同时出现相同文件,问题可能发生在构建阶段,而不是单台主机。
3.2 执行:名字可以伪装,运行上下文更难伪装
判断进程时,至少同时看六个属性:
1 | 进程名 + 可执行路径 + 父进程 + 启动时间 + 用户 + 网络/文件行为 |
高风险组合包括:
- 系统风格名称,却从
/tmp、/dev/shm、用户家目录或隐藏目录运行; - Web、数据库或监控进程启动交互 shell;
- 可执行文件已删除,进程仍长期运行;
- 父进程为 cron、未知 systemd unit 或异常容器入口;
- 命令行包含下载后管道执行、编码解码或非常规解释器参数;
- 进程位于陌生 namespace/cgroup,并映射宿主机敏感目录。
对容器宿主机,必须把 PID 映射回容器:
1 | PID=<可疑PID> |
如果使用 Docker、containerd 或 CRI-O,再从对应运行时查询容器 ID、镜像摘要、挂载、特权模式和启动命令。不要只删除容器;如果恶意内容来自镜像或编排配置,新容器会再次生成相同问题。
3.3 权限提升:确认攻击者到达了哪一层信任边界
首先检查账号、sudo、SUID/SGID 和 Linux Capabilities:
1 | getent passwd |
-xdev 只检查根文件系统,不会跨越独立挂载的数据盘、容器存储或网络文件系统。应先用 findmnt 列出挂载点,再根据业务范围对其他本地文件系统分别检查;大范围 find 可能产生明显 I/O,优先在磁盘快照或离线副本上执行。
继续检查:
- sudo/su 日志是否与异常会话吻合;
- 新增 UID 0 账号、组成员或 sudoers 规则;
- 非预期 SUID 文件或
cap_setuid、cap_sys_admin等高风险能力; - Docker/containerd socket 是否被普通账号访问;
- 主机目录、设备或
/proc是否被特权容器挂载; - 内核日志中是否出现崩溃、模块加载、保护机制关闭或提权利用迹象。
“进程当前以 root 运行”并不能单独说明它如何获得 root。需要向前追踪父进程、认证日志、auditd、服务配置、容器权限和漏洞利用时间点。
3.4 持久化:攻击者如何在重启、退出和清理后回来
应按机制而不是只按目录检查。
systemd 与服务管理
1 | systemctl list-unit-files --state=enabled |
不能只检查 .service 文件。攻击者还可能使用 .timer、用户级 unit、drop-in、generator 或修改现有服务的 ExecStart。
Cron、at 与用户级任务
1 | sudo cat /etc/crontab |
crontab -l 只会显示指定用户的任务。还要依据 getent passwd 枚举可登录账号,检查其用户 crontab;不要只看 root。
SSH 公钥与账号后门
真正决定谁能使用公钥登录本机的通常是 authorized_keys,而不是 known_hosts:
1 | sudo find /root /home -type f -path '*/.ssh/authorized_keys' -printf '%TY-%Tm-%Td %TH:%TM:%TS %u %m %p\n' 2>/dev/null |
MITRE ATT&CK T1098.004 将修改 authorized_keys 作为 Linux 持久化的重要方式。还应检查 sshd_config 的 Include 文件、AuthorizedKeysCommand、账号家目录权限,以及云平台通过实例元数据下发 SSH 公钥的记录。
PAM、启动链和动态链接器
1 | sudo stat /etc/rc.local /etc/ld.so.preload 2>/dev/null |
高权限事件还应检查内核模块、initramfs、udev 规则、包管理 hooks、动态链接器配置和安全模块状态。若这些信任根被改动,不应依赖手工清理恢复可信。
3.5 木马杀掉又启动:不要和子进程玩“打地鼠”
一个恶意进程被终止后几秒或几分钟再次出现,说明背后存在负责拉起它的机制。反复执行 kill -9 只会不断销毁当前进程的内存、连接和父子关系,真正的启动源仍然存在。
常见拉起源包括:
| 重启特征 | 可能的启动源 |
|---|---|
| 退出后立即出现,PID 改变 | systemd 的 Restart=、Supervisor、Monit、runit、s6 或 shell watchdog |
| 每分钟、每小时或固定时间出现 | cron、systemd timer、anacron、at |
| 容器停止后自动创建或重新运行 | Docker restart policy、Kubernetes Deployment/DaemonSet、容器编排控制器 |
| 用户退出后仍会启动 | user systemd unit、linger、用户 cron、shell 初始化文件 |
| 重启主机后早期出现 | initramfs、system service、udev、启动脚本、内核模块 |
| 各工具看到的 PID、端口或文件不一致 | namespace 隔离、用户态 Hook、Rootkit 或系统工具被替换 |
第一步:保留一次完整生命周期
先隔离网络,防止木马继续接收命令或外传数据。不要马上终止新进程,先记录它从哪里来:
1 | PID=<可疑PID> |
重点记录旧 PID 的退出时间、新 PID 的出现时间、PPID、可执行路径和 cgroup。优先利用现有日志、EDR 和 systemd 记录还原“退出—重新生成”过程;不要为了观察而主动杀死进程。若完成证据采集后因止损必须终止,再监控它是否重新生成。
如果木马仍在执行破坏操作,可以在网络已经隔离的前提下使用 SIGSTOP 暂停进程,保留其内存和打开文件:
1 | sudo kill -STOP "$PID" |
暂停不是清除,也不能阻止其他副本运行。完成必要采集后,仍要处理启动源和整条进程树。
第二步:定位真正的拉起者
如果进程属于 systemd unit:
1 | systemctl status "$PID" --no-pager |
如果重启有固定周期,检查 timer 与 cron:
1 | systemctl list-timers --all |
如果父进程是守护或进程管理工具:
1 | ps -ef | grep -E '[s]upervisord|[m]onit|[s]6-svscan|[r]unsv|[p]m2|[f]orever' |
如果进程位于容器:
1 | cat /proc/$PID/cgroup |
继续从可信管理端检查容器的 restart policy、Kubernetes Deployment、DaemonSet、StatefulSet 和静态 Pod。只在节点上 kill 容器进程没有意义,控制器会按期望状态重新创建它;必须隔离节点,并在编排层停止控制器、封禁恶意镜像和修复工作负载配置。
用户级 systemd 也容易被漏掉:
1 | loginctl list-users |
如果 pstree 显示由 bash、sh 或脚本循环拉起,应沿 PPID 一直向上追踪,保存整个祖先进程的命令行、工作目录、打开文件和脚本内容。不要只杀最末端的木马进程。
第三步:保留证据后阻断重启链
先保存 unit、cron、脚本、容器配置、日志和样本,并计算哈希。随后根据拉起源执行阻断:
- systemd:停止并在当前启动周期临时 mask 对应 unit,防止再次启动;
- cron/timer:禁用具体恶意条目,不要无差别停止全部业务定时任务;
- Supervisor/Monit/runit/s6:停止对应任务并隔离其配置与执行文件;
- Docker/Kubernetes:从编排层缩容或停止控制器,取消 restart policy,隔离节点和镜像;
- shell watchdog:在采集后终止负责循环的祖先进程及其子树;
- 内核模块、initramfs、PAM 或 Rootkit:保持网络隔离,完成内存和磁盘采集后关闭旧主机,不再尝试原地修复。
systemd 的临时阻断示例:
1 | sudo systemctl mask --runtime --now <可疑unit> |
该操作会改变现场,必须在证据保存后执行并记录时间、操作者和命令。旧主机最终仍按可信重建流程处理。
第四步:证明它没有从另一条通道回来
攻击者经常同时设置两种以上持久化。阻断一个 unit 后,至少继续检查:
- 是否在已知重启周期内产生新 PID;对 timer/cron 还要覆盖其最长已知周期;
- 同一哈希、文件路径、命令行和网络目标是否再次出现;
- 是否换成另一个账号、容器、unit 或临时目录运行;
- systemd、cron、用户 unit、SSH 公钥、PAM 和内核模块是否还有第二条入口;
- 网络侧是否仍有来自该主机或关联主机的相同 Beacon。
“进程不见了”只能证明当前副本停止,不能证明持久化已经清除。旧主机应继续隔离,其结果只用于调查,不能作为系统已经恢复可信的证明。
3.6 凭据访问与横向移动:一台主机可能只是跳板
Linux 主机常保存比自身权限更有价值的凭据:SSH 私钥、Agent 转发会话、云实例角色、Kubernetes kubeconfig、数据库口令、CI/CD Token、备份密钥和服务账号配置。
调查目标不是把所有秘密打印出来,而是确认哪些秘密可能被读取或使用:
- 可疑进程打开过哪些密钥、配置和 socket;
- auditd 是否记录对敏感文件的访问;
- 事故期间是否存在异常
ssh、scp、sftp、rsync或远程管理进程; known_hosts、SSH 配置和运维脚本暴露了哪些潜在横向目标;- 同一账号或密钥是否在其他 Linux 主机出现新会话;
- 云审计日志是否出现异常角色调用、快照、密钥或安全组操作。
known_hosts 只能证明该账号曾见过某个远端主机身份,不能证明登录成功,也不能代替网络和认证日志。
由于主机已经确认失陷,应假设攻击者能够读取该主机可访问的凭据。后续撤销与轮换必须在干净设备上进行,并按依赖关系排序,避免新凭据再次同步到受控主机。
3.7 C2、数据外传与防御规避:攻击者做了什么,带走了什么
从主机侧查看实时连接只是第一步:
1 | ss -Hantup |
还要从 DNS、防火墙、代理、流量日志和云网络日志检查:
- 周期固定、流量很小的 Beacon;
- 与新注册域名、动态 DNS、代理或匿名网络的通信;
- 非业务时间的大规模上传;
- DNS 查询量、子域长度或失败率异常;
- 主机突然扫描大量内网地址或管理端口;
curl、wget、nc、socat、ssh、rclone等工具与异常时间线重合。
数据外传之前常有归档和暂存。应围绕时间窗检查新增的大文件、压缩包、数据库导出和临时目录,但不能仅凭扩展名下结论:
1 | sudo find /tmp /var/tmp /dev/shm /root /home -xdev -type f -newermt '<开始时间>' ! -newermt '<结束时间>' -printf '%TY-%Tm-%Td %TH:%TM:%TS %u %s %p\n' 2>/dev/null |
防御规避常见信号包括:
- 日志在关键时间段突然中断或轮转规律异常;
- 文件时间早于软件部署时间,或多个文件时间完全相同;
/proc/<PID>/exe显示(deleted);- 进程、端口或文件在不同工具中结果不一致;
- auditd、SELinux/AppArmor、EDR 或防火墙被停止;
/etc/ld.so.preload、PAM、内核模块或 namespace 出现异常。
必须把 Rootkit 和系统工具篡改纳入威胁模型。本机 ps、ss、ls、包数据库乃至内核接口都可能说谎,因此活系统结果只能作为线索,关键结论必须用内存镜像、离线磁盘、网络侧记录和可信基线交叉验证。
四、从“确认失陷”到“掌握全貌”:建立可验证的时间线
4.1 先确定锚点,再向两侧扩展
不要一开始就读取几个月的全部日志。先选一个可靠锚点,例如:
- EDR 记录的进程启动时间;
- 防火墙记录的首次外连;
- SSH 登录成功时间;
- Web 请求返回异常响应的时间;
- 文件首次出现在制品或备份中的时间。
以锚点前后 15—30 分钟为窗口,关联 Journal、认证、auditd、应用、DNS 和网络记录:
1 | journalctl --list-boots |
systemd 服务名因发行版而异,例如 ssh/sshd、cron/crond。传统日志还可能位于 /var/log/auth.log、/var/log/secure、/var/log/syslog、/var/log/messages、/var/log/cron 和 /var/log/audit/audit.log。
systemd 的 journalctl 文档 支持按时间、启动批次、unit、PID 和可执行文件过滤。若 Journal 未配置持久化,重启前的日志可能只存在于 /run/log/journal/,重启后无法恢复。
ausearch 接受的绝对日期格式受系统区域设置影响,执行前应以本机 man ausearch 或 ausearch --help 为准。不要为了方便关联而修改受害主机时间,应在时间线中记录时钟偏差并统一换算。
4.2 用假设驱动调查,而不是见到什么查什么
每一轮调查都应写出可证伪的假设:
1 | 假设:攻击者通过被盗 SSH 密钥登录 deploy 账号,随后 sudo 到 root。 |
如果证据推翻假设,就更新方向。不要因为最初告警写着“挖矿木马”,后续所有异常都被强行解释为挖矿。
4.3 给证据标置信度
不同来源的可信度不同:
| 证据来源 | 一般置信度 | 主要限制 |
|---|---|---|
| 独立网络设备、云控制面、集中日志 | 较高 | 保留期、采样、时钟偏差 |
| EDR 原始遥测 | 较高 | Agent 可能被停止或绕过 |
| 内存镜像、离线磁盘镜像 | 较高 | 采集时间和工具正确性 |
| 受影响主机上的 Journal/auditd | 中等 | root 可清理或篡改 |
history、last、文件时间戳 |
较低到中等 | 易缺失、延迟落盘或伪造 |
| 单一杀毒标签或文件名 | 较低 | 误报、伪装和命名不一致 |
结论应尽量由两个相互独立的来源支持。例如,本机 ss 显示外连,同时防火墙日志也记录同一五元组;authorized_keys 出现新公钥,同时 auditd 记录写入行为。
4.4 影响面确认不能只查最初那台主机
从已确认 IOC 和行为模式向外扩展:
- 同一 IP、域名、URL、证书、哈希和文件路径;
- 同一账号、SSH 公钥指纹、Token 或云角色;
- 同一镜像、软件版本、部署流水线和配置模板;
- 同一父子进程关系、命令行和 systemd unit;
- 同一入口漏洞和对外暴露方式。
IOC 适合快速筛查,但攻击者可以更换文件名和地址。行为搜索通常更稳健,例如“Web 服务启动 shell 后访问公网”“root 向非预期账号写入 authorized_keys”“新 systemd timer 执行用户目录文件”。
4.5 用调查结果形成处置输入
隔离不需要等待所有问题都有答案,但后续清场不能只凭一份恶意文件列表开始。调查阶段至少要交付以下结果:
| 交付物 | 必须包含的内容 |
|---|---|
| 攻击时间线 | 首次已知活动、登录、执行、提权、持久化、横向移动、外联和关键处置时间 |
| 资产范围表 | 已确认失陷、疑似受影响和暂未发现异常的主机,以及各自判定依据 |
| 身份暴露表 | 可能泄露的账号、SSH 密钥、Token、证书、云角色和它们可访问的系统 |
| 持久化清单 | unit、timer、cron、用户服务、容器控制器、脚本、PAM 或内核级机制 |
| 数据影响说明 | 被访问、暂存或可能外传的数据,证据来源及结论置信度 |
| 证据索引 | 文件名、来源主机、采集时间、采集人、SHA-256 和保存位置 |
进入下一阶段前,团队应能回答:攻击者从哪里进入、何时取得 root、通过什么机制持续运行、哪些凭据可能泄露、触达了哪些主机、是否访问或外传数据,以及还有哪些结论无法证实。
无法回答的问题不能被省略,应作为明确的调查缺口记录。这样后续处置针对的是已知入口、持久化和信任关系,而不是只把当前看得见的木马进程删除。