dukeboles/cbcscan
GitHub: dukeboles/cbcscan
扫描 AWS 账户中各类 TLS endpoint 是否允许或实际协商了 CBC 模式密码套件,并为每项发现提供具体修复方案的安全审计工具。
Stars: 0 | Forks: 0
# cbcscan
扫描 AWS 账户,找出**允许**或**已实际协商过** CBC 模式 cipher suite 的 TLS endpoint,并为每个发现提供具体的修复方案。
目标:完全消除连接到您账户时使用 CBC 系列 cipher 的任何可能性。
## 检查内容
| Scanner key | Surface | How ciphers are determined |
|---|---|---|
| `alb-nlb` | ALB/NLB HTTPS & TLS listeners | 实时,通过 `elbv2 describe-ssl-policies` |
| `clb` | Classic ELB SSL negotiation policies | 实时,基于每个 cipher 的策略属性 |
| `cloudfront` | Distribution viewer security policies (global) | 基于文档推导的静态映射,经分类器验证 |
| `apigw` | API Gateway custom domains (REST + HTTP/WS) | AWS 托管:即使 `TLS_1_2` 也包含 CBC → 标记为不可移除 |
| `opensearch` | Domain endpoint TLS policies | 保守策略:标记 2019 策略;PFS-2023-10 会触发探测验证的 INFO 发现 |
| `lightsail` | Lightsail load balancer TLS policies | 实时,通过 `get-load-balancer-tls-policies` |
使用 `--usage` 时,它还会**通过 Athena 查询访问日志**(ALB、NLB、CLB、CloudFront —— 每个连接都会记录协商的 cipher),并报告在回溯窗口内客户端*实际*协商了 CBC 的每个资源,包括每个 cipher 的连接计数和示例客户端 IP,以便您在断开连接之前找到引起问题的客户端。
禁用了访问日志的 TLS 服务资源将收到 `NO_VISIBILITY` 发现 —— 如果没有日志,您无法证明不存在 CBC。
### 发现类型
| Type | Severity | Meaning |
|---|---|---|
| `OBSERVED_CBC_CONNECTIONS` | CRITICAL | 真实客户端在回溯窗口内协商了 CBC |
| `CONFIG_ALLOWS_CBC` | HIGH | 配置允许 CBC(无法验证时为 INFO) |
| `CBC_NOT_REMOVABLE` | MEDIUM | AWS 托管的 cipher 列表包含 CBC 且无法收紧 |
| `NO_VISIBILITY` | MEDIUM | 提供 TLS 服务,但没有访问日志以验证实际使用情况 |
每份报告还会列出**盲点**(EC2 上的自管理 TLS、API Gateway 默认 endpoint、AWS 服务 endpoint、托管服务数据平面),因此干净的扫描绝不会被误认为是“没有任何 CBC”。
## 安装
要求 Python 3.11+。
```
uv venv && uv pip install -e . # or: pip install -e .
```
## 用法
```
# 配置扫描(只读,无副作用)
cbcscan scan --region us-east-1 --profile myprofile
# 通过 Athena 进行配置 + 实际使用扫描
cbcscan scan --region us-east-1 --usage --days 30 \
--athena-output s3://my-athena-results/cbcscan/
# Outputs 与 CI
cbcscan scan --region us-east-1 --output findings.json --html report.html --fail-on high
cbcscan list-services # available scanner keys for --services
```
Exit codes: `0` 表示干净,`2` 表示发现达到或超过 `--fail-on` 阈值,`1` 表示运行时/身份验证错误。
注意:
- CloudFront 是一项全局服务;无论 `--region` 设置如何,都会对其进行扫描。
- 该工具**绝不修改 AWS 配置**。在 `--usage` 模式下,唯一的副作用是创建名为 `cbcscan` 的 Glue 数据库/表,并将 Athena 查询结果写入 `--athena-output`。
- Athena 的成本约为 5 美元/TB 扫描量。ALB/NLB/CLB 表使用日期分区投影,因此 `--days` 会限制扫描范围。CloudFront 旧版标准日志未进行分区 —— 会扫描整个日志前缀(工具会在发生这种情况时发出警告);建议考虑使用带分区功能的 CloudFront 标准日志记录 v2。
## 所需的 IAM 权限
配置扫描(纯只读):
```
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CbcscanConfigScan",
"Effect": "Allow",
"Action": [
"sts:GetCallerIdentity",
"elasticloadbalancing:Describe*",
"cloudfront:ListDistributions",
"cloudfront:GetDistributionConfig",
"apigateway:GET",
"es:ListDomainNames",
"es:DescribeDomains",
"lightsail:GetLoadBalancers",
"lightsail:GetLoadBalancerTlsPolicies"
],
"Resource": "*"
}
]
}
```
使用模式还需要:
```
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CbcscanAthena",
"Effect": "Allow",
"Action": [
"athena:StartQueryExecution",
"athena:GetQueryExecution",
"athena:GetQueryResults",
"athena:StopQueryExecution",
"athena:GetWorkGroup",
"glue:CreateDatabase",
"glue:GetDatabase",
"glue:CreateTable",
"glue:GetTable",
"glue:UpdateTable"
],
"Resource": "*"
},
{
"Sid": "CbcscanReadLogBuckets",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket", "s3:GetBucketLocation"],
"Resource": ["arn:aws:s3:::", "arn:aws:s3:::/*"]
},
{
"Sid": "CbcscanAthenaResults",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket", "s3:GetBucketLocation"],
"Resource": ["arn:aws:s3:::", "arn:aws:s3:::/*"]
}
]
}
```
## 端到端冒烟测试(针对测试账户)
1. 创建一个 ALB,其 HTTPS listener 固定使用 `ELBSecurityPolicy-2016-08`,并启用访问日志到测试 bucket。
2. `cbcscan scan --region us-east-1` → 预期会看到 `CONFIG_ALLOWS_CBC` 发现,列出如 `ECDHE-RSA-AES128-SHA256`、`AES128-SHA` 等 cipher suite,以及确切的 `modify-listener` 修复命令;exit code 2。
3. 生成 CBC 流量,然后等待约 5 分钟以便交付日志:
curl --ciphers ECDHE-RSA-AES128-SHA256 --tls-max 1.2 -k https:///
4. `cbcscan scan --region us-east-1 --usage --days 1 --athena-output s3:///cbcscan/` → 预期会看到 `OBSERVED_CBC_CONNECTIONS`,包含 cipher 计数和您的源 IP。
5. 逐字应用输出的修复命令并重新运行 —— 发现将消失,并且步骤 3 中的 `curl` 现在将**握手失败**。这种失败正是目的所在:该 endpoint 上不再可能使用 CBC。
6. 禁用 ALB 的访问日志并重新运行 → 预期会看到 `NO_VISIBILITY` 发现。
## 开发
```
uv pip install -e ".[dev]"
pytest # 137 tests: classifier tables, per-scanner moto/Stubber, Athena state machine, CLI contract
ruff check src tests
```
添加服务 scanner:继承 `cbcscan.scanners.base.Scanner`,实现 `scan()`(如果服务会写入带有 cipher 字段的访问日志,则还需实现 `discover_log_sources()`),并在 `cbcscan/scanners/__init__.py` 中注册该类。
标签:AWS, DPI, TLS, 加密套件检查, 安全扫描, 时序注入, 逆向工具, 防御工具