IceCubeSandwich/CaddySmith
GitHub: IceCubeSandwich/CaddySmith
CaddySmith 从 Cobalt Strike 或 Sliver 的 C2 配置文件自动生成带有流量过滤和反侦察功能的 Caddy 重定向器配置。
Stars: 23 | Forks: 0
# CaddySmith
我写这个工具是因为 Caddy 是一个比 Apache 更容易快速搭建的 Web 服务器,它是一个单一静态二进制文件,支持自动 Let's Encrypt 证书,而且不需要折腾 `a2enmod`。
## 支持的 Profile 格式
CaddySmith 会根据文件内容自动检测格式:
- **Cobalt Strike** — 带有 `set uri "/foo"` 指令的经典文本格式。每个 HTTP-GET / HTTP-POST URI 都会成为各自独立的精确路径路由,并强制执行 profile 中的客户端 header。
- **Sliver** — 从 Sliver 导出的 JSON implant 配置。Sliver 没有固定的 URI;它会在构建 beacon 时根据路径 / 文件 / 扩展名列表生成它们。CaddySmith 通过将顶级路径前缀作为 glob 进行匹配(例如 `path /api* /static* /resources*`)并对来自 UA 的 Chrome 构建版本号进行子字符串匹配(这能在 Sliver 针对不同平台的 UA 重写中保留下来)来处理这个问题。
你也可以使用 `--profile-type cobaltstrike` 或 `--profile-type sliver` 强制指定特定的解析器。
## 它的功能
给定一个 profile 文件,脚本会提取以下内容:
- User-Agent 字符串
- URI (CS) 或路径前缀 (Sliver)
- 客户端 header(仅限 CS — Sliver 不强制指定特定的 header)
- Host header(如果你不传递 `--server-name`,则用作重定向器的域名)
- 是否启用 Staging(仅限 CS — `set host_stage`)
然后它会构建一个 Caddyfile,执行以下操作:
1. (可选)向纯 HTTP 流量返回 403
2. 屏蔽约 15 个已知的恶意 User-Agent(curl, nmap, sqlmap, Googlebot 等)
3. 屏蔽直接 IP 访问以及任何非 GET/POST 的 HTTP 方法
4. 仅反向代理 profile 中的 URI(或针对 Sliver 的前缀),并根据匹配的 User-Agent 进行控制
5. 屏蔽常见的扫描器探测路径(`.env`, `/wp-admin`, `.php` 等)
6. 将其他所有流量重定向到你的诱饵 URL
## 环境要求
- Python 3.7+(仅使用标准库,无需 `pip install`)
- 重定向器本身需要 Caddy 2.x([安装指南](https://caddyserver.com/docs/install))
## 快速开始
```
python3 caddysmith.py my.profile \
--backend https://teamserver.internal:443 \
--decoy https://www.example.com/ \
--server-name redirector.example.com \
--email you@example.com \
--forbid-http \
-o redirector.caddy
```
这会将生成的配置写入 `redirector.caddy`,并将它所执行操作的摘要打印到 stderr。
## 部署生成的配置
### 选项 A:直接运行 Caddyfile
将生成的文件复制到重定向器并运行 Caddy。你需要使用 `--adapter caddyfile` 标志,因为 Caddy 默认使用 JSON 配置:
```
caddy run --config /etc/caddy/redirector.caddy --adapter caddyfile
```
要使用更新后的配置重载正在运行的实例:
```
caddy reload --config /etc/caddy/redirector.caddy --adapter caddyfile
```
如果 Caddy 警告格式不一致,请使用以下命令进行清理:
```
caddy fmt --overwrite /etc/caddy/redirector.caddy
```
### 选项 B:从主 Caddyfile 导入
将该文件放在 `/etc/caddy/` 中,并从你的主 Caddyfile 导入它:
```
# /etc/caddy/Caddyfile
import /etc/caddy/redirector.caddy
```
如果你传递了 `--email`(推荐),生成的代码片段已经包含了全局选项块,因此主 Caddyfile 只需要 `import` 行。如果你没有传递,请手动将 email 添加到 import 上方的 `{ }` 块中。
然后验证并重载:
```
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
```
只要 A 记录指向重定向器,Caddy 就会自动为 `--server-name` 中的域名签发 Let's Encrypt 证书。
## 所有标志
| 标志 | 默认值 | 功能 |
| ------------------- | ------------------------------ | -------------------------------------------------------- |
| `profile` | (必填) | `.profile` 文件的路径 |
| `--backend` | `https://teamserver.local:443` | 匹配流量的代理目标 |
| `--decoy` | `https://www.example.com/` | 未匹配流量的重定向地址 |
| `--server-name` | `c2.example.com` | 你的重定向器域名 |
| `--policy` | `strict` | `strict`, `lax`, 或 `none` |
| `--profile-type` | `auto` | 强制指定 `cobaltstrike` 或 `sliver`(默认:自动检测) |
| `--extra-uri PATH` | — | 额外代理的 URI(进行 UA 检查)。可重复使用。 |
| `--lax-uri PATH` | — | 额外代理的 URI(无检查)。可重复使用。 |
| `--allow-ua STRING` | — | 在 `--extra-uri` 路由上允许的额外 UA。可重复使用。 |
| `--forbid-http` | off | 对纯 HTTP 返回 403 |
| `--email EMAIL` | — | 用于 Let's Encrypt 注册和续订通知的 Email |
| `-o, --output FILE` | stdout | 将配置写入文件 |
## 策略模式
- **strict**(默认)— 检查 User-Agent、所有客户端 header、直接 IP、HTTP 方法和探测路径
- **lax** — 仅屏蔽恶意 User-Agent,不进行基于路由的 header 匹配
- **none** — 代理发往 profile URI 的任何请求,不进行过滤
Strict 通常是你想要的模式。当你调试为什么真实的 beacon 无法连接时,Lax 模式非常有用。
## 一个实际示例
假设你有一个模拟 Amazon endpoint 的 profile,并且你想将其部署在 `redirector.0xtb.sh` 上:
```
python3 caddysmith.py amazon.profile \
--backend https://10.1.1.10:443 \
--decoy https://www.amazon.com/ \
--server-name redirector.0xtb.sh \
--forbid-http \
--policy strict \
-o /etc/caddy/redirector.caddy
```
摘要会准确显示构建了哪些路由,例如:
```
Routes built: 2
- [profile-get] /broadcast
- [profile-post] /1/events/com.amazon.csm.csa.prod
```
如果你重新生成后发现*没有*路由,脚本可能无法解析你的 profile — 请检查 stderr 上的警告。
### Sliver 示例
对于 Sliver implant 配置 (JSON):
```
python3 caddysmith.py sliver-implant.json \
--backend https://10.1.1.10:443 \
--decoy https://www.amazon.com/ \
--server-name redirector.0xtb.sh \
--email you@example.com \
--forbid-http \
--policy strict \
-o /etc/caddy/redirector.caddy
```
摘要会告诉你检测到了 Sliver 并显示前缀路由:
```
Profile type: sliver
Routes built: 1
- [sliver] /api /public /resources /services /static (prefix)
```
因为 Sliver 是根据 路径 × 文件 × 扩展名 的组合随机生成 URI 的,所以生成的 `path` 匹配器使用前缀 glob(`path /api* /public* /resources* /services* /static*`)而不是精确路径。User-Agent 匹配器使用 Chrome 构建版本号的子字符串(例如 `3921.146`),Sliver 会跨平台保留此子字符串的 UA 重写。
## 部署后的冒烟测试
```
# Plain HTTP 应该返回 403(如果你使用了 --forbid-http)
curl -I http://redirector.0xtb.sh/
# 裸 hostname 应该重定向到诱饵
curl -kI https://redirector.0xtb.sh/
# 错误的 UA 也应该重定向
curl -kI -A "curl/8.4.0" https://redirector.0xtb.sh/broadcast
# 带有正确 UA + path 的请求应该通过代理转发 (200)
# 在 strict mode 下,你还需要发送该 profile 的所有 client headers。
```
## 已知限制
- **不会生成 Staging 规则 (Cobalt Strike)。** 如果你的 CS profile 设置了 `set host_stage "true"`(或者根本没有设置),脚本会警告你并跳过 stager URI。请将 `set host_stage "false";` 添加到你的 profile 中,或者通过 `--extra-uri` 显式传递 stager URI。
- **Sliver 前缀匹配比 CS 精确匹配范围更广。** 对于 Sliver,代理路由会接管任何以 `/api`、`/static` 等开头的 URL。碰巧使用这些前缀的扫描器探测(例如 `/api/.env`)将被发送到 team server,而不是在本地拦截 —— 但 Sliver 自身的 HTTP 传输通过 implant ID 进行身份验证,因此未经授权的请求会在 C2 层被拒绝。UA 限制仍然能将大多数扫描器拒之门外。
- **每次运行只有一个后端。** 每个路由都代理到相同的 `--backend`。如果你需要多个 team server,请多次运行脚本并手动合并。
- **Profile URI 解析是基于行的 (Cobalt Strike)。** `set uri "/path1 /path2";` 可以工作(一行上有多个路径),但特殊的格式可能会使解析器出错。请检查摘要中的路由列表以确认。
- **HTTPS 后端证书验证默认是关闭的。** Team server 通常使用自签名证书,因此生成的配置包含 `tls_insecure_skip_verify`。如果你的后端拥有真实的证书,请从生成的文件中删除该行。
## 许可证
MIT
标签:逆向工具