Translated ['', 'src/pentesting-ci-cd/github-security/basic-github-infor

This commit is contained in:
Translator
2025-09-29 22:23:54 +00:00
parent 389d77d2b9
commit d452cf43e5
6 changed files with 362 additions and 362 deletions

View File

@@ -16,25 +16,25 @@ The following tools are useful to find Github Action workflows and even find vul
На цій сторінці ви знайдете:
- Короткий огляд усіх наслідків, якщо зловмисник отримає доступ до Github Action
- **Огляд усіх наслідків** у разі, якщо нападник отримає доступ до Github Action
- Різні способи **отримати доступ до action**:
- Наявність **permissions** для створення action
- Маючи **permissions** для створення action
- Зловживання тригерами, пов'язаними з **pull request**
- Зловживання іншими зовнішніми методами доступу
- **Pivoting** з уже скомпрометованого repo
- Нарешті, розділ про **post-exploitation techniques** для зловживання action зсередини (що викликають зазначені наслідки)
- Зловживання **іншими техніками зовнішнього доступу**
- **Pivoting** з уже скомпрометованого репо
- Нарешті, розділ про **post-exploitation techniques to abuse an action from inside** (щоб спричинити згадані наслідки)
## Резюме наслідків
## Підсумок впливів
For an introduction about [**Github Actions check the basic information**](../basic-github-information.md#github-actions).
Якщо ви можете **execute arbitrary code in GitHub Actions** в межах **repository**, ви зможете:
Якщо ви можете **виконувати довільний код у GitHub Actions** в межах **репозиторію**, ви зможете:
- **Steal secrets** mounted to the pipeline and **abuse the pipeline's privileges** to gain unauthorized access to external platforms, such as AWS and GCP.
- **Compromise deployments** and other **artifacts**.
- Якщо pipeline deploys або stores assets, ви можете змінити кінцевий продукт, що дає змогу виконати supply chain attack.
- **Execute code in custom workers** для зловживання обчислювальною потужністю та pivot до інших систем.
- **Overwrite repository code**, в залежності від permissions, пов'язаних з `GITHUB_TOKEN`.
- **Вкрасти secrets**, змонтовані в pipeline, і **зловживати привілеями pipeline** для отримання несанкціонованого доступу до зовнішніх платформ, таких як AWS і GCP.
- **Компрометувати deployments** та інші **artifacts**.
- Якщо pipeline розгортає або зберігає assets, ви можете змінити кінцевий продукт, що дозволяє провести supply chain attack.
- **Виконувати код у custom workers** для зловживання обчислювальними ресурсами та pivot до інших систем.
- **Перезаписати код репозиторію**, залежно від permissions, пов'язаних із `GITHUB_TOKEN`.
## GITHUB_TOKEN
@@ -45,7 +45,7 @@ This "**secret**" (coming from `${{ secrets.GITHUB_TOKEN }}` and `${{ github.tok
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`.
> Github має випустити a [**flow**](https://github.com/github/roadmap/issues/74) який **дозволяє доступ між репозиторіями** 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)
@@ -91,11 +91,11 @@ https://api.github.com/repos/<org_name>/<repo_name>/pulls \
{{#endtabs }}
> [!CAUTION]
> Зверніть увагу, що в кількох випадках ви зможете знайти **github user tokens inside Github Actions envs or in the secrets**. Ці токени можуть надати вам додаткові привілеї у repository та organization.
> Зверніть увагу, що у деяких випадках ви зможете знайти **github user tokens inside Github Actions envs or in the secrets**. Ці токени можуть надати вам більше привілеїв над репозиторієм та організацією.
<details>
<summary>Перелік secrets у виводі Github Action</summary>
<summary>List secrets in Github Action output</summary>
```yaml
name: list_env
on:
@@ -121,7 +121,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
<details>
<summary>Отримати reverse shell з secrets</summary>
<summary>Отримати reverse shell за допомогою secrets</summary>
```yaml
name: revshell
on:
@@ -144,29 +144,29 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
Можна перевірити дозволи, надані Github Token в репозиторіях інших користувачів, **checking the logs** of the actions:
Можна перевірити права, надані Github Token у репозиторіях інших користувачів, **переглянувши логи** Github Actions:
<figure><img src="../../../images/image (286).png" alt="" width="269"><figcaption></figcaption></figure>
## Allowed Execution
## Дозволене виконання
> [!NOTE]
> Це був би найпростіший спосіб скомпрометувати Github actions, оскільки в цьому випадку передбачається, що ви маєте доступ до **create a new repo in the organization**, або маєте **write privileges over a repository**.
> Це був би найпростіший спосіб скомпрометувати Github actions, оскільки в цьому випадку передбачається, що у вас є доступ до **створення нового репозиторію в організації**, або є **права запису в репозиторій**.
>
> Якщо ви в цій ситуації, ви можете просто переглянути [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action).
> Якщо ви в такій ситуації, ви можете просто переглянути [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action).
### Execution from Repo Creation
### Виконання через створення репозиторію
У випадку, якщо учасники organization можуть **create new repos** і ви можете виконувати github actions, ви можете **create a new repo and steal the secrets set at organization level**.
Якщо учасники організації можуть **створювати нові репозиторії** і ви можете запускати Github Actions, ви можете **створити новий репозиторій і викрасти секрети, встановлені на рівні організації**.
### Execution from a New Branch
### Виконання з нової гілки
Якщо ви можете **create a new branch in a repository that already contains a Github Action** configured, ви можете **modify** його, **upload** контент, а потім **execute that action from the new branch**. Таким чином ви можете **exfiltrate repository and organization level secrets** (але вам потрібно знати, як вони називаються).
Якщо ви можете **створити нову гілку в репозиторії, який вже містить налаштований Github Action**, ви можете **змінити** його, **завантажити** вміст, а потім **запустити той action із нової гілки**. Таким чином ви можете **витягти секрети на рівні репозиторію та організації** (але вам потрібно знати їхні імена).
> [!WARNING]
> Будь-яке обмеження, реалізоване лише всередині workflow YAML (наприклад, `on: push: branches: [main]`, job conditionals, або ручні валіди), може бути відредаговане співавторами. Без зовнішнього примусового застосування (branch protections, protected environments, and protected tags), учасник може перенаправити workflow на свій branch і зловживати змонтованими secrets/permissions.
> Будь-яке обмеження, реалізоване лише всередині workflow YAML (наприклад, `on: push: branches: [main]`, умовні вирази job або ручні підтвердження) може бути відредаговане співавторами. Без зовнішнього контролю (branch protections, protected environments, and protected tags) контриб'ютор може перенаправити workflow на виконання у своїй гілці та зловживати змонтованими секретами/дозволами.
Ви можете зробити змінений action виконуваним **вручну,** коли створено **PR** або коли **якийсь код запушено** (в залежності від того, наскільки багато шуму ви хочете зробити):
Ви можете зробити змінений action виконуваним **вручну,** коли **створюється PR** або коли **певний код пушиться** (залежно від того, наскільки помітними ви хочете бути):
```yaml
on:
workflow_dispatch: # Launch manually
@@ -180,49 +180,49 @@ branches:
```
---
## Виконання з форку
## Forked Execution
> [!NOTE]
> Існують різні тригери, які можуть дозволити атакуючому **виконати Github Action з іншого репозиторію**. Якщо такі тригерувані дії налаштовані неналежним чином, атакуючий може їх скомпрометувати.
> Існують різні тригери, які можуть дозволити атакуючому **виконати Github Action з іншого репозиторію**. Якщо ці тригерні дії погано налаштовані, атакуючий може їх скомпрометувати.
### `pull_request`
Тригер workflow **`pull_request`** виконуватиме workflow щоразу, коли надходить pull request, з деякими винятками: за замовчуванням, якщо це **вперше**, коли ви **співпрацюєте**, якийсь **maintainer** повинен **підтвердити** **запуск** workflow:
Тригер workflow **`pull_request`** виконуватиме workflow щоразу, коли надходить pull request, з деякими винятками: за замовчуванням, якщо це **вперше**, коли ви **співпрацюєте**, якийсь **maintainer** має **підтвердити** **запуск** workflow:
<figure><img src="../../../images/image (184).png" alt=""><figcaption></figcaption></figure>
> [!NOTE]
> Оскільки **обмеження за замовчуванням** стосуються **перших** контрибуторів, ви можете зробити внесок, **виправивши дійсну помилку/описку**, а потім надіслати **інші PR, щоб зловживати новими привілеями `pull_request`**.
> Оскільки **обмеження за замовчуванням** застосовується до **нових** контрибуторів, ви можете внести PR, виправивши **дійсну помилку/опечатку**, а потім надсилати **інші PRs, щоб зловживати вашими новими `pull_request` привілеями**.
>
> **Я це протестував і це не працює**: ~~Іншим варіантом було б створити акаунт з ім'ям когось, хто робив внесок у проєкт, а потім видалив його акаунт.~~
> **Я це тестував і це не працює**: ~~Another option would be to create an account with the name of someone that contributed to the project and deleted his account.~~
Крім того, за замовчуванням **запобігає наданню прав на запис** та **доступу до secrets** у цільовому репозиторії, як зазначено в [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories):
Крім того, за замовчуванням **перешкоджається надання прав запису** та **доступ до secrets** у цільовому репозиторії, як зазначено в [**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**.
Атакуючий може змінити визначення Github Action, щоб виконати довільні дії та додати довільні steps. Проте він не зможе вкрасти secrets або перезаписати репо через згадані обмеження.
Атакуючий може змінити визначення Github Action, щоб виконати довільні дії та додати довільні кроки. Однак через згадані обмеження він не зможе вкрасти секрети або перезаписати репо.
> [!CAUTION]
> **Так, якщо атакуючий змінить у PR github action, який буде тригеритись, його Github Action буде використано, а не той, що з origin repo!**
Оскільки атакуючий також контролює код, що виконується, навіть якщо немає доступу до secrets або прав запису через `GITHUB_TOKEN`, атакуючий, наприклад, може **завантажити шкідливі артефакти**.
Оскільки атакуючий також контролює код, що виконується, навіть якщо немає доступу до секретів або прав запису в `GITHUB_TOKEN`, атакуючий, наприклад, може **завантажувати шкідливі артефакти**.
### **`pull_request_target`**
Тригер workflow **`pull_request_target`** має **права на запис** у цільовому репозиторії та **доступ до secrets** (і не запитує дозволу).
Тригер workflow **`pull_request_target`** має **права запису** до цільового репозиторію та **доступ до секретів** (і не запитує підтвердження).
Зауважте, що тригер workflow **`pull_request_target`** **запускається в базовому контексті** і не в тому, що надається PR (щоб **не виконувати недовірений код**). Для отримання додаткової інформації про `pull_request_target` [**перегляньте docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
Крім того, для додаткової інформації про цей конкретно небезпечний випадок перегляньте цей [**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
Зверніть увагу, що тригер workflow **`pull_request_target`** **виконується в контексті base** і не в тому, який надає PR (щоб **не виконувати недовірений код**). Для додаткової інформації про `pull_request_target` [**check the docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
Крім того, для детальнішого розгляду цього конкретно небезпечного використання перегляньте цей [**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
Може здатись, що оскільки **виконуваний workflow** — це той, що визначений у **base**, а **не в PR**, то використання **`pull_request_target`** є **безпечним**, але існує **декілька випадків, коли це не так**.
Може здатися, що оскільки **виконуваний workflow** — це той, що визначений у **base**, а не в PR, то використовувати **`pull_request_target`** **безпечніше**, але є **кілька випадків, коли це неправда**.
І цей тригер матиме **доступ до secrets**.
І цей тригер матиме **доступ до секретів**.
### `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`.
Тригер [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) дозволяє запускати workflow після завершення іншого workflow, коли він `completed`, `requested` або `in_progress`.
In this example, a workflow is configured to run after the separate "Run Tests" workflow completes:
У цьому прикладі workflow налаштований на запуск після завершення окремого workflow "Run Tests":
```yaml
on:
workflow_run:
@@ -230,29 +230,29 @@ workflows: [Run Tests]
types:
- completed
```
Крім того, згідно з документацією: workflow, запущений подією `workflow_run`, може **access secrets and write tokens, even if the previous workflow was not**.
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**, який може бути **triggered** зовнішнім користувачем через **`pull_request`** або **`pull_request_target`**. Декілька вразливих прикладів можна [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** Перший полягає в тому, що workflow, який тригериться через **`workflow_run`**, завантажує код атакуючого: `${{ github.event.pull_request.head.sha }}`\
Другий полягає в **передачі** **artifact** з **untrusted** коду до workflow **`workflow_run`** і використанні вмісту цього artifact таким чином, що це робить його **vulnerable to RCE**.
Такий workflow може бути атакований, якщо він **depends** on a **workflow** that can be **triggered** by an external user via **`pull_request`** or **`pull_request_target`**. A couple of vulnerable examples can be [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** The first one consist on the **`workflow_run`** triggered workflow downloading out the attackers code: `${{ github.event.pull_request.head.sha }}`\
The second one consist on **passing** an **artifact** from the **untrusted** code to the **`workflow_run`** workflow and using the content of this artifact in a way that makes it **vulnerable to RCE**.
### `workflow_call`
TODO
TODO: Перевірити, чи коли виконується з `pull_request` використовуваний/завантажений код — з origin чи з forked PR
TODO: Check if when executed from a pull_request the used/downloaded code if the one from the origin or from the forked PR
## Зловживання виконанням fork'ів
## Зловживання виконанням з форка
Ми перелічили всі способи, якими зовнішній атакуючий може змусити виконатися github workflow; тепер подивімося, як ці виконання, якщо вони неправильно налаштовані, можуть бути зловживані:
Ми вже перелічили всі способи, якими зовнішній атакуючий може змусити github workflow виконатися, тепер подивімося, як такі виконання, якщо вони неправильно налаштовані, можуть бути використані зловмисником:
### Виконання untrusted checkout
### Untrusted checkout execution
У випадку **`pull_request`**, workflow виконуватиметься в **контексті PR** (тому він виконає **malicious PRs code**), але хтось повинен **authorize it first** і воно виконуватиметься з певними [limitations](#pull_request).
У випадку з **`pull_request`** workflow буде виконуватися в **контексті PR** (тобто виконуватиметься **шкідливий код PR**), але хтось повинен його **авторизувати спочатку**, і воно виконуватиметься з певними [обмеженнями](#pull_request).
У випадку workflow, що використовує **`pull_request_target` or `workflow_run`**, який залежить від workflow, який може бути triggered з **`pull_request_target` or `pull_request`**, виконуватиметься код з оригінального repo, тож **attacker cannot control the executed code**.
У випадку workflow, що використовує **`pull_request_target` or `workflow_run`**, який залежить від workflow, що може бути triggered from **`pull_request_target` or `pull_request`**, код з оригінального репозиторію буде виконаний, тож **атакуючий не зможе контролювати виконуваний код**.
> [!CAUTION]
> Однак, якщо **action** має **explicit PR checkou**t, який **get the code from the PR** (а не з base), буде використано код, контрольований атакуючим. Наприклад (див. line 12, де завантажується код PR):
> 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):
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Provided as an example only.
on:
@@ -282,14 +282,14 @@ message: |
Thank you!
</code></pre>
Потенційно **untrusted code is being run during `npm install` or `npm build`**, оскільки build scripts та згадані **packages are controlled by the author of the PR**.
Потенційно **небезпечний код виконується під час `npm install` або `npm build`**, оскільки build-скрипти та залежні пакети контролюються автором PR.
> [!WARNING]
> A github dork to search for vulnerable actions is: `event.pull_request pull_request_target extension:yml` проте існують різні способи налаштувати jobs для безпечного виконання навіть якщо action налаштований небезпечно (наприклад використовуючи conditionals про те, хто є actor, що створює 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 <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
Зауважте, що існують певні [**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) значення яких **контролюються** користувачем, який створює PR. Якщо github action використовує ці **data to execute anything**, це може призвести до **arbitrary code execution:**
Зверніть увагу, що існують певні [**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context), значення яких **контролюються** користувачем, що створює PR. Якщо github action використовує ці **дані для виконання чого-небудь**, це може призвести до **виконання довільного коду:**
{{#ref}}
gh-actions-context-script-injections.md
@@ -297,17 +297,17 @@ gh-actions-context-script-injections.md
### **GITHUB_ENV Script Injection** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
Згідно з документацією: Ви можете зробити **environment variable available to any subsequent steps** в job'і workflow, визначивши або оновивши змінну оточення та записавши це у файл середовища **`GITHUB_ENV`**.
Згідно з документацією: 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.
Якщо атакуючий може **inject any value** в цю **env** змінну, він може ввести змінні оточення, які можуть виконувати код у наступних кроках, наприклад **LD_PRELOAD** або **NODE_OPTIONS**.
Якщо атакуючий може **інжектувати будь-яке значення** у цю змінну середовища, він може додати змінні середовища, які спричинять виконання коду в наступних кроках, наприклад **LD_PRELOAD** або **NODE_OPTIONS**.
Наприклад ([**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)), уявіть workflow, який довіряє завантаженому artifact і зберігає його вміст у змінній оточення **`GITHUB_ENV`**. Атакуючий може завантажити щось подібне, щоб скомпрометувати його:
Наприклад ([**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)), уявіть workflow, який довіряє завантаженому artifact і зберігає його вміст у **`GITHUB_ENV`** env variable. Атакуючий міг би завантажити щось на кшталт цього, щоб скомпрометувати його:
<figure><img src="../../../images/image (261).png" alt=""><figcaption></figcaption></figure>
### Dependabot та інші довірені боти
### Dependabot and other trusted bots
Як вказано в [**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), кілька організацій мають Github Action, який merges any PRR від `dependabot[bot]`, наприклад:
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:
@@ -317,16 +317,16 @@ if: ${ { github.actor == 'dependabot[bot]' }}
steps:
- run: gh pr merge $ -d -m
```
Це проблема, тому що поле `github.actor` містить користувача, який спричинив останню подію, що запустила workflow. Існує кілька способів змусити користувача `dependabot[bot]` змінити PR. Наприклад:
Що є проблемою, тому що поле `github.actor` містить користувача, який спричинив останню подію, що запустила workflow. І існує кілька способів змусити користувача `dependabot[bot]` модифікувати PR. Наприклад:
- 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).
- Форкніть репозиторій жертви
- Додайте шкідливий payload до вашої копії
- Увімкніть Dependabot у вашому форку, додавши застарілу залежність. Dependabot створить гілку, яка виправляє залежність і містить шкідливий код.
- Відкрийте Pull Request до репозиторію жертви з тієї гілки (PR буде створено користувачем, тож поки нічого не станеться)
- Потім атакуючий повертається до початкового PR, який Dependabot відкрив у його форку, і виконує `@dependabot recreate`
- Потім Dependabot виконує деякі дії в тій гілці, які модифікують PR у репозиторії жертви, що робить `dependabot[bot]` актором останньої події, яка запустила workflow (і отже, workflow виконується).
Далі: що якби замість злиття Github Action мав command injection, як у:
Далі, що якби замість злиття Github Action мав command injection, як у:
```yaml
on: pull_request_target
jobs:
@@ -336,22 +336,22 @@ if: ${ { github.actor == 'dependabot[bot]' }}
steps:
- run: echo ${ { github.event.pull_request.head.ref }}
```
Отже, оригінальний допис у блозі пропонує два варіанти зловживання цією поведінкою, другим з яких є:
Отже, оригінальний блогпост пропонує два варіанти зловживання цією поведінкою, де другим є:
- Форкнути репозиторій жертви та увімкнути Dependabot з якоюсь застарілою залежністю.
- Створити нову гілку з шкідливим shell injection кодом.
- Змінити default branch репо на ту гілку.
- Створити PR з цієї гілки до репозиторію жертви.
- Запустити `@dependabot merge` у PR, який Dependabot відкрив у своєму форку.
- Dependabot змерджить свої зміни в default branch вашого форку, оновивши PR у репозиторії жертви, зробивши тепер `dependabot[bot]` актором останньої події, яка викликала workflow, та використовуючи шкідливу назву гілки.
- Форкніть репозиторій жертви та увімкніть Dependabot з якоюсь застарілою залежністю.
- Створіть нову гілку зі шкідливим shell injeciton кодом.
- Змініть гілку за замовчуванням репо на ту гілку.
- Створіть PR з цієї гілки до репозиторію жертви.
- Запустіть `@dependabot merge` в PR, який Dependabot відкрив у його форку.
- Dependabot зіллє його зміни в гілку за замовчуванням вашого форкнутого репозиторію, оновивши PR в репозиторії жертви, зробивши тепер `dependabot[bot]` актором останньої події, що запустила workflow, і використовуючи шкідливу назву гілки.
### Vulnerable Third Party Github Actions
### Уразливі сторонні Github Actions
#### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
Як зазначено в [**цьому дописі**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), цей Github Action дозволяє отримувати доступ до artifacts з різних workflow і навіть з інших репозиторіїв.
Як зазначено в [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), цей Github Action дозволяє отримувати доступ до artifacts з різних workflows і навіть repositories.
Проблема в тому, що якщо параметр **`path`** не заданий, артефакт розпаковується в поточну директорію і може перезаписати файли, які пізніше можуть бути використані або навіть виконані у workflow. Тому, якщо Artifact вразливий, нападник може зловживати цим, щоб скомпрометувати інші workflow, які довіряються цьому Artifact.
Проблема в тому, що якщо параметр **`path`** не задано, артефакт розпаковується в поточний каталог і може перезаписати файли, які потім можуть бути використані або навіть виконані у workflow. Тому, якщо Artifact уразливий, атакуючий може зловживати цим, щоб скомпрометувати інші workflows, що довіряють цьому Artifact.
Example of vulnerable workflow:
```yaml
@@ -397,23 +397,23 @@ path: ./script.py
### Deleted Namespace Repo Hijacking
If an account changes it's name another user could register an account with that name after some time. If a repository had **less than 100 stars previously to the change of nam**e, Github will allow the new register user with the same name to create a **repository with the same name** as the one deleted.
Якщо account змінює своє ім'я, інший користувач може зареєструвати account з цим іменем згодом. Якщо repository мав **less than 100 stars previously to the change of name**, Github дозволить новому зареєстрованому користувачу з тим самим ім'ям створити **repository with the same name** як той, що був видалений.
> [!CAUTION]
> So if an action is using a repo from a non-existent account, it's still possible that an attacker could create that account and compromise the action.
> Тому, якщо action використовує repo з неіснуючого account, все ще можливо, що зловмисник зможе створити цей account і compromise action.
If other repositories where using **dependencies from this user repos**, an attacker will be able to hijack them Here you have a more complete explanation: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
Якщо інші repositories використовували **dependencies from this user repos**, зловмисник зможе hijack їх. Детальніше: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
---
## Repo Pivoting
> [!NOTE]
> In this section we will talk about techniques that would allow to **pivot from one repo to another** supposing we have some kind of access on the first one (check the previous section).
> У цьому розділі ми поговоримо про техніки, які дозволяють **pivot from one repo to another**, припускаючи, що ми маємо певний доступ до першого (див. попередній розділ).
### Cache Poisoning
A cache is maintained between **workflow runs in the same branch**. Which means that if an attacker **compromise** a **package** that is then stored in the cache and **downloaded** and executed by a **more privileged** workflow he will be able to **compromise** also that workflow.
Між workflow runs в тій самій branch підтримується cache. Це означає, що якщо зловмисник compromise package, який потім зберігається в cache і потім downloaded та виконується більш привілейованим workflow, він також зможе compromise і цей workflow.
{{#ref}}
gh-actions-cache-poisoning.md
@@ -421,7 +421,7 @@ gh-actions-cache-poisoning.md
### Artifact Poisoning
Workflows could use **artifacts from other workflows and even repos**, if an attacker manages to **compromise** the Github Action that **uploads an artifact** that is later used by another workflow he could **compromise the other workflows**:
Workflows можуть використовувати **artifacts from other workflows and even repos** — якщо зловмиснику вдасться compromise Github Action, яка **uploads an artifact**, який пізніше використовується іншим workflow, він зможе compromise й інші workflows:
{{#ref}}
gh-actions-artifact-poisoning.md
@@ -433,9 +433,9 @@ gh-actions-artifact-poisoning.md
### Github Action Policies Bypass
As commented in [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass), even if a repository or organization has a policy restricting the use of certain actions, an attacker could just download (`git clone`) and action inside the workflow and then reference it as a local action. As the policies doesn't affect local paths, **action буде виконано без жодних обмежень.**
Як зазначено в [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass), навіть якщо repository або organization має політику, що обмежує використання певних actions, зловмисник може просто download (`git clone`) action всередині workflow і потім посилатися на нього як на local action. Оскільки політики не впливають на local paths, **the action will be executed without any restriction.**
Приклад:
Example:
```yaml
on: [push, pull_request]
@@ -468,15 +468,15 @@ path: gha-hazmat
../../../pentesting-cloud/gcp-security/gcp-basic-information/gcp-federation-abuse.md
{{#endref}}
### Доступ до секретів <a href="#accessing-secrets" id="accessing-secrets"></a>
### Доступ до secrets <a href="#accessing-secrets" id="accessing-secrets"></a>
Якщо ви вставляєте вміст у скрипт, корисно знати, як отримати доступ до секретів:
Якщо ви вставляєте вміст у скрипт, корисно знати, як можна отримати доступ до secrets:
- Якщо секрет або токен задані як **змінна середовища**, їх можна напряму отримати, використовуючи **`printenv`**.
- Якщо secret або token встановлено як **environment variable**, їх можна безпосередньо отримати через середовище за допомогою **`printenv`**.
<details>
<summary>Перелічити секрети у виводі Github Action</summary>
<summary>Перелічити secrets у виводі Github Action</summary>
```yaml
name: list_env
on:
@@ -503,7 +503,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
<details>
<summary>Отримати reverse shell за допомогою secrets</summary>
<summary>Отримати reverse shell за допомогою секретів</summary>
```yaml
name: revshell
on:
@@ -526,15 +526,15 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
- Якщо secret використовується **безпосередньо в виразі**, згенерований shell script зберігається **на диску** і доступний.
- Якщо секрет використовується **безпосередньо в виразі**, згенерований shell-скрипт зберігається **на диску** і доступний.
- ```bash
cat /home/runner/work/_temp/*
```
- Для JavaScript actions secrets передаються через змінні середовища
- Для JavaScript actions секрети передаються через environment variables
- ```bash
ps axe | grep node
```
- Для **custom action** ризик може варіюватися залежно від того, як програма використовує секрет, який вона отримала з **argument**:
- Для **custom action** ризик може варіюватися залежно від того, як програма використовує секрет, отриманий з **argument**:
```yaml
uses: fakeaction/publish@v3
@@ -542,7 +542,7 @@ with:
key: ${{ secrets.PUBLISH_KEY }}
```
- Перелічіть всі secrets через secrets context (collaborator level). Контриб'ютор з правами write може змінити workflow в будь-якій гілці, щоб вивантажити всі repository/org/environment secrets. Використовуйте подвійне base64, щоб обійти GitHubs log masking, і декодуйте локально:
- Перелічіть всі secrets через secrets context (рівень collaborator). Контриб'ютор з правами запису може змінити workflow у будь-якій гілці, щоб вивантажити всі repository/org/environment secrets. Використовуйте подвійне base64, щоб обійти маскування логів GitHub та декодувати локально:
```yaml
name: Steal secrets
@@ -558,7 +558,7 @@ run: |
echo '${{ toJson(secrets) }}' | base64 -w0 | base64 -w0
```
Декодуйте локально:
Розкодувати локально:
```bash
echo "ZXdv...Zz09" | base64 -d | base64 -d
@@ -568,20 +568,20 @@ echo "ZXdv...Zz09" | base64 -d | base64 -d
### Зловживання Self-hosted runners
Щоб знайти, які **GitHub Actions виконуються поза інфраструктурою GitHub**, шукайте **`runs-on: self-hosted`** у конфігураційному yaml для Github Action.
Щоб знайти, які **Github Actions виконуються в інфраструктурі поза GitHub**, шукайте **`runs-on: self-hosted`** у конфігураційному yaml Github Action.
**Self-hosted** runners можуть мати доступ до **додаткової конфіденційної інформації**, до інших **мережевих систем** (вразливі endpoints у мережі? metadata service?) або, навіть якщо він ізольований і буде знищений, **можуть виконуватись більше ніж одна action одночасно**, і зловмисна дія може **вкрасти secrets** іншої.
**Self-hosted** ранери можуть мати доступ до **додаткової чутливої інформації**, інших **мережевих систем** (вразливі endpoints у мережі? metadata service?) або, навіть якщо вони ізольовані і видалені, **декілька action-ів можуть виконуватися одночасно**, і зловмисний може **вкрасти secrets** іншого.
На self-hosted runners також можливо отримати **secrets from the \_Runner.Listener**\_\*\* process\*\*, який міститиме всі secrets workflow на будь-якому кроці, шляхом дампу його пам'яті:
У self-hosted ранерах також можливо отримати **secrets from the \_Runner.Listener**\_\*\* process\*\*, який міститиме всі secrets workflow-ів на будь-якому кроці шляхом дампу його пам'яті:
```bash
sudo apt-get install -y gdb
sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')"
```
Перегляньте [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
Check [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
### Регістр Docker-образів у Github
### Github Docker Images Registry
Можна створити Github actions, які будуть **build and store a Docker image inside Github**.\
Можна створити Github actions, які **будуть збирати та зберігати Docker image всередині Github**.\
Приклад можна знайти в наступному розкривному блоці:
<details>
@@ -617,31 +617,31 @@ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ e
```
</details>
Як видно з попереднього коду, реєстр Github розміщено на **`ghcr.io`**.
Як ви могли побачити в попередньому коді, реєстр Github розміщено на **`ghcr.io`**.
Користувач із read permissions до repo зможе завантажити Docker Image, використовуючи personal access token:
Користувач з правами читання репозиторію зможе завантажити Docker Image, використовуючи personal access token:
```bash
echo $gh_token | docker login ghcr.io -u <username> --password-stdin
docker pull ghcr.io/<org-name>/<repo_name>:<tag>
```
Then, the user could search for **leaked secrets in the Docker image layers:**
Потім користувач може шукати **leaked secrets in the Docker image layers:**
{{#ref}}
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
{{#endref}}
### Sensitive info in Github Actions logs
### Чутлива інформація в Github Actions logs
Навіть якщо **Github** намагається **detect secret values** у actions logs і **не показувати** їх, **інші чутливі дані**, які могли бути згенеровані під час виконання action, не будуть приховані. Наприклад, JWT підписаний за допомогою secret value не буде прихований, якщо це не [specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
Навіть якщо **Github** намагається **виявляти secret values** в actions logs і **уникати їх показу**, **інші чутливі дані**, які могли бути згенеровані під час виконання action, не будуть приховані. Наприклад, JWT підписаний secret value не буде прихований, якщо він не [specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
## Приховування слідів
(Техніка з [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) По-перше, будь-який PR видно публічно на Github і для цільового облікового запису GitHub. За замовчуванням у GitHub ми **cant delete a PR of the internet**, але є тонкість. Для облікових записів Github, які були **suspended** GitHub, всі їхні **PRs are automatically deleted** і видаляються з інтернету. Тож щоб приховати свою активність, потрібно або домогтися **GitHub account suspended**, або щоб ваш обліковий запис був flagged. Це **приховає всі ваші активності** на GitHub з інтернету (фактично видалить всі ваші exploit PR).
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Перш за все, будь-який PR, що створюється, чітко видно публічно в Github і власнику цільового GitHub акаунта. За замовчуванням у GitHub ми **cant delete a PR of the internet**, але є нюанс. Якщо акаунт Github буде **suspended** GitHub, всі їхні **PRs are automatically deleted** і видаляються з інтернету. Тому, щоб приховати вашу активність, вам потрібно або домогтися, щоб ваш **GitHub account suspended or get your account flagged**. Це **приховає всю вашу активність** на GitHub з інтернету (фактично видалить усі ваші exploit PR)
Організація на GitHub дуже оперативно повідомляє акаунти до GitHub. Все, що потрібно — поділитися «деякими речами» в Issue, і вони подбають, щоб ваш акаунт був suspended протягом 12 годин :p і от ваш експлойт став невидимим на github.
Організація в GitHub дуже активно повідомляє облікові записи в GitHub. Все, що потрібно — опублікувати «деякі речі» в Issue, і вони подбають, щоб ваш акаунт був suspended протягом 12 годин :p і от, ваш exploit стане невидимим на github.
> [!WARNING]
> Єдиний спосіб для організації зясувати, що її атакували — перевірити GitHub logs через SIEM, оскільки з GitHub UI PR буде видалено.
> Єдиний спосіб для організації з'ясувати, що її атакували — перевірити GitHub logs через SIEM, оскільки з GitHub UI PR буде видалено.
## Посилання