Skip to content

Dieses Werkzeug ist weder mit GitHub, Inc. oder der Microsoft Corporation verbunden noch von ihnen unterstützt oder gesponsert. GitHub und GitHub Actions sind Marken von GitHub, Inc. Andere Namen sind Marken ihrer jeweiligen Inhaber.

Self-hosted Runner Sicherheit: Forensik für GitHub Actions

Fremde oder kompromittierte Self-hosted Runner in GitHub: relevante Audit-Log-Ereignisse, Spuren in _diag auf dem Host, Umfang bestimmen, Runner neu aufbauen.

Veröffentlicht am 6 Min. Lesezeit

Kurz gesagt. Self-hosted Runner sind ein GitHub-Risiko, das mitten in Ihrem Netzwerk steht. Es gibt zwei Szenarien. Ein fremder Runner: Ein Angreifer registriert seine eigene Maschine (org.register_self_hosted_runner / repo.register_self_hosted_runner) und erhält Ihre Jobs samt deren Secrets. Ein kompromittierter Runner: Nicht vertrauenswürdiger Code läuft auf Ihrem persistenten Host und bleibt dort. Das Audit-Log zeigt Ihnen, wann sich Runner und Runner-Gruppen geändert haben. Die Logs _diag/Runner_* und Worker_* auf dem Host zeigen Ihnen, was dort gelaufen ist. Entfernen Sie unbekannte Runner, bauen Sie jeden Host neu auf, der nicht vertrauenswürdige Jobs ausgeführt hat, und stellen Sie auf ephemere Runner in eingeschränkten Gruppen um.

GitHub-hosted Runner sind frische virtuelle Maschinen, die nach jedem Job verworfen werden. Self-hosted Runner (selbst gehostete Runner) sind das, was Sie ihnen geben: eine VM in Ihrer VPC, ein Pod in Ihrem Cluster oder ein Mac mini unter dem Schreibtisch. Sie haben oft Netzwerkzugriff auf interne Systeme und auf die Metadaten-Endpunkte der Cloud, und genau deshalb sind sie bei Angreifern so beliebt.

Warum Runner für Angreifer interessant sind

GitHubs Referenz zur sicheren Nutzung formuliert es deutlich. Bei Self-hosted Runnern gibt es keine Garantie, dass sie auf sauberen, ephemeren Maschinen laufen, und sie können durch nicht vertrauenswürdigen Code in einem Workflow dauerhaft kompromittiert werden. Für öffentliche Repositories sollten sie so gut wie nie eingesetzt werden. Bei privaten Repositories kann unter Umständen jeder, der einen Pull Request aus einem Fork öffnen darf, Code auf ihnen ausführen.

SzenarioWas der Angreifer bekommtATT&CK
Fremder Runner in der Organisation oder in einem Repository registriertJobs werden an seine Maschine geleitet, mit ausgechecktem Code, Secrets und GITHUB_TOKENT1072 Software Deployment Tools
Nicht vertrauenswürdiger Workflow auf einem persistenten RunnerCodeausführung in Ihrem Netzwerk, Persistenz zwischen Jobs, Zugriff auf die Secrets späterer JobsT1677 Poisoned Pipeline Execution
Runner-Gruppe erweitertSensible Runner (mit Zugang zum Produktionsnetz) stehen jetzt mehr Repositories zur Verfügungentfällt, eine Konfigurationsänderung

Was das Audit-Log aufzeichnet

Die Audit-Log-Ereignisse der Organisation decken den Lebenszyklus eines Runners ab:

AktionBedeutung
org.register_self_hosted_runner, repo.register_self_hosted_runnerEin Runner wurde registriert
org.configure_self_hosted_jit_runner, repo.configure_self_hosted_jit_runnerEin Just-in-time-Runner (für einen einzigen Job) wurde über die API konfiguriert
org.remove_self_hosted_runner, repo.remove_self_hosted_runnerEin Runner wurde entfernt
org.self_hosted_runner_online / _offline, repo.…Die Runner-Anwendung wurde gestartet oder beendet
org.self_hosted_runner_updatedDie Runner-Anwendung hat sich selbst aktualisiert
org.runner_group_created, org.runner_group_updated, org.runner_group_runners_added, org.runner_group_visiblity_updatedRunner-Gruppen und ihre Zugriffsrechte wurden geändert
org.update_repo_self_hosted_runners_policyEs wurde geändert, welche Repositories Runner auf Repository-Ebene anlegen dürfen

Der Analyzer löst self-hosted-runner-registered (mittel) für org., repo. und enterprise.register_self_hosted_runner aus. Die übrigen Aktionen oben sind keine Regeln. Sie erscheinen in der Ereignistabelle, und es lohnt sich, rund um jede Registrierung, die Sie nicht erklären können, danach zu filtern (runner ins Suchfeld eingeben).

Eine Registrierung lesen

Für die Registrierung eines Runners braucht man ein Registrierungstoken, das nach einer Stunde abläuft. Abrufen kann es nur, wer Admin-Rechte auf das Repository oder die Organisation hat oder ein Token mit gleichwertigen Rechten besitzt. Ist eine Registrierung verdächtig, stellen Sie deshalb folgende Fragen:

  • Wer ist der Akteur des Ereignisses? Prüfen Sie dieses Konto auf weitere Befunde (Token aus einem neuen Land, kürzlich vergebene Owner-Rechte).
  • Von wo? Eine Registrierung von einer IP-Adresse, die in Ihrer CI-Infrastruktur nie vorkommt, ist ein Alarmsignal.
  • Welcher Name, welche Labels? Fremde Runner verwenden oft Labels wie self-hosted, linux und x64, damit bestehende Workflows mit runs-on: [self-hosted, linux] sie übernehmen, ohne dass jemand eine YAML-Datei anfassen muss.
  • Welche Gruppe? Ein Runner in der Standardgruppe einer Organisation steht jedem Repository zur Verfügung, das diese Gruppe zulässt.

