CyberBytes Daily

Trending cyberattacks, explained simply.

supply chain attacks

How attackers poisoned a security scanner to steal the secrets it was scanning

The tool your engineering team runs to find secrets accidentally left in code was itself stealing those secrets and sending them to attackers. That is not a hypothetical. On April 22, 2026, attackers replaced the official KICS (Keeping Infrastructure as Code Secure) container image on Docker Hub with a version that did exactly that: it ran your infrastructure scan, generated a complete report of every API key, cloud credential, and configuration secret it found, and quietly transmitted the results to an attacker-controlled server before returning normal-looking output to your pipeline.

KICS is a widely used open-source scanner made by Checkmarx, a major application security company. Its Docker image has been downloaded more than five million times. Organizations use it specifically to catch exposed credentials in Terraform, Kubernetes, and CloudFormation files. The attackers understood this. They did not need to break into your environment. They waited for your security tool to do the work for them.

The malicious window was 83 minutes. But the operation behind it had been running for nearly two months, and the blast radius extended far beyond a single container image.

Narrative ยท 6 min read

The Context

Checkmarx is an application security company whose tools are embedded in the software development pipelines of thousands of enterprises. KICS is one of its flagship open-source products: a scanner that reads infrastructure-as-code files and flags security problems, including secrets accidentally left in the code. Because it needs to read those files to do its job, it necessarily processes some of the most sensitive material in an organization's codebase.

The KICS Docker container image is the standard way teams run the scanner inside automated pipelines. With over five million downloads, it sits inside CI/CD workflows at a significant fraction of the enterprise DevSecOps ecosystem. That ubiquity, combined with the elevated access the scanner requires, made it an extraordinarily high-value target.

The Attack, Phase by Phase

Phase 1: Credential Harvest via CI/CD Misconfiguration

The campaign began on February 27, 2026, when an autonomous bot operated by the threat group TeamPCP exploited a misconfigured GitHub Actions workflow in Aqua Security's Trivy repository. The misconfiguration allowed the bot to steal a privileged Personal Access Token belonging to Aqua Security's automated service account, which had write access to more than 33 repositories.

Aqua Security disclosed the intrusion on March 1 and attempted to rotate its credentials. The rotation was incomplete. TeamPCP retained residual access and used it on March 19 to push a backdoored version of Trivy to 76 of its 77 version tags. Every organization that ran the poisoned Trivy scanner during that window handed the attacker the credentials stored in their pipeline โ€” including GitHub tokens belonging to Checkmarx's own publishing service account.

INITIAL CREDENTIAL HARVEST (FEB 27 TO MAR 19, 2026)๐Ÿค–1Bot exploits CI/CD misconfigurationSteals Aqua Security PAT via workflow flaw๐Ÿ”„2Incomplete credential rotationAqua discloses breach; residual access remainsโ˜ ๏ธ3Trivy backdoor deployed76 of 77 version tags overwritten Mar 19๐Ÿ—๏ธ4Pipeline credentials harvestedCheckmarx publisher PAT stolen from victimsA single incomplete credential rotation left the door open for everything that followed.

Phase 2: Staging the Payload via Git History Manipulation

Before executing the visible attack, TeamPCP pre-positioned its payload inside an official Checkmarx repository. The attacker injected a commit (68ed490b) into the Checkmarx/ast-vscode-extension repository and backdated it to appear authored in 2022, attaching it to a real historical commit with a surface-level change that looked routine.

That commit introduced a roughly 10MB file called mcpAddon.js: a heavily obfuscated JavaScript credential stealer. Because it appeared to be a four-year-old part of the official codebase, automated scanners and human reviewers were unlikely to flag it. The attacker could now reference a raw.githubusercontent.com URL pointing to an official Checkmarx repository โ€” a domain most security tools treat as trusted.

PAYLOAD PRE-POSITIONING (BEFORE APR 22, 2026)๐Ÿ“1Backdated commit injected68ed490b spoofed to appear from 2022๐Ÿ“ฆ210MB stealer embeddedmcpAddon.js hidden in official repoโœ…3Payload appears legitimateHosted on trusted github.com domainThe attacker turned GitHub's own trust reputation into a delivery mechanism.

Phase 3: Multi-Channel Distribution Poisoning

On April 22, 2026, at 12:35 UTC, the attacker authenticated to Docker Hub using the stolen Checkmarx credentials and pushed malicious images to the official checkmarx/kics repository. Five existing tags were overwritten: latest, v2.1.20, v2.1.20-debian, alpine, and debian. Two fabricated tags were also created โ€” v2.1.21 and v2.1.21-debian โ€” with no corresponding legitimate release.

Any pipeline pinned to one of those named tags silently received the malicious image on its next run. The poisoned images performed a normal scan, then encrypted the full results and transmitted them to audit.checkmarx[.]cx/v1/telemetry, a domain crafted to resemble legitimate Checkmarx infrastructure.

In parallel, malicious versions of two VS Code extensions were published: cx-dev-assist and ast-results. On activation, they silently downloaded mcpAddon.js from the pre-staged GitHub commit and executed it using the Bun JavaScript runtime, without any user prompt or integrity check.

SIMULTANEOUS DISTRIBUTION POISONING (APR 22, 2026)๐Ÿณ1Docker Hub tags overwritten5 tags replaced, 2 fake tags created๐Ÿงฉ2Malicious VS Code extensions publishedcx-dev-assist and ast-results poisonedโฌ‡๏ธ3mcpAddon.js fetched and executedDownloaded from official Checkmarx repoTWO SIMULTANEOUS VECTORS๐Ÿ“กDocker vectorScanned secrets sent to attacker C2๐Ÿ’ปExtension vectorDeveloper credentials stolen on activationBoth vectors reported to the same C2 server, confirming coordinated infrastructure.

Phase 4: Credential Exfiltration, Worm Propagation, and Ransomware Escalation

The malware harvested GitHub tokens, AWS, Azure, and Google Cloud credentials, npm publishing tokens, SSH keys, and environment variables, then encrypted and transmitted them to the attacker's server. Stolen GitHub tokens were used to create public repositories under victim accounts labeled "Checkmarx Configuration Storage" as exfiltration staging. By April 22, Socket researchers had identified 51 such repositories.

The malware also injected a malicious GitHub Actions workflow (format-check.yml) into any repository the victim had write access to, causing it to dump its entire secrets context as a downloadable artifact. Stolen npm credentials were then used to republish up to 250 packages maintained by compromised developers, each embedded with the payload โ€” spreading the infection without further attacker action.

Downstream, the Vect ransomware group โ€” which had announced a formal partnership with TeamPCP in late March 2026 โ€” began publishing victim data for double-extortion. On April 15, Vect listed its first confirmed victim, a property-management technology company, claiming 700 GB of data and approximately four million emails.

EXFILTRATION AND PROPAGATION๐Ÿ”‘1Credentials harvestedGitHub, AWS, Azure, GCP, npm, SSH keys๐Ÿ“‚2Staging repos created51 Checkmarx Configuration Storage reposโš™๏ธ3CI/CD secrets dumpedformat-check.yml injected into victim repos๐Ÿ“ฆ4npm worm propagates250 packages republished with payload๐Ÿ’ฐ5Ransomware escalationVect publishes first victim, 700 GB claimedStolen credentials from one pipeline became the entry point for the next victim's pipeline.

What Made This Possible

  1. Mutable distribution primitives. Docker image tags, GitHub Actions version tags, and extension marketplace releases can all be silently repointed. A pipeline referencing checkmarx/kics:latest has no way to detect that "latest" now points to a different image. Pinning to a cryptographic digest would have made the substitution impossible.

  2. Cascading credential economy. The entire campaign traces back to a single incomplete credential rotation at Aqua Security. Those retained credentials became the master key for compromising Checkmarx's publishing accounts weeks later. Each compromised pipeline yielded new credentials that funded the next attack. No single organization's failure was contained to that organization.

  3. Security tools run with elevated trust. KICS, by design, reads every infrastructure configuration file in a repository, including the ones containing secrets. That access makes these tools the highest-value targets in the pipeline, and organizations had no independent mechanism to verify tool integrity at runtime.

What Should Have Stopped This

  • Digest pinning instead of tag references. Referencing a container image by its immutable cryptographic digest means a tag overwrite has no effect on your pipeline.
  • Egress filtering on CI/CD runners. Pipeline runners should only make outbound connections to an explicit allowlist. A connection to audit.checkmarx[.]cx would have been blocked before any data left the environment.
  • Least-privilege pipeline tokens. Tokens scoped to read-only access cannot create repositories, inject workflows, or republish packages. The worm propagation stage depended entirely on victims' tokens having write access the scanner never needed.
  • Behavioral monitoring on developer workstations. The VS Code extension executed a 10MB JavaScript file and made outbound network connections on activation โ€” unexpected process spawns from an editor process that endpoint detection should have flagged.

