// 6 ZERO-DAY · 7 CVE · 6 EXPLOIT IN THE LAST 24H
Threat actors turned GitHub Actions runners into botnet nodes for large-scale cPanel/WHM scanning and exploitation. The campaign generated up to 16,000 matching workflow files, though the source clarifies these represent matched files—not confirmed compromised accounts or repositories.

Between July 12 and 13, 2026, threat actors transformed the world's largest CI/CD platform into a distributed attack infrastructure. By compromising the account of a legitimate PHP developer, they injected 583 malicious workflows into open-source packages that, when executed on GitHub's ephemeral Ubuntu runners, downloaded payloads for large-scale cPanel and WHM exploitation via CVE-2026-41940.

Key Takeaways
  • The GitHub account of dinushchathurya, a legitimate PHP and DevOps developer, was compromised and used to distribute malicious workflows through Packagist.
  • The workflows resided in .github/workflows/, not in the PHP code, exploiting the fact that GitHub ignores workflows nested in vendor/ during package installation.
  • Ephemeral Ubuntu runners were converted into botnet nodes with multi-architecture payloads downloaded from a C2 server at IP 43[.]228[.]157[.]68.
  • GitHub searches returned approximately 15,000-16,000 matching files, but the source specifies these represent matched files, not confirmed compromised accounts or repositories.

How a Legitimate Developer's Account Became a Conduit for 583 Malicious Workflows

The compromise targeted the GitHub account of dinushchathurya, a developer active in the PHP and DevOps ecosystems. Packagist, the primary repository for PHP packages, automatically synced malicious development versions across 10 packages associated with the account. Each version contained between 55 and 62 GitHub Actions workflows, totaling 583 files.

The mechanism is insidious: the PHP code itself was benign, containing only static reference data and ordinary lookup functions. The attack resided entirely in the .github/workflows/ directory. According to the source, "the library's PHP code is benign. It contains static reference data and ordinary lookup functions, with no malicious install hooks, network activity, shell execution, or import-time behavior. The attack code lives under .github/workflows/".

An architectural feature of GitHub Actions protected package installers: the platform ignores workflows nested in vendor/. This meant installation via Composer did not trigger the malicious workflows. Execution occurred only on push to the compromised repository or on manual trigger, when GitHub assigned an ephemeral Ubuntu runner with full internet connectivity.

The Technical Mechanism: From CI Runner to Botnet Node in Seconds

Once triggered, the workflow detected the runner's processor architecture and downloaded the corresponding Linux payload from the C2 server 43[.]228[.]157[.]68 via HTTP. The exposed endpoints were structured by architecture: /api/dl/386, /amd64, /arm, /arm64. The AMD64 payload, with SHA-256 hash 22f7…81f1, executed internet-scale scanning configured with standard cPanel and WHM ports: 80, 443, 8080, 8443, 2082, 2083, 2086, 2087.

The payload implemented infostealer functionality: it searched for AWS credentials, GitHub/GitLab tokens, OpenAI and Google API keys, Stripe keys, SendGrid/Mailgun credentials, database information, SSH data, and Git remotes. A heartbeat loop sent updates every 30 seconds to /api/github-heartbeat with the repository identifier. Scan results were exfiltrated via POST to /api/github-results, with offset tracking to avoid duplicates.

"Operators repurpose GitHub-hosted Ubuntu runners as disposable attack infrastructure for large-scale scanning, exploitation, and credential theft" — Socket Researchers via GBHackers

The Scale: From 6,100 to 16,000 Files, But the Numbers Hide Uncertainty

A search using the unique DNSHook identifier returned approximately 6,100 matching workflow files. Broader searches, using multiple indicators such as the C2 address, scanner arguments, credential filenames, and the heartbeat endpoint, brought the total to approximately 15,000-16,000 matching files. The source is explicit on a critical point: "these figures represent matched files rather than confirmed victim accounts, since a single repository can host many cloned workflows and some of the infrastructure is attacker-controlled staging rather than compromised projects."

This distinction is not academic. It means the count includes forked repositories, mirrors, and possible test infrastructure managed directly by the threat actors. The actual number of compromised legitimate accounts remains indeterminable from available sources.

Why This Matters

The dossier does not verify the claim that GitHub restricted its bug bounty program. This mandatory topic element is not covered by any available source.

The brief does not specify how the dinushchathurya account was initially compromised: credential theft, a prior supply chain compromise, or another vector are not documented. It is also unclear whether CVE-2026-41940 corresponds to a real vulnerability with an official advisory, or if the number was attributed by sources without verification by NVD or the primary vendor. The threat actor's identity is not attributed by any source.

No details emerge on any GitHub countermeasures beyond the suspension of the compromised account. The source does not document specific remedial measures adopted by the platform to prevent similar structural abuse.

The campaign exposes an architectural fragility: the "free compute" function with public runners, combined with automatic synchronization between repositories and package registries, allows seemingly legitimate repositories to be converted into attack infrastructure without the main source code revealing anomalies. Traditional package or code detection fails because the threat resides in the CI/CD configuration, not in the distributed software.

The GitHub Actions Trust Boundary: Feature or Vulnerability?

The security mechanism that ignores workflows in vendor/ is designed to protect users from unwanted execution during dependency installation. In the documented campaign, this same mechanism became an obfuscation vector: packages appeared benign to installers, while the active payload resided in a trust boundary that developers do not directly control.

The GitHub platform faces a structural tension here. Public runners are designed to execute arbitrary code on cloud infrastructure; industrial-scale abuse turns this legitimate function into a hosting service for criminal operations. The suspension of individual accounts, documented for dinushchathurya, does not disrupt forks, mirrors, and active C2 infrastructure indicating an ongoing campaign.

The risk for enterprises hosting cPanel/WHM is concrete: CVE-2026-41940 carries a CVSS score of 9.8 according to available sources, with a network vector, low attack complexity, and no privileges required. For developers and open-source maintainers, the threat is more subtle: their own repositories can be converted into attack infrastructure without alteration of the distributed code, making detection extremely difficult for traditional tools.

Frequently Asked Questions

Did the PHP package install malware on my computer?

No. Workflows in .github/workflows/ are ignored by GitHub when the package resides in vendor/. Execution occurred only on GitHub's cloud runners, not on the machines of developers who installed the package.

Do the 16,000 files indicate 16,000 compromised repositories?

No. The source specifies these are search-matched files, which include cloned workflows, forks, and possible staging infrastructure controlled by the attacker. The number of actually compromised accounts is not determinable.

What happened to the compromised account?

The dinushchathurya account was suspended, but the source notes that forks, mirrors, and C2 infrastructure remain active, indicating the campaign continues.

Sources

Information is based on the cited source and current as of publication.

Sources


Sources and references
  1. gbhackers.com
  2. socket.dev
  3. cdn.sanity.io