Was nur der Host verrät

Das Audit-Log zeigt nicht, welche Jobs auf welchem Runner gelaufen sind. Dafür brauchen Sie den Runner-Host selbst:

  • _diag/Runner_*.log: das Log der Runner-Anwendung. Pro Start gibt es eine Datei, benannt mit einem UTC-Zeitstempel. Es zeigt Registrierung, Verbindungen und Job-Zuweisungen.
  • _diag/Worker_*.log: ein detailliertes Log pro Job, den der Runner verarbeitet hat, einschließlich Repository und Workflow.
  • Das Arbeitsverzeichnis (_work/): ausgecheckte Repositories, Tool-Caches und Überbleibsel früherer Jobs. Angreifer legen dort Dateien ab, die spätere Jobs ausführen.
  • Übliche Host-Telemetrie: Prozessstarts, ausgehende Verbindungen, neue Cronjobs oder Dienste, SSH-Keys und Zugriffe auf die Instanz-Metadaten der Cloud.

Bei ephemeren Runnern weist GitHub darauf hin, dass die Runner-Logs an einen externen Speicher weitergeleitet werden müssen, sonst verschwinden sie mit der Maschine. Wenn Sie Runner auf Kubernetes mit dem Actions Runner Controller betreiben, gehören die Pod-Logs, das Kubernetes-Audit-Log und die Container-Runtime des Nodes zu den Beweisen. Diese Seite übernimmt das Schwesterwerkzeug Kubernetes Forensics.

Den Umfang eines Runner-Vorfalls bestimmen

  1. Listen Sie alle Runner auf (Organisation, Repositories, Enterprise) und gleichen Sie sie mit Ihrem Inventar ab. Unbekannte Namen oder IP-Adressen werden sofort entfernt, nachdem Sie ihre Details dokumentiert haben.
  2. Korrelieren Sie Registrierungen mit der übrigen Aktivität des Akteurs im Analyzer: Entitäten → Runner, dann über den Akteur und die IP-Adresse weiter pivotieren.
  3. Finden Sie die Jobs. Bei einem fremden Runner nutzen Sie die Ereignisse workflows.completed_workflow_run im Audit-Log für Workflows, die im fraglichen Zeitraum Self-hosted-Labels ansprechen, und dazu die Job-Logs selbst: Der Schritt „Set up job“ gibt den Namen des Runners und den Maschinennamen aus. Bei einem kompromittierten Host nutzen Sie die Worker_*-Logs.
  4. Gehen Sie davon aus, dass die Secrets dieser Jobs offengelegt sind. Rotieren Sie sie, einschließlich der Deploy-Zugangsdaten des Repositories und jeder Cloud-Rolle, die die Maschinenidentität des Runners übernehmen konnte.
  5. Bauen Sie neu auf: jeden persistenten Runner, der nicht vertrauenswürdigen Code ausgeführt hat. Bereinigen Sie ihn nicht, installieren Sie ihn neu.

Härtung

  • Setzen Sie ephemere Runner (./config.sh --ephemeral) oder Just-in-time-Runner ein. GitHub weist ihnen nur einen einzigen Job zu, was die Persistenz zwischen Jobs begrenzt. Siehe die Referenz zu Self-hosted Runnern.
  • Legen Sie sensible Runner in Runner-Gruppen, die auf bestimmte Repositories und Workflows beschränkt sind. Siehe Zugriff über Gruppen verwalten.
  • Unterbinden Sie Runner auf Repository-Ebene, sofern es keinen Grund dafür gibt. Owner der Organisation können einschränken, welche Repositories sie anlegen dürfen.
  • Verbinden Sie Self-hosted Runner niemals mit öffentlichen Repositories.
  • Geben Sie Runner-Hosts Cloud-Identitäten nach dem Least-Privilege-Prinzip und filtern Sie ausgehenden Verkehr. Viele Runner-Kompromittierungen werden über die Rolle der Instanz zu Cloud-Vorfällen.
  • Alarmieren Sie bei jeder Registrierung. In einer stabilen Organisation ist das ein seltenes Ereignis.

Verwandte Artikel

Verwandte Artikel

Wie GitHub-Actions-Secrets trotz ***-Maskierung leaken: manipulierte Workflows, neue Branches, kodierte Ausgaben, fremde Actions – und welche Beweise zählen.
Ein fiktiver Supply-Chain-Angriff auf GitHub, durchgehend untersucht: gestohlenes PAT, 38 Repos geklont, AWS-Keys per Workflow geleakt, Branch-Schutz entfernt.
AWS-, Google-Cloud- oder Azure-Keys aus GitHub Actions oder einem Repo geleakt: Key sperren, Nutzung in Cloud-Audit-Logs verfolgen, Keys durch OIDC ersetzen.

Dieses Werkzeug ist weder mit GitHub, Inc. oder der Microsoft Corporation verbunden noch von ihnen unterstützt oder gesponsert. GitHub und GitHub Actions sind Marken von GitHub, Inc. Andere Namen sind Marken ihrer jeweiligen Inhaber.