← 返回 Day 161 正文

Day 161 · 练习与清单

Day 161 — 完成清单与练习题(渗透测试框架)

全部操作只在授权环境进行:本课所有实验都在 127.0.0.1 的回环实验服务上完成。 框架只读探测(TCP connect + 读取服务主动发来的 banner), 不发送任何数据、不做爆破、不做利用、不改动目标任何内容。 练习里出现的地址一律是回环地址或文档网段(RFC 5737:203.0.113.0/24、 198.51.100.0/24、192.0.2.0/24)。

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

二、基础练习

练习 1:给范围加上"授权时间窗"

当前 Scope 有 expires 字段,但没有"生效时间"(not_before)。 请增加 not_before 字段并让 Scope.check 在"尚未生效"时也抛 AuthorizationError。要求:

提示:datetime.fromisoformat() 对无时区字符串会给出 naive datetime, 要像 expired() 那样显式补时区,否则比较会抛 TypeError。

练习 2:让报告显示"每个端口的状态"

当前报告只列 open 的资产,closed/filtered 只在统计里出现数量。 请给 render_markdown 增加一节"全部目标明细",按 host 分组输出:

127.0.0.1
  8000  open     ssh     SSH-2.0-OpenSSH_8.9p1…
  8001  closed   -       -
  8002  filtered -       -

要求:filtered 行必须在末尾加 (不可判定) 标记。写完后跑 lab 验证。

练习 3:实现"服务指纹"插件

新增插件 tls_hint(priority=35):对 443/8443/9443 这类端口, 若 connect 成功但 没有 返回明文 banner,则产出一条 severity="info", confidence="low" 的 Finding,说明"疑似 TLS 服务(需握手确认)"。

关键要求:不要真的发起 TLS 握手(那会发送数据,超出本课"只读"边界)。 只在报告里标注"需要人工验证"。这正是框架中"推断层"与"结论层"的边界示例。

练习 4:黑名单优先的边界测试

构造一个范围:networks=["127.0.0.0/29"]、excluded=["127.0.0.1/32", "127.0.0.4/31"]。 列出 127.0.0.0/29 里被允许的主机,并解释为什么 127.0.0.1 即使同时出现在白名单里也必须被拒绝。写一句给"非技术同事"的解释。

练习 5:把三态统计做成"结论可信度"评分

定义一个 0–100 的可信度分数:

可信度 = 100 × 可判定目标数 / 总目标数

在报告顶部输出该分数,并在 filtered 占比 > 30% 时强制加一行警告: "本次结论可信度不足,建议更换网络路径复测"。写自检覆盖两种情况。

三、进阶挑战

练习 6:插件依赖的显式声明(替代隐式 priority)

当前插件顺序靠 priority 数字约定,属于隐式依赖。请改造成声明式依赖:

python
@fw.plugin("version_disclosure", priority=30, requires=["banner_evidence"])

要求:

讨论:为什么"声明式依赖"比"数字优先级"更难写错?它又引入了什么新成本?

练习 7:把 authorize 做成签发前的"边界报告"

authorize 目前只在通过时打印前 20 条目标。请改造为输出一份边界报告:

思考:为什么这份边界报告应该在扫描之前发给客户确认?

练习 8:并发下的"礼貌退避"(backoff)

当连续出现多个 filtered 时,说明链路在丢包。请实现自适应退避:

写自检:构造一个全部 filtered 的场景,断言 rate 至少被调整过一次。

练习 9:给框架加"离线重放"能力

扫描结果已存进 out/*-report.json,但审计日志是独立文件。 请实现 replay 子命令:读审计日志,不发起任何连接, 重建"阶段 → 资产 → 发现"的全过程并打印时间线。

为什么值得做:复核、教学、事故复盘都需要"重放"; 而重放必须是离线的,否则"复核一次"就等于"再扫一次"(可能超出授权窗口)。

练习 10:写一份"能力与局限"声明模板

为框架写一份给客户看的声明(一页以内),必须包含:

要求:不出现"确保安全""彻底扫描"这类无法兑现的措辞。

四、验收命令

bash
cd ~/code/Learn-Python
D="days/day-161-渗透测试框架/code"
python3 "$D/pentest_core.py" --self-test
python3 "$D/01-scan-engine.py" --self-test
python3 "$D/02-framework-advanced.py" --self-test
python3 "$D/03-pitfalls.py" --self-test
python3 "$D/04-pentest-framework.py" --self-test
python3 "$D/04-pentest-framework.py" lab --ports 8000-8080 --rate 500
python3 "$D/04-pentest-framework.py" authorize --hosts 127.0.0.1 --ports 8000-8002
python3 "$D/04-pentest-framework.py" scan --hosts 10.0.0.5 --ports 8000   # 期望退出码 2

前五条必须输出 SELF-TEST OK;lab 退出码 3;越界 scan 退出码 2。

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