GitHub-Supply-Chain-Angriff untersuchen: ein Fallbeispiel
Ein fiktiver Supply-Chain-Angriff auf GitHub, durchgehend untersucht: gestohlenes PAT, 38 Repos geklont, AWS-Keys per Workflow geleakt, Branch-Schutz entfernt.
Kurz gesagt. Dieses Fallbeispiel verwendet den fiktiven Vorfall hinter der Schaltfläche „Beispiel testen“ des Werkzeugs (Organisation northwind-labs; Personen, Repositories, Tokens und IP-Adressen sind allesamt erfunden). Das klassische PAT eines Entwicklers wird um 01:58 UTC von einem VPS in den Niederlanden aus wiederverwendet. Es klont in etwa 18 Minuten 38 private Repositories, pusht einen Workflow auf einen neuen Branch, der die AWS-Deploy-Keys doppelt base64-kodiert ausgibt, fügt einen Deploy-Key mit Schreibrecht hinzu und entfernt die Branch Protection auf main. Der Analyzer liefert Kompromittiert mit 10 Befunden. Im Folgenden sehen Sie, wie Sie diese lesen und in welcher Reihenfolge Sie handeln.
Fiktives Szenario. Alles in diesem Artikel stammt aus
scripts/make-samples.py. Das Skript erzeugt das Beispiel, das die Schaltfläche „Beispiel testen“ des Werkzeugs lädt. Die IP-Adressen stammen aus Dokumentationsbereichen (RFC 5737), und das AWS-Schlüsselpaar ist das Dokumentationsbeispiel von AWS selbst. Ähnlichkeiten mit einer realen Organisation sind zufällig.
Die Ausgangslage
northwind-labs ist eine kleine Entwicklungsorganisation: ein Owner (c-okafor) und drei Entwickler (m-hernandez, j-lindqvist, a-nowak), die überwiegend aus Frankreich und Schweden und zu Bürozeiten arbeiten. Die Beweise sind die drei Dateien, die ein Ermittler realistischerweise sammeln würde, jeweils im echten Exportformat:
| Datei | Quelle | Inhalt |
|---|---|---|
northwind-labs-audit-log.json | Audit-Log der Organisation, JSON-Export aus der UI | Änderungen an Mitgliedern, Workflow-Läufe, Secrets, Keys, Branch Protection |
export-northwind-labs-1789360000.json.gz | Git-Events-Export | git.clone / git.fetch / git.push mit Token-Metadaten |
northwind-labs-actions-run-4412.zip | „Download log archive“ eines Laufs | Schrittprotokolle des verdächtigen Workflow-Laufs |
Die Vergleichsbasis umfasst drei Wochen (2026-08-24 bis 2026-09-13). Das ist wichtig, denn die Regeln für neue Länder und neue IP-Adressen brauchen eine Historie, mit der sie vergleichen können.
Schritt 1: das Urteil
Ziehen Sie die drei Dateien in das Werkzeug (oder klicken Sie auf Beispiel testen). Das Banner zeigt Kompromittiert. Unter Warum stehen die vier Befunde, die zu diesem Urteil geführt haben: actions-secret-exfil (kritisch) sowie token-new-country, git-clone-burst und branch-protection-removed (hoch). Die Hinweise zur Abdeckung sind leer. IP-Adressen, Git-Events und Token-Metadaten sind vorhanden, keine Regel war also blind.
Die vollständige Liste, wie der Analyzer sie ausgibt:
| Schweregrad | Regel | Wann (UTC, 2026-09-14, sofern nicht anders angegeben) | Was |
|---|---|---|---|
| kritisch | actions-secret-exfil | 02:40:08 | Das Skript des Schritts leitet die AWS-Keys zweimal durch base64. Nächster Schritt: AWS |
| hoch | token-new-country | 01:58:12 → 03:06:30 | 43 Ereignisse aus NL für ein Token, das bisher nur in FR auftauchte |
| hoch | git-clone-burst | 02:14:00 → 02:31:53 | 38 verschiedene Repositories von 203.0.113.66 aus geklont |
| hoch | branch-protection-removed | 03:05:44 | main in payments-api |
| mittel | actions-encoded-output | 02:40:08 | Lange Base64-Zeichenkette im selben Schritt ausgegeben |
| mittel | deploy-key-added | 02:52:03 | Key backup-sync auf infra-terraform, mit Schreibrecht |
| niedrig | token-new-ip | 01:58:12 → 03:06:30 | Dieselben 43 Ereignisse, neue IP-Adresse |
| niedrig | workflow-new-branch | 02:39:40 | Workflow CI läuft zum ersten Mal auf ci/cache-fix |
| niedrig | actions-secret-created | 2026-09-08 | a-nowak hat die AWS-Secrets angelegt, legitim |
| niedrig | webhook-created | 2026-09-03 | a-nowak hat einen CI-Webhook angelegt, legitim |
Die letzten beiden sind das ehrliche Grundrauschen jeder echten Organisation: Routine-Administration, die die Regeln melden, weil sie relevant sein könnte. Sie haben weder Akteur noch Token noch IP-Adresse mit dem Rest gemeinsam, Sie können sie also beiseitelegen.
Schritt 2: welche Zugangsdaten?
Öffnen Sie token-new-country. Die zugehörigen Entitäten sind der Akteur m-hernandez, ein hashed_token und die IP-Adresse 203.0.113.66. Pivotieren Sie über das Token (Entitäten → Tokens → Ereignisse zeigen). Es ist ein Personal access token (classic) mit den Scopes repo, workflow, read:org. Drei Wochen lang wurde es tagsüber von 198.51.100.23 (FR) mit dem User-Agent git/2.39.5 (Apple Git-154) verwendet. Ab 01:58 UTC am 2026-09-14 taucht es von 203.0.113.66 (NL) mit git/2.43.0 auf, später mit curl/8.5.0.
Dieselbe Person, dasselbe Token, eine andere Maschine, ein anderes Land, mitten in der Nacht: Das Token wurde wiederverwendet. Der Scope workflow erklärt, wie der Angreifer eine Workflow-Datei pushen konnte. Im Szenario ist die Quelle ein Infostealer auf dem Laptop des Entwicklers. Diesen Teil können die GitHub-Logs nicht zeigen, und genau deshalb besteht das Playbook zum geleakten Token darauf, den Endpunkt zu prüfen.
Schritt 3: was wurde abgegriffen?
git-clone-burst zählt 38 verschiedene Repositories. In den Git-Events laufen die Klonvorgänge von 02:14:00 bis 02:31:53, etwa einer alle 29 Sekunden. Dieser gleichmäßige Takt ist geskriptet. m-hernandez arbeitet normalerweise mit vier Repositories (payments-api, billing-worker, ledger, web-app). Die Häufung umfasst infra-terraform, secrets-rotation, kyc-service und terraform-modules, Repositories, in die diese Person nie gepusht hat.
Fazit für den Bericht: Quellcode und vollständige Historie von 38 Repositories befinden sich in den Händen des Angreifers. Daraus folgt die Maßnahme „Geklonten Code als geleakt behandeln“: Durchsuchen Sie diese Historien nach Secrets und rotieren Sie, was Sie finden. Der Artikel zur Exfiltration von Repositories beschreibt, wie Sie den Umfang bestimmen.
Schritt 4: was wurde verändert?
Lesen Sie die Zeitleiste mit Nur Befunde:
- 02:39:21
git.pushaufpayments-apivom VPS aus. - 02:39:40
workflows.created_workflow_run: WorkflowCI, Ereignispush, Branchci/cache-fix. Das ist der erste Lauf auf diesem Branch, also schlägtworkflow-new-branchan. - 02:40:08 Im Protokollarchiv des Laufs
4412führt der Schritt Restore build cacheecho "$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY" | base64 -w0 | base64 -w0aus und gibt eine lange Zeichenkette aus. Die Maskierung greift nicht, weil der Wert kodiert war. Zweimal dekodiert ergibt sich das Schlüsselpaar (hier das Dokumentationsbeispiel von AWS).actions-secret-exfilschlägt als kritisch an, mit AWS als nächstem Schritt, undactions-encoded-outputschlägt bei der Zeichenkette an. - 02:52:03
public_key.createaufinfra-terraform: Titelbackup-sync,read_only: false, User-Agentcurl/8.5.0. Ein Deploy-Key mit Schreibrecht ist Persistenz, die den Widerruf des PAT übersteht. - 03:05:44
protected_branch.destroyaufpayments-api/main. Die Regel verlangte zwei zustimmende Reviews. - 03:06:30
git.pushaufpayments-api, eine Minute nachdem der Schutz entfernt wurde. - 07:48:10
protected_branch.createdurchc-okaforaus dem Büro: Der Owner hat es bemerkt und die Regel wiederhergestellt.
Schritt 6 sollte Ihnen die größten Sorgen machen. Etwas wurde ohne Review auf main gepusht. Das Audit-Log enthält den Diff nicht, der Commit muss also im Repository geprüft werden (siehe Branch Protection deaktiviert).
Schritt 5: Bereinigung in der Reihenfolge des Werkzeugs
Der Tab Maßnahmen sortiert die Checkliste nach Dringlichkeit:
- Beweise sichern: Audit-Log und Git-Events erneut exportieren und das Protokollarchiv des Laufs aufbewahren, bevor jemand die Protokolle von Lauf 4412 löscht.
- Alle erreichbaren Actions-Secrets rotieren: sämtliche Secrets, die Workflows in
payments-apilesen können, nicht nur die beiden AWS-Secrets. - Cloud-Zugangsdaten rotieren und die Cloud untersuchen: den AWS-Key deaktivieren und CloudTrail ab 02:40 UTC durchsuchen. Siehe Geleakte Cloud-Keys in GitHub Actions und AWS Forensics.
- Workflow-Änderungen und -Läufe prüfen:
.github/workflowsaufci/cache-fixvergleichen, den Branch löschen und CODEOWNERS-Reviews für Workflow-Dateien verlangen. - Das Token widerrufen und das Konto zurücksetzen, nachdem der Laptop neu aufgesetzt wurde.
- Geklonten Code als geleakt behandeln: die Historie der 38 Repositories durchsuchen.
- Branch-Schutz wiederherstellen und Eingänge prüfen: den Push um 03:06.
- Persistenz entfernen: den Deploy-Key
backup-synclöschen und nach allem suchen, was sonst noch von203.0.113.66aus angelegt wurde.
Was dieses Beispiel nicht zeigt
Echte Vorfälle sind unübersichtlicher. Hier gibt es keine Übernahme durch einen Owner, keinen Self-hosted Runner und keinen entfernten Audit-Stream. Der Angreifer hat seine Aktivität auch nicht über Tage verteilt, um unter den Schwellenwerten zu bleiben. Wenn eine Regel bei Ihren Daten nicht angeschlagen hat, prüfen Sie die Hinweise zur Abdeckung und lesen Sie, was das Audit-Log nicht aufzeichnet, bevor Sie Schlüsse ziehen.