回溯凌晨三点的那一小时
目标
拿到一起事件的四类资料,把调查完整走一遍:清点、挑出、保全、编成时间线、抓住分析支点一路追到集群、确定措施顺序,并撰写事后分析报告。
为什么重要
告警响起后的 30 分钟里做什么,决定了这次事件的结局。急着删 Pod、重启节点,入侵路径会随之消失;反过来,在完美收集证据的期间,泄露的凭据又会让另一个命名空间被攻破。
所以响应不是“什么是对的”的问题,而是“先做什么”的问题,而且这个顺序必须在事件发生之前定好。先收集易失性大的,不动原件,时间统一用 UTC,凭据撤销不要拖——这些规则,全都是有人丢过一次东西之后才产生的。
本实验的资料是合成的。但格式与真实的一样。直接使用 Falco 的 JSON 输出、内核审计的原始记录、journalctl -o json 的字段和 Kubernetes 审计事件。
步骤
- 统计四类资料的行数,保存到
/root/ir/01-sources.tsv。 - 把最早的 Falco 告警的规则名称、时间和 PID 保存到
/root/ir/02-first.json。 - 把四类资料复制到
/root/ir/evidence/,并留下manifest.sha256。 - 把四个来源放到同一条时间轴上的时间线,在
/root/ir/04-timeline.tsv中写 8 行以上。 - 把四个分析支点(
pid、cron-file、c2-host、k8s-identity)以值和依据写到/root/ir/05-pivot.tsv。 - 把六项措施的时点和依据写到
/root/ir/06-containment.tsv。 - 把被盗用的身份在集群中做过的事写到
/root/ir/07-k8s.tsv。 - 把事后分析报告写到
/root/ir/08-postmortem.md。
参考
- 资料在
/opt/lab/fixtures/detection/incident/下:falco.jsonl、audit.log、cron.jsonl、kube-audit.jsonl。另外还有不是日志的参考资料host-facts.json。 - 第 4 步的来源名称写成
falco、auditd、cron、kube-audit四者之一。时间的形式为2026-03-14T03:00:04Z。 - 第 6 步的措施名称有六个:
메모리 수집、네트워크 차단、프로세스 종료、예약 작업 제거、자격증명 폐기、노드 재설치(韩文,依次意为“内存收集”“网络阻断”“进程终止”“计划任务移除”“凭据撤销”“节点重装”),时点是지금、나중、안함(韩文,依次意为“现在”“以后”“不做”)之一。 - 第 7 步中,被拒绝(403)的请求也是行为。不要漏掉。
- 常见错误:内核审计原始记录的时间是纪元秒。请用
date -u -d @<초>(占位符为秒数)转换。 - 常见错误:用编辑器打开原始文件并修改。原件要按只读处理,只看副本。
清点有什么
统计 /opt/lab/fixtures/detection/incident/ 中 falco.jsonl、audit.log、cron.jsonl、kube-audit.jsonl 四个文件的行数,按每个文件一行的形式以 파일이름<탭>줄수(占位符依次为文件名、制表符、行数)保存到 /root/ir/01-sources.tsv。
用 wc -l 即可。调查中如果跳过这一步,以后就会冒出“原来还有那份日志”。
挑出最初的告警
在 falco.jsonl 中找到最早的告警,把规则名称、时间和 PID 以 {"rule": …, "time": …, "pid": …} 的形式保存到 /root/ir/02-first.json。
用 jq -s 'min_by(.time)' 可以选出最早的一条。PID 在 output_fields 中。时间直接使用文件中写的值。
不动原件地保全
把四类资料复制到 /root/ir/evidence/,并创建能在该目录下用 sha256sum -c 验证的 /root/ir/evidence/manifest.sha256。
sha256sum <파일들> > manifest.sha256(占位符为各个文件)要写成相对路径。验证要在该目录中用 sha256sum -c manifest.sha256 进行。
放到同一条时间轴上
把四个来源的记录按时间升序写到 /root/ir/04-timeline.tsv,至少 8 行,每行四栏:시각<탭>출처<탭>행위자<탭>무슨 일(占位符依次为时间、制表符、来源、制表符、行为者、制表符、发生了什么)。四个来源必须都至少出现一次。
来源名称统一为 falco、auditd、cron、kube-audit。内核审计原始记录的纪元秒用 date -u -d @<초> +%Y-%m-%dT%H:%M:%SZ(占位符为秒数)转换。journald 的 __REALTIME_TIMESTAMP 是微秒。
抓住支点并跳转
在 /root/ir/05-pivot.tsv 中写四行,格式为 축<탭>값<탭>근거(占位符依次为分析支点、制表符、值、制表符、依据)。分析支点名称是 pid、cron-file、c2-host、k8s-identity,依据栏要用 10 个字符以上写明根据哪个文件的什么做出了这样的判断。
pid 是在临时目录中执行的进程的 PID。cron-file 是当晚新出现的计划任务,在内核审计原始记录的 PATH 记录中。k8s-identity 是审计日志中的 user.username。
先做什么
把六项措施按 조치<탭>시점<탭>근거(占位符依次为措施、制表符、时点、制表符、依据)的格式写到 /root/ir/06-containment.tsv。时点是 지금、나중、안함(韩文,依次意为“现在”“以后”“不做”)之一,依据要 20 个字符以上。
先收集易失性大的。另外有一样东西即使关掉节点仍然有效——它不能拖。
被盗用的身份在集群里做了什么
在 kube-audit.jsonl 中找出 system:node:edge-07 发出的全部请求,以 verb<탭>리소스<탭>네임스페이스<탭>이름<탭>응답코드(占位符依次为 verb、制表符、资源、制表符、命名空间、制表符、名称、制表符、响应码)五栏写到 /root/ir/07-k8s.tsv。命名空间或名称为空时写 -。
用 jq -r 'select(.user.username == …)' 过滤。被拒绝的请求(403)也是行为——试图做什么,说明了意图。
改变下周的文章
在 /root/ir/08-postmortem.md 中写六节:## 요약、## 타임라인、## 영향、## 원인、## 탐지 공백、## 재발 방지(韩文,依次意为“摘要”“时间线”“影响”“原因”“检测缺口”“防止再次发生”)。正文中必须出现命令与控制(C2)地址、使用了凭据的命名空间、被捕获的持久化手段的路径。
## 탐지 공백(韩文,意为“检测缺口”)是这份报告中最重要的一节。是没有规则,还是告警发到了没人看的地方,抑或日志本身就不存在,会导向完全不同的处方。以人名收尾的报告,下周会招来同样的事故。