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
标签:逆向工具