← 返回 Day 160 正文

Day 160 · 练习与清单

Day 160 — 完成清单与练习题(日志安全分析)

全部操作在授权环境进行:只分析你自己拥有或已获授权的日志。 分析器只读日志文件,不修改日志、不发起任何网络请求、不构造任何攻击请求。 练习中使用的 IP 一律为文档示例段(203.0.113.0/24、198.51.100.0/24、192.0.2.0/24)。

一、完成清单(先跑通,再做题)

二、基础练习

  1. 加一个日志格式:为 log_core 增加 parse_windows_event, 支持形如 2026-09-19T06:12:01+08:00 win-dc01 Security 4625 An account failed to log on (user=admin, ip=203.0.113.7) 的一行日志。要求:detect_source 能识别它,01-log-parser.py --self-test 仍通过。

  2. 时间戳边界:构造 3 条没有时间戳、但动作是 login_failed 的日志, 验证它们被计入 no_timestamp 且不产生任何 brute_force_* 告警。 解释:如果把它们的时间"猜"成文件修改时间,会引入什么错误结论?

  3. 跨主机不混淆:同一 IP 分别在 web01 失败 6 次、web02 失败 6 次, 阈值分别设为 8 和 10,验证两种设置下都不告警;再把两台机器合并成 "一台机器被打了 12 次"的假数据,观察告警出现。写一句结论。

  4. 滑动窗口 vs 分桶:把 9 次失败安排在 00:59 与 01:01 两个整分桶里 (各 4~5 次),证明滑动窗口仍然告警,而"整分桶计数"不会。 说明为什么攻击者会利用分桶边界。

  5. 去重实验:把同一行日志复制 20 份,确认 coverage.deduped == 19 且告警次数不受影响。解释日志重采/轮转边界为什么会产生重复行。

三、进阶挑战

  1. 检测器的精度与召回:构造 4 组带标签的合成日志 (正常值班登录 / 本人连错口令 / 真实爆破 / 分布式爆破), 统计每个检测器的误报与漏报,把结果写进一张表。结论必须包含 "哪些检测器在没有值班表的情况下无法降低误报"。

  2. 阈值敏感性分析:对 brute_threshold 取 3/5/8/12/20, 画出(或打印)"阈值 → 告警数"曲线,找出"再放宽 1 个单位就会漏掉 真实攻击"的临界点,并说明这个临界点依赖数据,不能写死在文档里。

  3. 可判定性声明:给 03-log-analyzer.py 增加一个 --strict 开关: 当 coverage.complete == False 时直接拒绝输出结论(只输出缺口清单)。 讨论:这个开关在 CI 里应该默认开还是默认关?为什么?

  4. 报告脱敏边界:当前只掩码 IP 末段,但用户名是明文。 设计一个方案:对外报告里用户名如何处理(掩码?哈希?保留?), 并说明该方案对"复核人员需要定位到人"这个需求的影响。

  5. 时间基准问题:日志时间来自被分析主机,可能被篡改或被 NTP 偏移。 设计一个"时间可信度"检查:至少给出两个可用信号 (提示:与本机 wall clock 的偏差、日志内部单调性、乱序比例), 并说明发现偏差后报告应该怎么写。

四、验收命令

bash
cd ~/code/Learn-Python
D=days/day-160-日志安全分析/code
python3 $D/01-log-parser.py --self-test
python3 $D/02-detectors.py --self-test
python3 $D/03-log-analyzer.py --self-test
python3 $D/03-log-analyzer.py lab
python3 $D/03-log-analyzer.py lab --dirty

前三条必须输出 SELF-TEST OK;lab 退出码 3,lab --dirty 退出码 4。

五、思考题(写在笔记里)