Inside the Miasma Software Supply Chain Attack Toolkit The Miasma software supply chain attack toolkit has been released as open source across multiple GitHub repositories, likely through compromised developer accounts. The toolkit enables attackers to execute supply chain attacks against public registries including PyPI, npm, and RubyGems, as well as GitHub repositories, GitHub Actions, and AI coding tools through stolen credentials. The codebase includes capabilities to bypass GitHub environment protection rules, generate valid Sigstore provenance bundles for trojanized packages, and operate three independent command-and-control channels using GitHub commit search. Inside the Miasma Software Supply Chain Attack Toolkit Table of Contents The infamous Miasma worm /miasma-worm-ai-coding-agent-config-injection goes open source. Multiple GitHub repositories with name Miasma-Open-Source-Release started appearing since yesterday. Most of them are likely published through compromised developer accounts. We have seen this in the past when Team PCP /ti/campaigns/teampcp open sourced the Mini Shai-Hulud payload which in turn, likely motivated further software supply chain attacks. We managed to obtain the source code from one such repository https://github.com/YangYongAn/Miasma-Open-Source-Release yanked now . As the developers of PMG https://github.com/safedep/pmg , we are continuously looking to update our benchmark of attacker TTPs against which we evaluate PMG, especially its sandbox features https://github.com/safedep/pmg/blob/main/docs/sandbox.md . In this blog, we do a deep-dive analysis of the Miasma-Open-Source-Release source code obtained from one of the public GitHub repositories. TL;DR The Miasma codebase appears to be larger than a supply chain worm. It is a full supply chain attack toolkit that allows the operator to execute various attacks via stolen credentials against arbitrary or targeted packages on public registries PyPI, npm, RubyGems , JFrog Artifactory, GitHub repositories and GitHub Actions, AI coding tools config poisoning, SSH based lateral movement and other attack vectors. Some of the interesting findings from the analysis: - Bypasses GitHub environment protection rules to trigger deployments. Details npm-oidc-branch-mutator - Generates valid Sigstore provenance bundles for trojanized npm packages. Details npm-oidc-mutator - Three independent C2 channels using GitHub commit search, each with a different search string and crypto key. Details command-and-control - Dead-man switch that wipes the victim’s home directory if the stolen PAT is revoked. Details dead-man-switch - Victim PATs embedded in exfiltration commits create a self-perpetuating flywheel for future worm instances. Details exfiltration - Hijacks GitHub Actions semver tags via orphan commits with cloned author metadata. Details github-actions-mutator - Injects into 13 AI coding tools Claude, Gemini, Cursor, Copilot, Kiro, Cline, and others . Details slow-path-propagation - Living off the pull request LOTP technique injects payload into existing project files across 12+ languages. Details living-off-the-pull-request-lotp - Credential harvesting from AWS, Azure, GCP, Kubernetes, HashiCorp Vault, and password managers 1Password, Bitwarden . Details credential-gathering - Dumps GitHub Actions runner memory via /proc to extract secrets not exposed as env vars. Details fast-path - 5-layer build obfuscation with per-build random keys, making each compiled payload unique. Details obfuscation-and-evasion - Targets npm, PyPI, and RubyGems via both stolen auth tokens fast path and OIDC trusted publishing slow path . Details propagation - MCP-suffixed typosquatting mode for PyPI packages. Details typo-mutator GitHub as a Common and Control Infrastructure We have been tracking TeamPCP, Mini Shai-Hulu, Miasma and other related campaigns /ti . One of the common observation is, attackers are moving away from custom C2 infrastructure which requires maintenance, warming and safeguarding. Instead, they are now leveraging GitHub as a full-fledged C2 infra for remote command execution, configuration, exfiltration. This is a key behavioural shift because, traditional network based detection and protection tools rely on baselining and anomaly detection. Defenders now have to operate closer to application protocol to identify behavioural anomaly instead of network based anomalies. High Level Architecture The repository consists of the following files: The file listing indicates the following: Bun https://bun.sh as a dependency for the payload, consistent with droppers that we have seen in the past /redhat-cloud-services-hit-by-mini-shai-hulud-npm-worm ARCHITECTURE.MD and INTEGRATION TESTING.md files indicate AI coding agent generated and maintained codebase. ARCHITECTURE.MD The ARCHITECTURE.md calls out the intention of the worm: A worm that aims to automate spreading across multiple developer tooling ecosystems. Written in TypeScript, executed via Bun, designed for CI/CD environments especially GitHub Actions and developer machines. Exfiltrates secrets and propagates through NPM packages, PyPI wheels, RubyGems, GitHub repositories and Actions, Claude settings hooks, SSH, and AWS SSM. The same file calls out a key architecture decision that aligns with what we have identified in past campaigns and why we consider network baselining an ineffective detection strategy for such payloads: Requires NO C2 infrastructure. No dealing with takedowns or maintaining infrasturcture. Stolen GitHub PATs are all that is necessary. The same file also calls out the following gaps in the current implementation: PyPI trusted publishing https://docs.pypi.org/trusted-publishers/ based spreading is untested.- SSH based propagation through scp and ssh exec is untested. - JFrog Artifactory npm package infection is untested. RubyGems trusted publishing https://guides.rubygems.org/trusted-publishing/ based package infection is untested.- GCP and Azure provider for secret exfiltration does not work. Components At a high level, the codebase consists of: scripts/ - Containing scripts for payload preparation, obfuscation and operations. src/ - Contains the actual worm source code with src/index.ts as the entrypoint. The worm application in turn is divided into following modules: - Orchestrator - Assets - Pre-crafted files used at runtime such as loaders, malicious GitHub Actions workflow, VSCode settings for code execution etc. - Collector - Dispatcher - Mutator - Provider - Sender - Utils The architecture also indicates what we have seen in Shai-Hulud class of worms that consist of a fast and slow path for credential exfiltration and propagation. The fast path is used for quick exfiltration of credentials and slow path is used for propagation through various ecosystems which may take time to execute. Following is the architecture diagram from the ARCHITECTURE.md file: Application Logic Preflight The pre-flight stage of the worm execution performs the following checks: - Check for known sandbox environment and fail fast. - Checks and ensures proxy env vars are set consistently across the different variables required by bun via libcurl . - Bail out on Russian systems identified through locale resolution. Interestingly, the worm has targeted mode for npm OIDC based self-propagation. During the pre-flight, it checks if WORKFLOW ID and REPO ID SUFFIX env-var is set, matches substring GITHUB WORKFLOW REF and GITHUB REPOSITORY env-vars, then it executes the npm OIDC based propagation flow and quits without executing the full worm logic. The pre-flight also detects malware analysis environments through known fake environment variables, docker containers, sudo restrictions on GitHub Actions, and known security tools by process name and file path. It actively restores sudo access using docker privileged containers and overwrites /etc/resolv.conf with public DNS to evade dynamic analysis tools. Example code for sudo restoration: Fast Path If the pre-flight checks are successful, the worm executes its fast path, that executes: - Credential gathering from known sources via gatherQuickResults . - Infect npm, PyPI, RubyGem packages via download, patch, publish vector if a valid token is found. - Create a layered sender chain containing the transport logic for exfiltrated data. - Execute the collector to validate, cache in-memory quick results and deliver via the sender chain. The fast path is designed to quickly exfiltrate credentials and other sensitive information before dropping the larger propagation and persistence payloads, that may be detected by EDR and other security tools. Credential Gathering The worm uses Provider as an abstraction for source specific credential gathering logic. Following providers are registered: The full provider bundle also appends services that are deemed to be available based on credentials gathered from fast path harvesting, such as GitHubActionsService , GrepProvider . Interestingly, the worm logic uses GrepProvider when classic GitHub tokens are found. The following code determines when to register the GitHubActionsService : Credential Collection The Collector acts as an orchestrator for classifying credentials, taking action based on credential type, and triggering exfiltration. The high level behavior is as follows: - In-memory, bounded cache for ProviderResult credentials , flushed based on byte count. - Classify token type by pattern matching and dispatch token-specific handlers that perform validation and propagation using the token’s privileges. - Execute the slow path for credential collection, which includes cloud services, password managers, vaults, and more. Example code for dispatching token handles by token pattern: When collector’s in-memory buffer cache reaches a threshold or when the finalize method is called, it invokes the Dispatcher component to exfiltrate the collected credentials from the buffer. Exfiltration Exfiltration of collected credentials is handled by Dispatcher and Sender components. The dispatcher is responsible for: - Encrypting the batch of credentials to be exfiltrated - Exfiltrate by invoking the Sender chain At the time of initialization in src/index.ts , the worm creates the sender chain by invoking: The buildSenderChain itself is dynamic and creates the senders based on credentials collected in the fast path. Specifically, it creates the primary GitHub sender if it can find an attacker controlled PAT by searching for commits using GitHub Commit Search API https://docs.github.com/en/rest/search/search search-commits . In src/github utils/fetcher.ts , it attempts to find this attacker controlled PAT by searching for the string DontRevokeOrItGoesBoom . The attacker pre-plants GitHub PATs by committing them to public repos. The commit message format is: The payload for the attacker’s PAT is encrypted with a hardcoded AES key from src/utils/config.ts : Once decrypted and validated with a prefix github pat 11A , it checks that the token has repo scope and has 200+ rate limit quota remaining, before it selects it for use else continue with the next. This approach allows the attackers to continuously update the worm with new PATs, likely leveraging compromised credentials and developer machines, almost like a fly-wheel. It then creates the primary GitHub sender using the attacker controlled PAT: If no attacker controlled PAT is found, it creates the GitHub sender using victim’s own PAT found earlier in the fast path. This behaviour is again consistent with the observed worm behaviour of exfiltrating encrypted credentials batch using public repositories created under victim’s account. When using a victim’s PAT, the sender embeds the PAT in the exfiltration commit message. The token is AES-256-CBC encrypted and disguised as a github pat 11A... string, then included in the commit message as DontRevokeOrItGoesBoom: