Executive summary
The US Cybersecurity and Infrastructure Security Agency (CISA) added CVE-2026-33634, embedded malicious code in Aqua Security's Trivy scanner, to its Known Exploited Vulnerabilities (KEV) catalogue on 26 March 2026. Aqua's advisory says a threat actor used compromised credentials on 19 March to publish a malicious Trivy v0.69.4 release and to force-push 76 of 77 trivy-action tags and all 7 setup-trivy tags to malicious commits; Wiz reports that the actor self-identifies as TeamPCP. Wiz has since attributed compromises of Checkmarx's KICS GitHub Action on 23 March and the LiteLLM Python package on 24 March to TeamPCP, and JFrog reported on 27 March that malicious telnyx releases on the Python Package Index (PyPI) use the same public key as the LiteLLM compromise. PyPI's advisory traces the LiteLLM releases to an application programming interface (API) token exposed through an exploited Trivy dependency. We assess it is likely (B2) that TeamPCP will use credentials taken in these compromises to reach further packages or pipelines in the coming weeks, so organisations that ran an affected version should rotate every secret that version could reach.
Contextual background
Wiz describes Trivy as Aqua Security's vulnerability scanner, with two GitHub Actions, trivy-action and setup-trivy. Aqua's blog post, as archived on 26 March, says attackers exploited a misconfiguration in Trivy's GitHub Actions environment in late February 2026 and extracted a privileged access token. The Trivy team disclosed that incident on 1 March and rotated credentials, but Aqua says the rotation was not fully comprehensive, leaving the actor residual access. Aqua's GitHub Security Advisory (GHSA), published on 21 March and archived on 27 March, is more cautious: the rotation was not atomic, and that could have allowed the attacker to retain access.
CISA's 26 March alert says it added the flaw “based on evidence of active exploitation”. In the catalogue as published on 27 March, the Aquasecurity Trivy entry carries Common Weakness Enumeration (CWE) entry CWE-506, a due date of 9 April 2026 and known ransomware campaign use “Unknown”. It says the flaw could allow an attacker to gain access to everything in the continuous integration and continuous delivery (CI/CD) environment, including all tokens, Secure Shell (SSH) keys, cloud credentials, database passwords and any sensitive configuration in memory. The required action is to apply mitigations per vendor instructions, follow applicable Binding Operational Directive (BOD) 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable, and the note says additional vendor-provided guidance must be followed to ensure full remediation. BOD 22-01 binds Federal Civilian Executive Branch (FCEB) agencies to the due date.
In the National Vulnerability Database (NVD) change history, the initial analysis of 26 March lists litellm 1.82.7 and 1.82.8 in the Common Vulnerabilities and Exposures (CVE) record's product configurations, alongside Trivy 0.69.4, trivy-action before 0.35.0 and setup-trivy before 0.2.6.
Technical analysis
Trivy, as Aqua and Wiz describe it. Wiz's post of 20 March, updated to 22 March, says the actor made imposter commits to actions/checkout and aquasecurity/trivy, then pushed the v0.69.4 tag at 17:43:37 Coordinated Universal Time (UTC) on 19 March, triggering a release in which a malicious checkout fetched credential-stealer code from a typosquatted domain and backdoored binaries were published. Wiz says the attacker also used the compromised aqua-bot service account to push malicious workflows and steal further Aqua credentials. In the actions, Wiz describes a tool self-described as “TeamPCP Cloud stealer” that dumps Runner.Worker process memory, harvests SSH, cloud and Kubernetes secrets and exfiltrates them, with a tpcp-docs repository in the victim's GitHub account as the fallback. On a developer machine, Wiz says the binary attempts to install a Python script, sysmon.py, as a systemd service that polls a fallback address hosted on the Internet Computer Protocol (ICP) network for a further payload. Aqua's advisory adds that on 22 March the actor pushed malicious 0.69.5 and 0.69.6 images directly to Docker Hub with separately compromised credentials, and Wiz's 22 March update says TeamPCP expanded to the npm ecosystem through a worm, “CanisterWorm”, leveraging stolen publish tokens.
KICS and ast-github-action, as Wiz and Checkmarx describe them. Wiz reported on 23 March that between 12:58 and 16:50 UTC that day, users of the GitHub Action for KICS, Checkmarx's open source infrastructure-as-code scanner, who pinned to one of the compromised tags would have been served malware. Wiz says the attacker used what appears to be a compromised identity, the cx-plugins-releases service account, to point all 35 tags at staged commits. Checkmarx's update, as archived on 25 March, says tags were force-pushed in both kics-github-action and ast-github-action and that the KICS issue was fully resolved by 19:24 UTC. According to Wiz, the setup.sh script dumps Runner.Worker memory on GitHub-hosted runners, queries Amazon Web Services (AWS) instance metadata endpoints and, where it finds service account tokens, the Kubernetes API, then attempts to send its bundle to checkmarx[.]zone, falling back to a docs-tpcp repository. New, by Wiz's account, is Kubernetes persistence: with sufficient permissions the script attempts to deploy a highly privileged pod in kube-system on each node to install the sysmon.py backdoor.
Checkmarx and Wiz also name two compromised Open VSX extensions, ast-results 2.53.0 and cx-dev-assist 1.7.0. According to Wiz, they fetch a second stage from checkmarx[.]zone if the victim has credentials for at least one cloud provider, and the Visual Studio Code (VSCode) Marketplace versions appear unaffected.
LiteLLM, as Wiz, PyPI and LiteLLM describe it. Wiz's 24 March post describes LiteLLM as an open-source Python library and proxy server that converts API requests for over 100 large language models (LLMs) into the OpenAI format, and says its data shows LiteLLM in 36 per cent of cloud environments. Wiz says 1.82.7 runs its payload when the LiteLLM proxy is run or its proxy_server module imported, and 1.82.8 adds a litellm_init.pth file that runs whenever Python is invoked on the system. The payload, by Wiz's account, targets data including environment variables, SSH keys, cloud credentials, Kubernetes configurations and CI/CD secrets, exfiltrating to checkmarx[.]zone in 1.82.7 and models[.]litellm[.]cloud in 1.82.8; LiteLLM's update, as archived on 26 March, names only the second, which it says is not an official LiteLLM domain. PyPI's advisory PYSEC-2026-2 says the releases followed an API token exposure from an exploited Trivy dependency, and LiteLLM believes the compromise originated from the Trivy dependency in its CI/CD security scanning workflow.
telnyx, as JFrog describes it. JFrog reported on 27 March that telnyx versions 4.87.1 and 4.87.2 were uploaded to PyPI that day with malicious code in telnyx/_client.py, and that PyPI has quarantined the package. The code downloads a valid Waveform Audio File Format (WAV) file and extracts an encoded payload from its audio frames. On Windows it writes the decoded executable to the Startup folder as msbuild.exe; JFrog says that second stage is unknown because its file is unavailable for download. On other systems it runs a payload from a second WAV file, which JFrog calls, for Linux, an exact match to LiteLLM's apart from service names, and posts the encrypted results to 83.142.209[.]203 on port 8080. JFrog says how the library was compromised is unknown, but that it is likely a direct result of TeamPCP's recent attacks. Because the code fetches its payload over plain Hypertext Transfer Protocol (HTTP) from a bare Internet Protocol (IP) address without verifying it, JFrog warns that any man-in-the-middle (MitM) attacker could serve its own payload, so the versions remain dangerous although the payload URLs are inactive.
Attribution, as Wiz and JFrog present it. Wiz assesses with high confidence that the KICS operation is the Trivy actor, citing familiar naming conventions and the same public key. JFrog ties telnyx to the LiteLLM compromise through the identical encoded public key. CISA and Aqua name no actor, and no document cited here attributes the activity to a country.
The mapping is ours; each row rests on behaviour the named source describes.
| Technique | Basis |
|---|---|
| T1195.002 Compromise Software Supply Chain | Malicious Trivy, LiteLLM and telnyx releases and hijacked action tags (Aqua, Wiz, Checkmarx, JFrog) |
| T1003.007 OS Credential Dumping: Proc Filesystem | Runner.Worker memory read through /proc/<pid>/mem (Wiz; Aqua's advisory) |
| T1552.001 Unsecured Credentials: Credentials In Files | Sweeps of 50+ file paths for SSH keys and cloud credentials (Wiz; Aqua's advisory) |
| T1552.005 Unsecured Credentials: Cloud Instance Metadata API | KICS script querying AWS instance metadata endpoints (Wiz) |
| T1546.018 Event Triggered Execution: Python Startup Hooks | litellm_init.pth in LiteLLM 1.82.8 (Wiz) |
| T1543.002 Create or Modify System Process: Systemd Service | sysmon.py systemd unit (Wiz); audiomon.service (JFrog) |
| T1610 Deploy Container | Privileged pod in kube-system on each node (Wiz) |
| T1027.003 Obfuscated Files or Information: Steganography | telnyx payloads inside WAV audio frames (JFrog) |
| T1547.001 Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder | msbuild.exe in the Windows Startup folder (JFrog) |
| T1567.001 Exfiltration Over Web Service: Exfiltration to Code Repository | tpcp-docs and docs-tpcp repositories as the fallback (Wiz) |
Impact assessment
Aqua says the malware ran before the legitimate Trivy scan, so compromised workflows appeared to complete normally. Aqua says there is no indication that its commercial products were affected, and Checkmarx said on 23 March that it was not aware of any impact to customer data or production environments.
Each source's exposure window:
| Component | Window (UTC) | Affected and not affected | Source |
|---|---|---|---|
| Trivy v0.69.4 | 19 March, 18:22, when the release artefacts became public, to about 21:42 | Affected: v0.69.4, or latest during the window, as binaries from GitHub or Debian and RPM Package Manager (RPM) packages or Aqua's get.trivy.dev channel, or as images from GitHub Container Registry (GHCR), Amazon Elastic Container Registry (ECR) Public or Docker Hub. Not affected: v0.69.3 or earlier, images referenced by digest, binaries built from source, the official Homebrew formula (a separate custom Trivy tap was compromised). Aqua says removed artefacts may linger in intermediary caches | Aqua's advisory |
| trivy-action | 19 March from about 17:43, the earliest suspicious activity in Aqua's audit log, to 20 March about 05:40 | Affected: tags 0.0.1 to 0.34.2 (76 of 77 tags by Aqua's count; 75 of 76 by Wiz's); an explicit version: latest during the binary's window; a commit pin from before 9 April 2025, which would pull a malicious setup-trivy if invoked during the setup-trivy window. Not affected: tag 0.35.0, or a pin to a safe commit after 9 April 2025 | Aqua's advisory; Wiz |
| setup-trivy | 19 March, from about 17:43 (as above) to about 21:44 | Affected: any version without pinning; all 7 tags (v0.2.0 to v0.2.6) were force-pushed to malicious commits. Not affected: a pin to a safe commit | Aqua's advisory |
| Trivy images 0.69.5 and 0.69.6 on Docker Hub | 22 March from 15:43 (about 16:00 by Wiz); the advisory's duration column says about 10 hours, but its end time reads 22 March about 01:40 | Affected: 0.69.5, 0.69.6, or latest during the window; pushed with separately compromised Docker Hub credentials | Aqua's advisory; Wiz |
| kics-github-action | 23 March, 12:58 to 16:50 | All 35 tags (Wiz). Not affected: KICS itself, per Checkmarx | Wiz; Checkmarx |
| ast-github-action | Not stated | Tags force-pushed | Checkmarx |
| Open VSX ast-results 2.53.0 and cx-dev-assist 1.7.0 | 23 March from 02:53 (Checkmarx) or 12:53 (Wiz); to 15:41 by Checkmarx's account, though Wiz saw the malicious versions still present at the time of its report | VSCode Marketplace versions not affected (Checkmarx) | Checkmarx; Wiz |
| litellm 1.82.7 and 1.82.8 | 24 March, published about 08:30 and quarantined 11:25 (Wiz); installs between 10:39 and 16:00 (LiteLLM; its scan scripts use 08:00 to 12:44) | May be affected, per LiteLLM: unpinned or transitive installs, and unpinned Docker builds, in the window. Not affected, per LiteLLM: v1.82.6 or earlier without an upgrade in the window, the official proxy Docker image, LiteLLM Cloud, installs from the GitHub source | Wiz; LiteLLM |
| telnyx 4.87.1 and 4.87.2 | Uploaded 27 March; no times given | JFrog |
Indicators of compromise
A selection, defanged, from the cited primaries, with 256-bit Secure Hash Algorithm (SHA) file hashes; Wiz, Aqua and JFrog list more, including Wiz's hijacked tag commits.
| Indicator | Type | Context and source |
|---|---|---|
| scan.aquasecurtiy[.]org | Domain | Typosquatted command-and-control (C2) server for the Trivy payloads (Wiz; Aqua's advisory) |
| 45.148.10[.]212 | IP address | Resolution of that domain (Wiz) |
| plug-tab-protective-relay.trycloudflare[.]com | Cloudflare Tunnel host | Exfiltration from the Aqua workflows (Wiz); block this host, not the parent domain |
| tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0[.]io | ICP-hosted host | Fallback within the malicious Trivy binary (Wiz) |
| checkmarx[.]zone | Domain | KICS and LiteLLM 1.82.7 exfiltration, the Open VSX second stage and persistence polling (Wiz) |
| 83.142.209[.]11 | IP address | checkmarx[.]zone, per Wiz's KICS post |
| models.litellm[.]cloud | Domain | LiteLLM 1.82.8 exfiltration (Wiz; LiteLLM) |
| 83.142.209[.]203, port 8080 | IP address | telnyx WAV downloads and exfiltration (JFrog) |
| tpcp-docs, docs-tpcp | GitHub repository names | Fallback exfiltration for Trivy and KICS respectively (Wiz); Aqua's advisory gives tpcp-docs as a name prefix |
| litellm_init.pth | File | LiteLLM 1.82.8 (Wiz; LiteLLM) |
| ~/.config/audiomon/audiomon.py | File | telnyx Linux persistence (JFrog) |
| %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\msbuild.exe | File | telnyx Windows persistence (JFrog) |
| 822dd269ec10459572dfaaefe163dae693c344249a0161953f0d5cdd110bd2a0 | SHA-256 | Trivy v0.69.4 Linux 64-bit binary (Wiz; Aqua's advisory) |
| 65bd72fcddaf938cefdf55b3323ad29f649a65d4ddd6aea09afa974dfc7f105d | SHA-256 | ast-results-2.53.0.vsix (Wiz) |
| 744c9d61b66bcd2bb5474d9afeee6c00bb7e0cd32535781da188b80eb59383e0 | SHA-256 | cx-dev-assist-1.7.0.vsix (Wiz) |
Detection and hunting guidance
- Workflow runs: runs that referenced trivy-action, setup-trivy, kics-github-action or ast-github-action by tag inside a window above, or from 23 March for ast-github-action, which has no stated window. Aqua points to the Run Trivy and Setup environment steps; Checkmarx, in its Open VSX guidance, suggests searching GitHub Actions runs for tpcp.tar.gz, aquasecurity or checkmarx[.]zone.
- Repositories: names starting tpcp-docs, or docs-tpcp, in your GitHub organisation.
- Hosts: litellm_init.pth in site-packages, sysmon.py or audiomon under ~/.config, and msbuild.exe in the Windows Startup folder.
- Kubernetes: from Wiz's description, we suggest reviewing audit logs for privileged pods created in kube-system since 23 March, and nodes for /root/.config/sysmon/sysmon.py.
- Network: proxy and Domain Name System (DNS) logs for the indicators above, and HTTP POST requests carrying the header X-Filename: tpcp.tar.gz, which Wiz shows in the KICS script and JFrog in telnyx.
A generic proxy-log query to adapt:
-- Outbound requests carrying the exfiltration header, or to the listed hosts
SELECT event_time, src_ip, dest_host, dest_port, url
FROM proxy_logs
WHERE event_time >= '2026-03-19'
AND (request_headers LIKE '%X-Filename: tpcp.tar.gz%'
OR dest_host IN (SELECT indicator FROM ioc_list WHERE campaign = 'TeamPCP'))
ORDER BY event_time;
Incident response guidance
- Establish exposure for each component against its own window and the affected cases in the table above.
- Treat every runner or host that ran a malicious release, or a hijacked tag in its window, as having exposed every secret it could reach, and rotate those secrets, as Aqua's advisory instructs for Trivy and PyPI's for LiteLLM. For telnyx, JFrog says to assume everything on the local machine, including .env files, is compromised.
- Remove the malicious versions and move to those below.
- Where a KICS or LiteLLM payload had Kubernetes permissions, check every node for the persistence Wiz describes.
- Among the secrets to rotate, Aqua says npm publish tokens should be treated as actively compromised.
| Component | Move to | Source |
|---|---|---|
| Trivy binary | v0.69.2 or v0.69.3 | Aqua's advisory |
| trivy-action | 0.35.0 | Aqua's advisory |
| setup-trivy | 0.2.6 | Aqua's advisory |
| kics-github-action and ast-github-action | v2.1.20 and v2.3.33 respectively, or newer, the only versions Checkmarx now keeps; pin by commit (below) | Checkmarx |
| Open VSX cx-dev-assist and ast-results | 1.10.0 and 2.56.0 or later | Checkmarx |
| litellm | 1.82.6 or earlier, or a later verified release | LiteLLM |
| telnyx | 4.87.0 | JFrog |
These are our recommendations except where a source is named.
Mitigation recommendations
- Pin actions by commit. Aqua and Wiz both advise pinning GitHub Actions to full commit SHA hashes rather than version tags. Wiz's list of hijacked KICS tags includes v2.1.20, the version Checkmarx now names, so a tag alone does not show which commit a pipeline ran.
- Pin packages. LiteLLM says its official proxy Docker image, which pins dependencies in requirements.txt, was not affected; we recommend hash-pinned build-time installs.
- Immutable releases. Aqua's advisory says Trivy v0.69.3 and trivy-action 0.35.0 were protected by GitHub's immutable releases feature; we recommend maintainers enable it.
Historical context and related activity
Aqua's post says researchers at Aikido Security and CrowdStrike confirmed that the actor had pivoted beyond the initial CI/CD compromise and was weaponising stolen credentials across the broader ecosystem.
Future outlook
This section is assessment. By PyPI's account, the LiteLLM releases followed a token exposure through Trivy, and JFrog says the attack is ongoing and could target more repositories and ecosystems. We assess it is likely (B2) that TeamPCP will use credentials taken in these compromises to reach further packages or pipelines in the coming weeks. Because Aqua says compromised workflows appeared to complete normally, we judge it a realistic possibility (B3) that some organisations whose secrets were exposed have not yet found the exposure.
Further reading
- CISA, KEV alert, 26 March 2026, and catalogue of 27 March
- NVD, CVE-2026-33634 change history
- Aqua Security, GHSA-69fq-xp46-6x23 and blog post (archived copies)
- Wiz, Trivy (archived copy), KICS and LiteLLM
- Checkmarx, security update (archived copy)
- LiteLLM, security update (archived copy)
- PyPI, PYSEC-2026-2
- JFrog, telnyx