suhelkathi/hostsweep
GitHub: suhelkathi/hostsweep
一款 Host header 注入扫描器,通过基于 canary 值的两轮确认机制实现低误报率的 Web 应用信任检测。
Stars: 1 | Forks: 0
# HostSweep
一款 Host header 注入扫描器,专注于准确且基于确认的检测。
HostSweep 用于测试 Web 应用程序是否信任客户端提供的 host 信息,
并将其反射到与安全相关的位置。只有在响应中明确证明了被注入的 canary 值发生反射时,
它才会报告该发现,这使得误报率足够低,从而能够直接在实际测试中使用这些结果。

## 检测方法
每个候选 header 都会被注入一个唯一的 canary 值。只有当该确切的 canary 出现在响应中时(无论是在重定向目标、HTML 属性、响应主体还是 `Set-Cookie` 值中),才会记录一次发现。
反射即被视为确认;间接或行为信号会单独报告,绝不会计入已确认的发现中。
扫描分两轮进行:
1. **分诊。** 所有候选 header 都会在单个请求中发送,每个 header 携带一个不同的 canary。发生反射的 canary 可以准确识别出服务器信任哪个 header,而这仅需使用一个请求。
2. **确认。** 在分诊阶段发生反射的每个 header 都会被重新独立测试,并使用一个新的 canary,以排除同时发送多个 header 带来的干扰。只有再次发生反射的 header 才会被报告。
对于每次确认的反射,HostSweep 还会提取**返回的确切值**,并分类判断攻击者是否仍然控制最终的 host:
- **exact** — 值原封不动地返回(完全控制)。
- **prefixed** — 服务器在前面添加了标签,例如 `evil.com` 返回为 `fr.evil.com`。该 host 仍然会解析到攻击者的域,因此这仍然是可利用的,并会相应地进行评分。
- **wrapped** — 服务器附加了后缀,例如 `evil.com` 返回为 `evil.com.trusted.com`。有效的 host 不再受攻击者控制,因此这会被降级为信息性说明,而不是作为漏洞报告。
这种区别正是防止“已修改但不受控制”的反射被作为误报报告的原因。
实时输出流:每个目标一旦完成就会立即打印出来,并带有进度计数器;此外,`-v` 会在扫描运行时添加针对每个 header 的追踪记录。
## 测试的 Headers
`X-Forwarded-Host`, `X-Forwarded-Server`, `X-Host`, `X-HTTP-Host-Override`,
`X-Original-Host`, `X-Original-URL`, `X-Rewrite-URL`, `Forwarded`,
`X-Forwarded-For`,以及伪造的 `Host` 值。
## 严重性模型
| 反射位置 | 严重性 | 理由 |
|--------------|----------|-----------|
| 重定向 `Location`(受攻击者控制) | 高 | 开放重定向;潜在的密码重置投毒 |
| `Set-Cookie` domain(受攻击者控制) | 高 | Cookie 作用域或固定 |
| HTML 属性(`href`/`src`/`action`) | 中 | 可能加载受攻击者控制的内容 |
| 响应主体(受攻击者控制) | 中 | 确认该值到达了与安全相关的 sink |
| 缓存响应(使用 `--cache`) | 严重 | 影响其他用户的 Web 缓存投毒 |
| 发生反射但属于 `wrapped`(不受攻击者控制) | 信息 | 值被修改为非攻击者的域;可能无法利用 |
“高”和“中”级别的发现要求被反射的 host 仍然保持受攻击者控制的状态(`exact` 或 `prefixed`)。`wrapped` 反射仅作为信息性说明报告。
使用伪造 Host 带来的行为改变(但没有发生反射)将作为供人工审查的备注进行报告,而不是作为已确认的发现。
## 安装
```
git clone https://github.com/suhelkathi/hostsweep
cd hostsweep
pip install -r requirements.txt
```
## 用法
```
# 单个 target
python3 hostsweep.py -u https://target.com
# 已认证 test
python3 hostsweep.py -u https://target.com/account -c "session=..."
# 扫描列表,包含 cache poisoning 检查,导出 JSON
python3 hostsweep.py -l hosts.txt --cache --json results.json
# 通过 Burp 路由
python3 hostsweep.py -u https://target.com -k --proxy http://127.0.0.1:8080
```
## 选项
| 标志 | 描述 |
|------|-------------|
| `-u` / `-l` | 单个 URL 或包含 URL 的文件 |
| `-c` | 用于经过身份验证的扫描的 Cookie header |
| `-H` | 额外的请求 header,可重复使用 |
| `-v` | 扫描时实时的针对每个 header 的追踪 |
| `--cache` | 运行 Web 缓存投毒检查 |
| `-t` | 并发数(默认为 15) |
| `--proxy` | 通过 Burp 等代理发送流量 |
| `-k` | 跳过 TLS 验证 |
| `--json` / `--csv` | 机器可读的输出 |
| `--only-vuln` | 仅显示高/严重级别的发现 |
当存在任何高或严重级别的发现时,进程会以退出代码 2 退出,这对于 CI 流水线非常方便。
## 手动确认
```
curl -s -I https://target.com \
-H "X-Forwarded-Host: canary.example.com" | grep -i location
```
如果注入的 host 出现在 `Location` header 或生成的链接中,则说明应用程序信任客户端提供的 host 信息。要了解重置投毒的影响,请触发密码重置流程并检查生成的链接。
## 范围与限制
反射证实了某个 header 受到信任,但并非每次反射都能被独立利用。诸如密码重置投毒等高影响案例需要带外验证(例如,读取重置邮件),这是自动化扫描器无法观察到的。HostSweep 旨在精准地呈现已确认的反射,并将最后的验证留给测试人员。
## 法律声明
仅对您获得明确授权进行测试的系统使用。
## 许可证
MIT
标签:CISA项目, HTTP头部注入, Web安全, 蓝队分析, 逆向工具