CaddySmith 是一个小型 Python 脚本,它读取 Cobalt Strike 或 Sliver C2 配置文件,并从中生成一个 Caddy Web 服务器配置。生成的 Caddyfile 将普通的 Linux 机器变成一个重定向器:合法的 Beacon 流量被反向代理到你的团队服务器,其他一切(扫描器、搜索引擎爬虫、蓝队探针、随机 curl 请求)都被弹到一个诱饵 URL。
我写这个是因为 Caddy 是一个比 Apache 更友好的 Web 服务器,可以快速搭建:单一静态二进制文件,自动 Let's Encrypt 证书,无需 a2enmod 之类的操作。
仅限授权演习。 这是进攻性安全工具。仅在你拥有书面许可的环境上运行。
CaddySmith 根据文件内容自动检测格式:
set uri "/foo" 指令的经典文本格式。每个 HTTP-GET / HTTP-POST URI 都成为自己的精确路径路由,并强制执行配置文件中的客户端头。path /api* /static* /resources*)并执行 UA 中 Chrome 构建号的子字符串匹配(该构建号在 Sliver 每平台 UA 重写中保持不变)来处理。你还可以通过 --profile-type cobaltstrike 或 --profile-type sliver 强制指定解析器。
给定一个配置文件,脚本提取出:
--server-name,则用作重定向器的域名)set host_stage)然后它构建一个 Caddyfile,该文件:
.env、/wp-admin、.php 等)pip install)python3 caddysmith.py my.profile \
--backend https://teamserver.internal:443 \
--decoy https://www.example.com/ \
--server-name redirector.example.com \
--email [email protected] \
--forbid-http \
-o redirector.caddy
这会将生成的配置写入 redirector.caddy,并在 stderr 上打印所做操作的摘要。
将生成的文件复制到重定向器,并使用 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
将文件放入 /etc/caddy/ 并从主 Caddyfile 中导入:
# /etc/caddy/Caddyfile
import /etc/caddy/redirector.caddy
如果你传递了 --email(推荐),生成的片段已包含全局选项块,因此主 Caddyfile 只需要 import 行。如果没有传递,请手动在 import 上方添加一个 { } 块中的 email。
然后验证并重载:
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
只要 A 记录指向重定向器,Caddy 会自动为 --server-name 中的域名自动配置 Let's Encrypt 证书。
Strict 通常是你要用的。Lax 在调试真实 Beacon 未能连接时有用。
假设你有一个模拟 Amazon 端点的配置文件,并希望将其部署在 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
如果你重新生成但看到 没有 路由,脚本可能未能解析你的配置文件——请检查 stderr 上的警告。
对于 Sliver 植入配置(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 [email protected] \
--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 匹配器使用前缀通配符(path /api* /public* /resources* /services* /static*)而不是精确路径。User-Agent 匹配器使用 Chrome 构建号的子字符串(例如 3921.146),Sliver 在其每平台 UA 重写中保留此构建号。
# 纯 HTTP 应返回 403(如果你使用了 --forbid-http)
curl -I http://redirector.0xtb.sh/
# 裸主机名应重定向到诱饵
curl -kI https://redirector.0xtb.sh/
# 错误的 UA 也应重定向
curl -kI -A "curl/8.4.0" https://redirector.0xtb.sh/broadcast
# 带有正确 UA 和路径的请求应通过代理(200)
# 在严格模式下,还需要发送配置文件中所有客户端头。
set host_stage "true"(或未设置),脚本会发出警告并跳过 Stager URI。请在配置文件中添加 set host_stage "false";,或者通过 --extra-uri 显式传递 Stager URI。/api、/static 等开头的 URL。恰好使用这些前缀的扫描器探测(例如 /api/.env)会被发送到团队服务器,而不是在本地拦截——但 Sliver 自己的 HTTP 传输通过植入 ID 进行身份验证,因此未授权的请求会在 C2 层被拒绝。UA 门控仍然能阻止大多数扫描器。--backend。如果你需要多个团队服务器,多次运行脚本并手动合并结果。set uri "/path1 /path2"; 可以工作(一行多个路径),但异常格式可能会让解析器出错。请检查摘要中的路由列表确认。tls_insecure_skip_verify。如果你的后端有真实证书,请从生成的文件中删除该行。基于 Apache 的 Malleable-Redirector 是这个脚本生成内容的起点,同样的三轨道 URI 模型(配置文件 URI / 额外 URI / 宽松 URI),同样的策略模式,同样的总体布局。CaddySmith 只是将输出翻译成 Caddy 语法,而不是 Apache .htaccess。
MIT
| 标志 | 默认值 | 作用 |
|---|
profile | (必需) | 配置文件的路径 |
--backend | https://teamserver.local:443 | 匹配流量要代理到的后端 |
--decoy | https://www.example.com/ | 未匹配流量要重定向到的 URL |
--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 路由上通过的额外 User-Agent。可重复使用。 |
--forbid-http | 关闭 | 对纯 HTTP 返回 403 |
--email EMAIL | — | 用于 Let's Encrypt 注册和续期通知的邮箱地址 |
-o, --output FILE | stdout | 将配置写入文件 |