Abusing Github Actions
Last updated
Last updated
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
На цій сторінці ви знайдете:
резюме всіх наслідків для зловмисника, який зміг отримати доступ до Github Action
Різні способи отримати доступ до дії:
Маючи дозволи на створення дії
Зловживання тригерами, пов'язаними з pull request
Зловживання іншими зовнішніми техніками доступу
Півотинг з уже скомпрометованого репозиторію
Нарешті, розділ про техніки пост-експлуатації для зловживання дією зсередини (оскільки це викликає згадані наслідки)
Для введення про Github Actions перевірте основну інформацію.
Якщо ви можете виконувати довільний код у GitHub Actions в межах репозиторію, ви можете:
Викрасти секрети, змонтовані в конвеєрі, та зловживати привілеями конвеєра для отримання несанкціонованого доступу до зовнішніх платформ, таких як AWS та GCP.
Скомпрометувати розгортання та інші артефакти.
Якщо конвеєр розгортає або зберігає активи, ви можете змінити кінцевий продукт, що дозволяє здійснити атаку на ланцюг постачання.
Виконувати код у кастомних робітниках для зловживання обчислювальною потужністю та півотингу до інших систем.
Перезаписувати код репозиторію, залежно від дозволів, пов'язаних з GITHUB_TOKEN
.
Цей "секрет" (який походить з ${{ secrets.GITHUB_TOKEN }}
та ${{ github.token }}
) надається, коли адміністратор активує цю опцію:
Цей токен є тим самим, який буде використовувати Github Application, тому він може отримати доступ до тих самих кінцевих точок: https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps
Github повинен випустити потік, який дозволяє крос-репозиторний доступ у GitHub, щоб репозиторій міг отримати доступ до інших внутрішніх репозиторіїв, використовуючи GITHUB_TOKEN
.
Ви можете переглянути можливі дозволи цього токена за адресою: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
Зверніть увагу, що токен закінчує термін дії після завершення роботи.
Ці токени виглядають так: ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7
Деякі цікаві речі, які ви можете зробити з цим токеном:
Зверніть увагу, що в кількох випадках ви зможете знайти токени користувача github всередині середовищ Github Actions або в секретах. Ці токени можуть надати вам більше привілеїв над репозиторієм та організацією.
Можливо перевірити дозволи, надані Github Token в репозиторіях інших користувачів, перевіряючи журнали дій:
Це був би найпростіший спосіб скомпрометувати Github дії, оскільки цей випадок передбачає, що у вас є доступ до створення нового репозиторію в організації або права на запис у репозиторії.
Якщо ви в цьому сценарії, ви можете просто перевірити техніки постексплуатації.
У випадку, якщо члени організації можуть створювати нові репозиторії і ви можете виконувати github дії, ви можете створити новий репозиторій і вкрасти секрети, встановлені на рівні організації.
Якщо ви можете створити нову гілку в репозиторії, який вже містить налаштовану Github Action, ви можете модифікувати її, завантажити вміст, а потім виконати цю дію з нової гілки. Таким чином, ви можете екстрагувати секрети на рівні репозиторію та організації (але вам потрібно знати, як вони називаються).
Ви можете зробити модифіковану дію виконуваною вручну, коли створюється PR або коли якийсь код завантажується (залежно від того, наскільки помітними ви хочете бути):
Існують різні тригери, які можуть дозволити зловмиснику виконати Github Action з іншого репозиторію. Якщо ці тригери налаштовані неналежним чином, зловмисник може їх скомпрометувати.
pull_request
Тригер робочого процесу pull_request
буде виконувати робочий процес щоразу, коли отримується запит на злиття з деякими винятками: за замовчуванням, якщо це перше співробітництво, деякий керівник повинен схвалити виконання робочого процесу:
Оскільки за замовчуванням обмеження стосується перших учасників, ви можете внести виправлення дійсної помилки/друкарської помилки і потім надіслати інші PR, щоб зловживати вашими новими привілеями pull_request
.
Я це протестував, і це не працює: Інший варіант - створити обліковий запис з ім'ям когось, хто вніс внесок у проект, і видалити його обліковий запис.
Більше того, за замовчуванням запобігає запису прав і доступу до секретів цільового репозиторію, як зазначено в документації:
За винятком
GITHUB_TOKEN
, секрети не передаються виконавцю під час тригера робочого процесу з форкнутого репозиторію. `GITHUB_TOKEN має права лише на читання у запитах на злиття з форкнутими репозиторіями.
Зловмисник може змінити визначення Github Action, щоб виконати довільні дії та додати довільні дії. Однак він не зможе вкрасти секрети або перезаписати репозиторій через зазначені обмеження.
Так, якщо зловмисник змінить у PR github action, який буде тригеритися, його Github Action буде використано, а не той, що з оригінального репозиторію!
Оскільки зловмисник також контролює код, що виконується, навіть якщо немає секретів або прав на запис у GITHUB_TOKEN
, зловмисник може, наприклад, завантажити шкідливі артефакти.
pull_request_target
Тригер робочого процесу pull_request_target
має права на запис до цільового репозиторію та доступ до секретів (і не запитує дозволу).
Зверніть увагу, що тригер робочого процесу pull_request_target
виконується в базовому контексті і не в тому, що надається PR (щоб не виконувати ненадійний код). Для отримання додаткової інформації про pull_request_target
перевірте документацію.
Більше того, для отримання додаткової інформації про це конкретне небезпечне використання перевірте цей пост у блозі github.
Це може виглядати так, ніби виконуваний робочий процес є тим, що визначено в базі, а не в PR, тому це безпечно використовувати pull_request_target
, але є кілька випадків, коли це не так.
І цей тригер матиме доступ до секретів.
workflow_run
Тригер workflow_run дозволяє запустити робочий процес з іншого, коли він завершений
, запитаний
або в процесі
.
У цьому прикладі робочий процес налаштований на виконання після завершення окремого робочого процесу "Запустити тести":
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.
Цей тип робочого процесу може бути атакований, якщо він залежить від робочого процесу, який може бути запущений зовнішнім користувачем через pull_request
або pull_request_target
. Кілька вразливих прикладів можна знайти в цьому блозі. Перший з них полягає в тому, що workflow_run
запущений робочий процес завантажує код атакуючого: ${{ github.event.pull_request.head.sha }}
Другий полягає в передачі артефакту з недовіреного коду до workflow_run
робочого процесу та використанні вмісту цього артефакту таким чином, що він стає вразливим до RCE.
workflow_call
TODO
TODO: Перевірити, чи при виконанні з pull_request використовується/завантажується код з оригіналу чи з форкнутого PR
Ми згадали всі способи, якими зовнішній атакуючий може змусити робочий процес github виконатися, тепер давайте розглянемо, як ці виконання, якщо погано налаштовані, можуть бути зловживані:
У випадку pull_request
, робочий процес буде виконуватися в контексті PR (тому він виконає код шкідливого PR), але хтось повинен спочатку його авторизувати і він буде виконуватися з деякими обмеженнями.
У випадку робочого процесу, що використовує pull_request_target
або workflow_run
, який залежить від робочого процесу, що може бути запущений з pull_request_target
або pull_request
, код з оригінального репозиторію буде виконуватися, тому атакуючий не може контролювати виконуваний код.
Однак, якщо дія має явний чекаут PR, який отримає код з PR (а не з бази), вона буде використовувати код, контрольований атакуючим. Наприклад (перевірте рядок 12, де завантажується код PR):
Потенційно недовірений код виконується під час npm install
або npm build
, оскільки скрипти збірки та згадані пакети контролюються автором PR.
Гітхаб дорк для пошуку вразливих дій: event.pull_request pull_request_target extension:yml
, однак існують різні способи налаштування робочих процесів для безпечного виконання, навіть якщо дія налаштована ненадійно (наприклад, використовуючи умовні оператори про те, хто є актором, що генерує PR).
Зверніть увагу, що є певні контексти github, значення яких контролюються користувачем, що створює PR. Якщо дія github використовує ці дані для виконання чогось, це може призвести до випадкового виконання коду:
Gh Actions - Context Script InjectionsЗ документів: Ви можете зробити змінну середовища доступною для будь-яких наступних кроків у робочому процесі, визначивши або оновивши змінну середовища та записавши це у файл середовища GITHUB_ENV
.
Якщо атакуючий може впровадити будь-яке значення в цю змінну env, він може впровадити змінні середовища, які можуть виконати код у наступних кроках, такі як LD_PRELOAD або NODE_OPTIONS.
Наприклад (це і це), уявіть робочий процес, який довіряє завантаженому артефакту для зберігання його вмісту в змінній середовища GITHUB_ENV
. Атакуючий може завантажити щось на зразок цього, щоб скомпрометувати його:
Як згадано в цьому блозі, ця дія Github дозволяє отримувати артефакти з різних робочих процесів і навіть репозиторіїв.
Проблема в тому, що якщо параметр path
не встановлений, артефакт витягується в поточний каталог і може перезаписати файли, які можуть бути пізніше використані або навіть виконані в робочому процесі. Тому, якщо артефакт вразливий, атакуючий може зловживати цим, щоб скомпрометувати інші робочі процеси, які довіряють артефакту.
Приклад вразливого робочого процесу:
Це можна атакувати за допомогою цього робочого процесу:
Якщо обліковий запис змінює своє ім'я, інший користувач може зареєструвати обліковий запис з цим ім'ям через деякий час. Якщо репозиторій мав менше 100 зірок до зміни імені, Github дозволить новому зареєстрованому користувачу з таким же ім'ям створити репозиторій з таким же ім'ям, як і видалений.
Отже, якщо дія використовує репозиторій з неіснуючого облікового запису, все ще можливо, що зловмисник може створити цей обліковий запис і скомпрометувати дію.
Якщо інші репозиторії використовували залежності з репозиторіїв цього користувача, зловмисник зможе їх викрасти. Тут ви маєте більш детальне пояснення: https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/
У цьому розділі ми поговоримо про техніки, які дозволять пивотувати з одного репозиторію в інший, припускаючи, що у нас є якийсь доступ до першого (перевірте попередній розділ).
Кеш підтримується між виконаннями робочого процесу в одному гілці. Це означає, що якщо зловмисник скомпрометує пакет, який потім зберігається в кеші і завантажується та виконується більш привілейованим робочим процесом, він зможе також скомпрометувати цей робочий процес.
GH Actions - Cache PoisoningРобочі процеси можуть використовувати артефакти з інших робочих процесів і навіть репозиторіїв, якщо зловмисник зможе скомпрометувати Github Action, яка завантажує артефакт, що пізніше використовується іншим робочим процесом, він може скомпрометувати інші робочі процеси:
Gh Actions - Artifact PoisoningПеревірте наступні сторінки:
AWS - Federation AbuseGCP - Federation AbuseЯкщо ви впроваджуєте вміст у скрипт, цікаво знати, як ви можете отримати доступ до секретів:
Якщо секрет або токен встановлено в змінну середовища, його можна безпосередньо отримати через середовище, використовуючи printenv
.
Якщо секрет використовується безпосередньо в виразі, згенерований shell-скрипт зберігається на диску і доступний.
cat /home/runner/work/_temp/*
Для кастомної дії ризик може варіюватися в залежності від того, як програма використовує секрет, отриманий з аргументу:
Спосіб знайти, які Github Actions виконуються в не-Github інфраструктурі, - це шукати runs-on: self-hosted
в конфігураційному yaml файлі Github Action.
Самостійно розгорнуті виконавці можуть мати доступ до додаткової чутливої інформації, до інших мережевих систем (вразливі кінцеві точки в мережі? служба метаданих?) або, навіть якщо вони ізольовані та знищені, більше ніж одна дія може виконуватись одночасно і зловмисна може викрасти секрети іншої.
У самостійно розгорнуті виконавці також можливо отримати секрети з процесу _Runner.Listener_** який міститиме всі секрети робочих процесів на будь-якому етапі, скидаючи його пам'ять:
Перевірте цей пост для отримання додаткової інформації.
Можливо створити Github дії, які будують і зберігають Docker-образ всередині Github. Приклад можна знайти в наступному розширювальному:
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)