The Takeaway

The KICS attack is the same class of failure as the Stryker Intune wipe and the Axios build-time injection: a trusted, privileged tool weaponized against the organization it was built to protect. The attacker did not choose KICS despite it being a security tool โ€” they chose it because of it. A scanner that processes secrets at scale and runs with elevated pipeline access is a more efficient credential-harvesting engine than almost anything an attacker could build from scratch.

The broader TeamPCP campaign illustrates how a single incomplete remediation at one vendor can cascade into fresh compromises at entirely separate organizations weeks later. The meta-pattern: systems fail when they trust a boundary the attacker already controls.

Pattern to remember: When a security tool is the distribution channel, compromising the tool is equivalent to compromising every environment that trusts it.

What changed: Attackers are now selecting targets by the volume of secrets a tool processes, not by the value of the target organization itself โ€” which means the most dangerous entry point in your pipeline is the scanner you added to protect it.

Technical Deep Dive ยท 4 min

The Technical Mechanism

The April 22, 2026 Docker Hub compromise involved authenticated tag overwriting using valid Checkmarx publisher credentials. The attacker pushed a modified ELF binary (Golang-compiled) named kics that preserved the scanner's normal execution path while adding a credential exfiltration routine. The binary generated an uncensored scan report containing the full plaintext contents of every IaC file passed to it, then encrypted the payload using AES-256-CBC with the key wrapped in a hardcoded 4096-bit RSA public key (the same key used across all TeamPCP campaign waves) and transmitted it via HTTPS POST to audit.checkmarx[.]cx/v1/telemetry with a KICS-Telemetry/2.0 User-Agent header.

The VS Code extension vector used a distinct execution chain. Trojanized extension versions activated a hidden "MCP addon" feature that fetched mcpAddon.js from raw.githubusercontent.com/Checkmarx/ast-vscode-extension/68ed490b/mcpAddon.js, wrote it to ~/.checkmarx/mcp/mcpAddon.js, and executed it via the Bun JavaScript runtime. The mcpAddon.js payload was a single-line, heavily obfuscated bundle using mangled identifiers and a string-table decoder. It harvested credentials from standard locations (~/.gitconfig, ~/.aws/credentials, ~/.npmrc, ~/.ssh/, environment variables, Claude AI configuration files) and exfiltrated them to the same C2 endpoint as the Docker vector.

The worm propagation mechanism used stolen GitHub tokens to call the GitHub API and create public repositories under victim accounts, then used the GITHUB_TOKEN available in victim CI/CD environments to inject format-check.yml workflows that dumped the repository's secrets context as a downloadable Actions artifact. The npm propagation stage parsed victim .npmrc files to identify maintained packages and used stolen npm tokens to publish new versions with the payload embedded.

The backdated commit technique exploited Git's lack of server-side commit timestamp verification. Git commit timestamps are author-controlled fields; nothing in the GitHub platform prevents a commit from carrying a 2022 authorship date when pushed in 2026. The commit 68ed490b was constructed as an orphaned commit (no branch reference) attached to a real historical parent, making it invisible to standard git log traversal while remaining fetchable by direct hash reference.

DUAL-VECTOR EXFILTRATION ARCHITECTURE๐Ÿณ1Poisoned KICS binary executesNormal scan runs; secrets captured in full๐Ÿ”2Payload encryptedAES-256-CBC, RSA-wrapped hardcoded key๐Ÿ“ก3Exfiltration via HTTPS POSTSent to audit.checkmarx[.]cx/v1/telemetry๐Ÿ’ป4Extension fetches mcpAddon.jsFrom backdated commit 68ed490b on GitHub๐Ÿ—‚๏ธ5Credentials harvested locallygit, AWS, npm, SSH, env vars collected๐Ÿ“ก6Same C2 endpoint receives bothDocker and extension vectors convergeBoth attack vectors used identical encryption keys and C2 infrastructure, confirming unified campaign control.

CVE and Advisories

