Supply Chain Angriff - Software-Lieferkette als Angriffsvektor
Supply Chain Angriffe kompromittieren Software oder Hardware bevor sie beim Ziel ankommen: SolarWinds (18.000 Opfer, SUNBURST-Backdoor), XZ Utils Backdoor (CVE-2024-3094), npm-Typosquatting, Dependency Confusion, Malicious NPM-Packages, CI/CD-Pipeline-Kompromittierung. Schutz: SBOM (CycloneDX/SPDX), SLSA Framework, Sigstore/Cosign für Package-Signing, private Registry, Dependency Pinning.
Supply Chain Angriffe kompromittieren nicht das Ziel direkt, sondern einen vertrauenswürdigen Lieferanten oder eine Abhängigkeit. Das Opfer installiert selbst die kompromittierte Software - und vertraut ihr dabei vollständig.
Das Supply-Chain-Konzept
Warum Supply Chain so effektiv ist
Bei einem direkten Angriff muss der Angreifer viele Sicherheitshürden überwinden: Firewall, EDR und MFA stehen zwischen ihm und dem Ziel.
Bei einem Supply-Chain-Angriff ist der Weg zum Ziel dagegen elegant einfach: Angreifer → Lieferant/Paket → Ziel vertraut Update → Backdoor.
Die Vorteile für Angreifer sind erheblich:
- Signierter Code: EDR-Erkennung wird umgangen, da ein legitimes Zertifikat vorliegt
- Hohe Reichweite: Ein kompromittierter Lieferant trifft tausende Opfer gleichzeitig
- Vertrauen ausgenutzt: “Wir haben das Update immer installiert” - Sicherheitsteams überprüfen vertraute Updates selten
- Persistenz: Das Update kommt als normaler Geschäftsprozess und fällt nicht auf
Bekannte Angriffsvektoren
- Software-Updates (SolarWinds, 3CX)
- Open-Source-Pakete (NPM, PyPI, RubyGems)
- CI/CD-Pipelines (Build-Server kompromittiert)
- Container-Images (DockerHub, Harbor)
- Hardware (präparierte Chips/Netzwerkgeräte)
- Managed Service Providers (MSP → Kunden)
SolarWinds - Der Meisterfall
Timeline
| Datum | Ereignis |
|---|---|
| Oktober 2019 | Angreifer dringen in SolarWinds-Netzwerk ein |
| März 2020 | SUNBURST-Backdoor in Orion 2019.4.5280.20438 eingebettet |
| März 2020 | Signiertes Update an ~18.000 Kunden verteilt |
| Dezember 2020 | FireEye entdeckt den Angriff, Öffentlichmachung |
SUNBURST Mechanismus
Die Backdoor war in SolarWinds.Orion.Core.BusinessLayer.dll eingebettet. Nach der Installation wartete sie 12-14 Tage in einem Dormancy-Zustand, um Sandbox-Erkennungssysteme zu umgehen. Die C2-Kommunikation erfolgte über DNS-Anfragen mit verschlüsselten Beacons an Domains, die durch einen Domain Generation Algorithm (DGA) erzeugt wurden - Basis war avsvmcloud.com. Die Backdoor aktivierte sich nur, wenn keine Analysetools wie Wireshark oder IDA laufend erkannt wurden.
Opfer
Zu den Betroffenen zählten das US-Finanzministerium, DHS, Justizministerium und NSA, sowie Microsoft, Intel, Cisco und FireEye. Insgesamt waren über 100 US-Bundesbehörden betroffen, und die Angreifer hatten nahezu vollständigen Zugang für etwa 9 Monate.
Lektionen aus SolarWinds
- Code-Signing ist keine Sicherheitsgarantie - das Zertifikat war vollständig legitim
- Build-Environments sind Angriffsfläche - nicht nur der Code selbst
- DNS-Monitoring ist essenziell - auch für vertrauenswürdige IT-Tools
XZ Utils Backdoor (2024)
Was passiert wäre
XZ Utils ist eine Komprimierungsbibliothek, die in nahezu jeder Linux-Distribution vorhanden ist. Die geplante Backdoor hätte die SSH-Authentifizierung auf allen betroffenen Systemen kompromittiert. Mit einem eingebetteten Ed448-Schlüssel hätte der Angreifer unbegrenzte Root-Zugänge auf Millionen von Servern weltweit gehabt.
Der Social Engineering-Teil (2 Jahre)
Ab 2022 begann ein Account namens “Jia Tan” regelmäßige Beiträge zu XZ Utils auf GitHub zu leisten und baute über ein Jahr hinweg Vertrauen auf, bis er Co-Maintainer wurde. 2024 wurde unter falschem Druck - eine inszenierte “Maintainer burnout”-Situation - die Übergabe von Kontrolle angeboten. Nachdem Commit-Zugänge erhalten wurden, wurde im Februar 2024 die Backdoor in Release 5.6.0 eingebaut.
Backdoor-Technik
Die Backdoor war ausschließlich im Binär-Tarball enthalten, nicht im Git-Repository selbst. Testdateien (tests/*.xz) enthielten verschlüsselten Backdoor-Code, der durch das CMake-Build-System extrahiert und kompiliert wurde. Der Code lud sich in den systemd-sshd-Prozess und ersetzte die RSA-Key-Decryption-Funktion, um Command Injection zu ermöglichen.
Entdeckung durch Zufall
Andres Freund (Microsoft) bemerkte, dass SSH-Logins auf Debian unstable 500 Millisekunden langsamer waren als erwartet. CPU-Profiling führte ihn zu xz-utils. Er meldete den Fund am 29. März 2024.
Schutzmaßnahmen
- Binary Transparency: Build-Reproduzierbarkeit verifizieren
- Reproducible Builds: Gleicher Source-Code sollte ein bit-identisches Binary erzeugen
- SBOM-Monitoring: Wann hat sich eine Abhängigkeit geändert?
NPM/PyPI-Paket-Angriffe
1. Typosquatting
Angreifer registrieren Pakete mit Namen die legitimen sehr ähnlich sind:
| Legitim | Bösartig |
|---|---|
lodash | 1odash (Ziffer statt l) |
lodash | lodas |
lodash | lodash-utils |
Bekannte Fälle:
event-stream(2018): 2 Millionen Downloads/Woche, Ziel war Bitcoin-Wallet-Diebstahlua-parser-js(2021): 7 Millionen Downloads/Woche kompromittiertnode-ipc(2022): Maintainer fügte Wiper-Code als politisches Statement ein
2. Dependency Confusion
# Internes Paket: "@company/internal-utils" v1.0.0 (privat)
# Angreifer: "@company/internal-utils" v9.0.0 (öffentlich → höhere Version!)
# npm install → installiert v9.0.0 von öffentlichem NPM!
Dieser Angriff wurde bei Apple, Microsoft, PayPal, Tesla und Shopify nachgewiesen. Bug-Bounty-Auszahlungen erreichten bis zu 30.000 USD.
3. Account Takeover (Maintainer-Übernahme)
Angreifer erlangen Zugang zum Maintainer-Account über Credential Stuffing mit geleakten Passwörtern oder durch Kompromittierung des Maintainer-PCs und Token-Exfiltration. Anschließend publizieren sie ein bösartiges Update.
Scanning-Tools
# npm-audit (eingebaut):
npm audit --production
# OWASP Dependency Check:
dependency-check.sh --scan ./node_modules --format HTML
# Socket.dev (Echtzeit-Paket-Intelligence):
npx @socketsecurity/cli scan
# Snyk Open Source:
snyk test --all-projects
CI/CD Pipeline Kompromittierung
Angriffsvektoren
Secrets in Pipeline-Konfigurationen: Falsch konfigurierte Secrets können in Build-Logs lesbar sein.
Poisoned Pipeline Execution (PPE): Ein Fork des Repos löst über einen Pull Request eine CI-Pipeline mit Write-Zugang aus. Angreifer modifizieren dabei env.yml, Jenkinsfile oder .github/workflows/-Dateien.
Dependency im Build Process: Angreifer kompromittieren ein Build-Tool (Make, Gradle Plugin, Maven Plugin).
GitHub Actions Sicherheit
# FALSCH - keine gepinnte Version:
uses: actions/checkout@main
# RICHTIG - gepinnt auf Commit-SHA:
uses: actions/checkout@v4.2.2
# Oder per SHA:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
# OIDC statt langlebige Secrets:
permissions:
id-token: write
contents: read
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/GitHubActionsRole
aws-region: eu-central-1
# → Kein AWS_SECRET_ACCESS_KEY im Repository!
# Step Summary statt echo-Ausgabe (verhindert Log-Injection):
echo "Deploy complete" >> $GITHUB_STEP_SUMMARY
SBOM und SLSA Framework
Software Bill of Materials (SBOM)
Eine SBOM ist eine maschinenlesbare Stückliste aller Softwarekomponenten. Die gängigen Formate sind CycloneDX (OWASP, JSON/XML) und SPDX (Linux Foundation).
# Syft (Anchore, kostenlos):
syft packages dir:. -o cyclonedx-json > sbom.json
# CycloneDX für NPM:
npm install -g @cyclonedx/cyclonedx-npm
cyclonedx-npm --output-file sbom.json
# GitHub Actions Integration:
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
artifact-name: sbom.spdx.json
format: spdx-json
SBOM-Nutzen: Bei Log4Shell war sofort ersichtlich, ob log4j im Stack vorhanden war. Bei XZ Utils konnten alle betroffenen Systeme sofort identifiziert werden. Bei M&A ermöglicht die SBOM eine vollständige Due-Diligence zu Lizenzrisiken und Schwachstellen.
SLSA Framework (Supply-chain Levels for Software Artifacts)
| Level | Beschreibung |
|---|---|
| Level 1 | Dokumentierter Build-Prozess, Build-Logs vorhanden, SBOM generiert |
| Level 2 | Build-Service und Versionskontrolle: signierte Provenienz, authentifizierter Build-Service |
| Level 3 | Gehärteter Build-Prozess: kein Netzwerkzugang während Build, Ephemeral-Build-Environment |
| Level 4 | Reproduzierbare Builds (höchste Sicherheit): bit-identisches Binary bei gleichem Quellcode |
# SLSA GitHub Actions:
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
Schutzmaßnahmen
1. Dependency Pinning und Lock Files
# NPM - package-lock.json niemals ignorieren:
npm ci # statt npm install (nutzt Lock File!)
# Python - requirements.txt mit exakten Versionen:
requests==2.31.0
# pip-compile (pip-tools) für reproduzierbare Umgebungen:
pip-compile requirements.in
// Renovate-Konfiguration für automatische Update-PRs:
{
"extends": ["config:base"],
"vulnerabilityAlerts": {"enabled": true},
"schedule": ["before 5am on monday"]
}
2. Dependency Confusion Schutz
# .npmrc - interne Pakete immer von eigenem Registry:
@company:registry=https://registry.company.internal
# Oder: scoped packages auf privater Registry registrieren
3. Sigstore/Cosign - Container-Image-Signing
# Image signieren:
cosign sign --key cosign.key ghcr.io/company/app:v1.0.0
# Signatur verifizieren:
cosign verify --key cosign.pub ghcr.io/company/app:v1.0.0
# Kubernetes Policy (Kyverno): verweigert unsigned images automatisch
4. Private Registry und Allowlisting
Nexus oder JFrog Artifactory als Proxy einsetzen: Alle Downloads laufen durch die eigene Registry, bekannte Pakete werden gecacht und gescannt, neue Pakete durchlaufen einen manuellen Approval-Prozess.
5. Monitoring und Alerting
# GitHub Dependency Review Action:
- uses: actions/dependency-review-action@v4
with:
fail-on-severity: moderate
deny-licenses: GPL-2.0, AGPL-3.0
Wenn sich eine Dependency ändert, sollte sofort ein Alert ausgelöst werden.