doyensec/elbaph

GitHub: doyensec/elbaph

ELBaph 是一款 AWS 弹性负载均衡器配置审计工具,通过分析路由规则和主动探测来发现导致内部服务暴露于公网的配置错误。

Stars: 10 | Forks: 1

# ELBaph - **AWS Elastic Load Balancer 配置审计工具** [![Doyensec Research Island](https://img.shields.io/static/v1?logo=data:image/png;base64,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&link=https://doyensec.com/research.html&message=Research%20Island&&label=Doyensec&color=purple)](https://doyensec.com/research.html) ![GitHub](https://img.shields.io/github/license/doyensec/elbaph?logo=github&color=darkgreen) 一款白盒 CLI 工具,供渗透测试人员和安全工程师枚举 AWS Application Load Balancer 并检测导致内部服务暴露于公网的常见路由配置错误。 由 [Doyensec](https://doyensec.com) 作为 **CloudSec Tidbits Season 2** 的一部分构建。 **检查参考(行为、示例):** [docs/elbaph-checks-documentation.md](docs/elbaph-checks-documentation.md)。

## 目的 ELBaph 是一个使用 Go 编写的主动/被动审计框架。其目标是识别典型的安全态势管理工具 (CSPM) 会遗漏的 AWS Elastic Load Balancer (ELB) 中的路由配置错误和逻辑漏洞。 ELBaph 不仅仅检查是否启用了日志记录或是否附加了 WAF,它还会: - 评估监听器条件(路径、主机标头、源 IP)。 - 交叉引用不同 ALB 之间的 Target Group 及其 EC2 实例成员。 - 分析与周边网络组件(VPC、CloudFront 分发)的交互。 - 执行有针对性的 HTTP 可达性探测,以验证后端服务是否真正暴露。 ## 安装 ``` git clone https://github.com/doyensec/elbaph.git cd elbaph go build -o elbaph . ``` 需要 Go 1.24 或更高版本。 ## 用法 ``` # 扫描一个区域 - 实时打印发现结果,自动创建输出文件夹 elbaph scan --region us-east-1 # 使用 AWS profile 扫描多个区域 elbaph scan --all-regions -p my-pentest-profile # Inline access key + secret(可选的 STS creds session token) elbaph scan -r us-east-1 --aws-access-key-id AKIAEXAMPLE --aws-secret-access-key '...' # Shared credentials file(INI 格式,布局与 ~/.aws/credentials 相同)和 profile name elbaph scan -r us-east-1 --aws-credentials-file ./readonly.creds -p customer-audit # 通过远程代理路由活动的 HTTP 探测。 # 从内部网络或企业 VPN 运行该工具时非常有用 # 用于模拟外部视点并避免误报的可达性结果。 elbaph scan -r us-east-1 --proxy http://remote.vantage.point:8080 # 将所有内容以 JSON 格式输出到通用的 "out" 文件夹,并禁用终端颜色 elbaph scan -r eu-west-1 -d out -o json --no-color # 仅运行特定检查 elbaph scan --region us-east-1 --checks alb-external-reachability,alb-ip-gate-bypass # 同时导出结构化报告(与始终创建的文本文件夹一起) elbaph scan --region us-east-1 --output json elbaph scan --region us-east-1 --output markdown elbaph scan --region us-east-1 --output sarif # 将结构化导出写入特定路径 elbaph scan --region us-east-1 --output sarif --file /tmp/results.sarif # 抑制终端颜色(在 CI 中很有用) elbaph scan --region us-east-1 --no-color ``` ### 标志 | 标志 | 默认值 | 描述 | |---|---|---| | `-r, --region` | `us-east-1` | 要扫描的 AWS 区域(当设置了 `--all-regions` 时作为唯一区域被忽略) | | `--all-regions` | - | 扫描为该账户启用的每个区域 (`ec2:DescribeRegions`) | | `-p, --profile` | - | AWS 命名配置文件(使用自定义凭证文件时,选择对应的配置块;否则像往常一样使用共享配置) | | `--aws-access-key-id` | - | 访问密钥;必须与 `--aws-secret-access-key` 配合使用;与 `--aws-credentials-file` 互斥 | | `--aws-secret-access-key` | - | 私有密钥;必须与 `--aws-access-key-id` 配合使用 | | `--aws-session-token` | - | 使用临时 (STS) 内联凭证时的可选会话令牌 | | `--aws-credentials-file` | - | 指向凭证 INI 文件的路径(格式与 `~/.aws/credentials` 相同);与内联密钥标志互斥;与 `-p` 结合使用以指定非 `default` 的配置文件 | | `-c, --checks` | all | 要运行的检查 ID 的逗号分隔列表 | | `-d, --dir` | `elbaph-` | 输出目录名称 | | `-o, --output` | - | 额外导出格式:`json` \| `markdown` \| `sarif` | | `-f, --file` | `/report.` | 结构化导出的文件路径 | | `--proxy` | - | 用于主动探测检查的可选 HTTP 代理 URL | | `--vhost-probe-hosts-file` | - | 用于 `alb-vhost-probe`:以换行符分隔的主机名,合并**在**监听器规则和 Route 53 别名之后,但**在** Route 53 区域语料库**之前**,这样当语料库达到候选上限时,您的列表不会被截断 (`Source: file-corpus`) | | `--vhost-probe-path` | `/` | 用于 `alb-vhost-probe`:每个 GET 探测的 URL 路径(必须以 `/` 开头,例如 `/api/health`) | | `--no-color` | - | 禁用终端颜色 | ### AWS 凭证 默认情况下,ELBaph 在扫描区域使用 **AWS SDK 默认凭证链**(当设置了 `--all-regions` 时,对于诸如 CloudFront 和 `DescribeRegions` 之类的全局调用使用 `us-east-1`):环境变量 (`AWS_ACCESS_KEY_ID`、`AWS_SECRET_ACCESS_KEY`、`AWS_SESSION_TOKEN`)、位于 `~/.aws/` 下的共享文件,以及适用时的 EC2/实例配置文件。使用 **`-p` / `--profile`** 可强制使用共享配置中的指定命名配置文件。 **内联密钥:** `--aws-access-key-id` 和 `--aws-secret-access-key` 一起为整个运行过程安装一个静态凭证提供程序。在使用 STS 临时凭证时添加 `--aws-session-token`。此模式与 `--aws-credentials-file` **互斥**。内联密钥在**进程列表**和 shell 历史记录中可见;请尽可能使用环境变量、凭证文件或 IAM 角色。 **凭证文件:** `--aws-credentials-file` 指向一个格式与 `~/.aws/credentials` 相同的 INI 文件(包含 `[profile-name]` 部分以及 `aws_access_key_id` / `aws_secret_access_key` / 可选的 `aws_session_token`)。如果不使用 `-p`,SDK 将使用该文件中的 **`default`** 配置文件;如果使用 `-p myprofile`,则使用 **`[myprofile]`** 部分。 ### 代理探测 当 ELBaph 执行主动探测检查(例如 `alb-external-reachability`)时,它会直接对后端目标 IP 发起 HTTP 连接,以确定它们是否暴露在公共互联网中。 如果您是在企业 VPC 内部或企业 VPN 后方运行 ELBaph,您的计算机可能拥有对这些目标的特权网络访问权限。这种内部路由可能导致 ELBaph 错误地将隔离的实例归类为“可从互联网访问”。 为了减少此类误报,请使用 `--proxy` 标志通过外部有利位置(例如,面向互联网的代理服务器)路由主动探测。这可以确保可达性测试能够准确反映外部、未经身份验证的攻击者的视角。 对于 **HTTP** 监听器上的 **`alb-vhost-probe`**,`http://` 代理(包括运行在 `127.0.0.1:808` 的 Burp)的实现方式是:先向 `alb-dns:port` 发起 **`CONNECT`**,然后向 **`--vhost-probe-path`**(默认为 `/`)发起正常的 `GET` 请求,其 **`Host`** 标头为 vhost 候选项。这避免了 Go 的 `net/http` 的一个怪癖,否则普通的代理请求会发送 `GET http:///…`,而代理会去联系 vhost 名称而不是负载均衡器。在测试 HTTP 监听器时,请确保您的代理允许 **通过 CONNECT 连接 80 端口**(Burp:*Proxy settings → Request listeners → allow …* 或根据需要添加上游规则)。如果候选主机超过 **50** 个,vhost 探测将以**并发**方式运行;可以通过 **`ELBAPH_VHOST_PROBE_MAX_CONCURRENCY`**(默认为 **8**)来限制并发数。 ## 输出 每次扫描都会在当前工作目录中创建一个带有时间戳的文件夹: ``` elbaph-2026-04-01_22-00-00/ ├── summary.txt run metadata + per-check finding counts ├── albs.txt table of all discovered ALBs ├── nlbs.txt table of all discovered NLBs (scheme, DNS, listeners) ├── target_groups.txt table of all target groups + health ├── rules.txt per-ALB listener rule chain dump ├── findings.txt one detailed block per finding ├── vhost_route53_attachments.txt Route 53 FQDNs → ALB (alias/cname) for alb-vhost-probe ├── vhost_route53_corpus.txt record-owner FQDNs from listed zones, excluding zone apex (probe wordlist source) └── topology.html vis-network resource map (VPC → ALB → listener → rule → TG → targets; multi-ALB targets highlighted) ``` `topology.html` 文件是一个交互式图表,展示了您的 ELB 在 VPC 中的位置,以及流量如何通过监听器、规则、目标组和后端目标进行路由。 随着每项检查的完成,检查结果也会**实时打印到终端**——您无需等待整个扫描结束。 如果指定了 `--output`,系统会将 `report.json` / `report.md` / `report.sarif` 写入同一个文件夹。 ## 所需的 AWS 权限 ELBaph 是**只读的**。所需的最低 IAM 策略为: ``` { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "elasticloadbalancing:DescribeLoadBalancers", "elasticloadbalancing:DescribeLoadBalancerAttributes", "elasticloadbalancing:DescribeListeners", "elasticloadbalancing:DescribeRules", "elasticloadbalancing:DescribeTargetGroups", "elasticloadbalancing:DescribeTargetHealth", "ec2:DescribeRegions", "ec2:DescribeInstances", "route53:ListHostedZones", "route53:ListResourceRecordSets" ], "Resource": "*" } ] } ``` ## 检查 内置检查 ID(用于 `-c` / `--checks`)。**方法论、示例输出以及如何解读每项发现:** **[docs/elbaph-checks-documentation.md](docs/elbaph-checks-documentation.md)**。 | ID | 名称 | |----|------| | `alb-client-ip-spoofable` | 通过保留的 X-Forwarded-For 进行客户端 IP 欺骗 | | `cloudfront-bypass` | CloudFront 源站直接访问 | | `alb-desync-monitor` | Desync 缓解模式为 Monitor | | `alb-external-reachability` | 目标外部可达性 | | `alb-ip-gate-bypass` | 通过备用 ALB 绕过 IP 网关 | | `alb-optional-auth` | 允许可选的身份验证 | | `alb-rule-shadowing` | 严格的监听器规则被更宽泛的早期规则遮蔽 | | `alb-vhost-probe` | ALB 虚拟主机路由探测 | | `nlb-direct-target-reachability` | NLB 目标可直接访问 | ## 添加新检查 检查是位于 `internal/checks/` 中的单个 Go 文件。唯一的契约是 `Check` 接口: ``` type Check interface { ID() string Name() string Description() string Run(ctx context.Context, data *collector.Dataset) ([]model.Finding, error) } ``` ### 步骤详解 **1. 创建文件** ``` internal/checks/my_check.go ``` **2. 实现接口** ``` package checks import ( "context" "fmt" "github.com/doyensec/elbaph/internal/collector" "github.com/doyensec/elbaph/internal/model" ) /* alb-my-check Describe what this check looks for, why it matters, and what the exact trigger conditions are. This comment is the primary documentation for anyone reading or reviewing the check. Trigger condition: ALB scheme = internet-facing ... */ func init() { Register(&MyCheck{}) } type MyCheck struct{} func (c *MyCheck) ID() string { return "alb-my-check" } func (c *MyCheck) Name() string { return "alb-my-check" } func (c *MyCheck) Description() string { return "One-line description of what this check detects." } func (c *MyCheck) Run(ctx context.Context, data *collector.Dataset) ([]model.Finding, error) { var findings []model.Finding for _, lb := range data.LoadBalancers { // ... detection logic ... findings = append(findings, model.Finding{ ID: fmt.Sprintf("%s|%s", c.ID(), lb.ARN), CheckID: c.ID(), CheckName: c.Name(), Region: data.Region, LoadBalancerARN: lb.ARN, LoadBalancerName: lb.Name, LoadBalancerScheme: lb.Scheme, Detail: `Explain what was found and why it is a problem.`, Remediation: `Explain what should be done to fix it.`, }) } return findings, nil } ``` **3. 就这样。** `init()` 调用会在全局注册该检查。不需要修改任何其他文件。新检查将自动出现在 `--checks list` 的输出中,并作为默认扫描的一部分运行。请在 **[docs/elbaph-checks-documentation.md](docs/elbaph-checks-documentation.md)** 中添加一个简短的条目(ID、名称、叙述、示例输出),并在 README 的检查表中添加一行说明。 ### 有哪些可用数据 传递给 `Run()` 的 `collector.Dataset` 包含了从 AWS 收集的所有内容: | 字段 | 类型 | 内容 | |---|---|---| | `LoadBalancers` | `[]model.LoadBalancer` | 包含监听器、规则、已连接目标组指针以及 `Route53Names`(当允许使用 Route 53 API 时,指向该 ALB 的 ALIAS/CNAME 的 FQDN)的所有 ALB | | `TargetGroups` | `map[string]*model.TargetGroup` | 以 ARN 为键的所有 TG,包含健康数据 | `internal/albutil/` 中的辅助函数: | 函数 | 用途 | |---|---| | `albutil.ConditionSummary(conds)` | 规则条件的紧凑字符串表示 | | `albutil.ActionChainDesc(actions)` | 按顺序排列的、易于理解的操作描述切片 | `pkg/netutil` 包提供了 `IsRFC1918(ip)`。 ## 项目结构 ``` elbaph/ ├── docs/ │ └── elbaph-checks-documentation.md detailed check documentation + sample findings output ├── main.go ├── cmd/ │ ├── root.go cobra root command │ ├── scan.go scan subcommand - orchestrates collect → check → output │ └── version.go ├── internal/ │ ├── model/ shared domain types (LoadBalancer, Finding, ScanMeta, …) │ ├── collector/ AWS API calls → model types (no SDK types leak out) │ ├── checks/ detection modules + shared registry │ ├── output/ always-on text folder + live terminal printer │ └── export/ optional structured exporters (JSON, Markdown, SARIF) └── pkg/ └── netutil/ RFC1918 and CIDR helpers ``` ## :handshake: 贡献 ELBaph 的蓬勃发展离不开社区的贡献。无论您是开发者、研究人员还是漏洞猎人,您的反馈和 Pull Request 都有助于为所有人改进该项目。请使用 [GitHub Issue 跟踪器](https://github.com/doyensec/elbaph/issues) 进行报告和讨论。 本项目得到了 [Doyensec](https://doyensec.com/research.html) 的支持。 ![Doyensec Research](https://raw.githubusercontent.com/doyensec/inql/master/docs/doyensec_logo.svg)
标签:AWS, DPI, Elastic Load Balancer, EVTX分析, 日志审计