No CVE has been assigned specifically to the April 22, 2026 Docker Hub KICS image compromise as of the publication date. The broader TeamPCP campaign against Trivy was assigned CVE-2026-33634 with a CVSS4B score of 9.4, covering the GitHub Actions tag-hijacking vector.

Vendor advisories:

MITRE ATT&CK Mapping

Technique IDATT&CK nameHow it appeared
T1195.002Supply Chain Compromise: Compromise Software Supply ChainAttacker poisoned official distribution artifacts (Docker images, VS Code extensions) to deliver malicious payloads to downstream consumers.
T1078Valid AccountsStolen Checkmarx publisher credentials used to authenticate to Docker Hub and push malicious images through the legitimate publishing flow.
T1554Compromise Host Software BinaryThe legitimate KICS ELF binary was replaced with a trojanized Golang binary that preserved normal scanner behavior while adding exfiltration.
T1070.004Indicator Removal: File DeletionOrphaned commit technique used to stage payload in a location that does not appear in standard branch history traversal.
T1567.001Exfiltration Over Web Service: Exfiltration to Code RepositoryStolen credentials used to create public GitHub repositories under victim accounts as staging locations for encrypted exfiltrated data.
T1059.007Command and Scripting Interpreter: JavaScriptmcpAddon.js executed via Bun runtime to perform credential harvesting and C2 communication on developer workstations.
T1098.001Account Manipulation: Additional Cloud CredentialsMalicious GitHub Actions workflow (format-check.yml) injected to dump repository secrets context as downloadable artifacts.
T1543Create or Modify System ProcessOn non-CI systems, persistence established via a systemd user service polling the C2 domain every 50 minutes for additional payloads.

Indicators of Compromise

Network Indicators

  • Outbound HTTPS connections to audit.checkmarx[.]cx (C2 for Docker and extension vectors)
  • Outbound DNS queries or HTTP/HTTPS connections to checkmarx[.]zone (C2 for GitHub Actions vector)
  • HTTP requests carrying the KICS-Telemetry/2.0 User-Agent string from CI/CD runner processes
  • Outbound connections to raw.githubusercontent.com/Checkmarx/ast-vscode-extension/68ed490b/mcpAddon.js

File System Indicators

  • Presence of ~/.checkmarx/mcp/mcpAddon.js on developer workstations
  • GitHub Actions workflow file named format-check.yml in .github/workflows/ of repositories the victim did not create
  • Public GitHub repositories with description "Checkmarx Configuration Storage" under victim organization accounts, with commit messages matching the pattern LongLiveTheResistanceAgainstMachines

Repository Indicators

  • Git commit 68ed490b referenced in any extension or workflow configuration
  • Repositories named docs-tpcp created within victim GitHub organizations (fallback C2 mechanism)
  • Dune-universe naming pattern in attacker-created staging repositories (e.g., gesserit-melange-813, prescient-sandworm-556)

Safe Versions

  • Docker Hub KICS: v2.1.20 (restored legitimate digest; verify by digest, not tag)
  • checkmarx/ast-github-action: v2.3.36 or later
  • Checkmarx VS Code extensions: ast-results v2.64.0 or later, cx-dev-assist v1.18.0 or later

Attribution

TeamPCP publicly claimed responsibility via the @pcpcats account on X, posting taunting messages after the incident became public. The group first appeared in late December 2025, initially focused on misconfigured Docker APIs and Kubernetes clusters, operating under forum personas including DeadCatx3, PCPcat, Persy_PCP, ShellForce, and CipherForce.

Palo Alto Networks Unit 42, Datadog Security Labs, and Wiz independently linked the April 2026 KICS Docker Hub attack to the same actor responsible for the March 2026 Trivy, Checkmarx GitHub Actions, LiteLLM, and Telnyx compromises, based on shared C2 infrastructure, identical 4096-bit RSA public keys used for payload encryption, and consistent tradecraft including typosquatted vendor domains and fallback tpcp-docs repository creation.

Socket noted that technical artifacts alone cannot confirm whether the April access represented retained credentials, re-compromise, or unremediated access from March. No nation-state link has been established by any Tier 1 threat intelligence firm. One secondary source speculatively cross-references TeamPCP with DPRK-linked clusters; this attribution is unverified and not corroborated by primary research. The group's motivations appear primarily financial, confirmed by the formal partnership with the Vect ransomware-as-a-service operation announced in late March 2026.


Primary Sources