Miasma-family 'testmetest' npm worm with token-revocation wiper armed 42 real GitHub repos across 11 owners
Matéria consolidada. Reúne 2 matérias que o Tifon tinha publicado separadamente sobre a mesma história. A IA reescreveu o relatório com o que as 3 fontes trouxeram em 28/10/2026 03:01; os links antigos trazem para cá.
A Miasma-family self-propagating npm worm, tracked as the testmetest campaign, was first reported by SafeDep (safedep.io) on 22 October 2026 as an operator's public test with no victims. Reporting on 26 October (theregister.com), attributed to JFrog, says the worm had in fact armed 42 real GitHub repositories belonging to 11 owners, with accounts hijacked as early as July. The malware steals credentials, spreads through npm, PyPI, RubyGems, JFrog and GitHub/GitLab repositories, and installs a wiper that deletes the victim's home directory when the stolen GitHub token is revoked. It shares code with Miasma "Phantom Gyp" (June 2026) and the token-revocation wiper from Mini Shai-Hulud, but SafeDep has not confirmed the lineage and does not attribute it to the original Miasma operators (safedep.io). JFrog also linked the operator's GitHub account CementBeetleSteeple to a shellpanel scanner that Socket documented in a campaign exploiting CVE-2026-41940 (cPanel/WHM authentication bypass), without confirming any downstream cPanel compromise (theregister.com). JFrog researchers Guy Korolevski and Yair Benamou's 26 October investigation, relayed by gbhackers.com, ties the worm to a hidden CI publisher and notes that a 27 October SafeDep update found newer packages that run on import, so disabling install scripts alone no longer prevents execution (gbhackers.com).
Entenda a falha
A vulnerabilidade
CVE-2026-41940 is an authentication bypass in cPanel and WHM. The articles give no affected component, attacker prerequisites, or exact affected and fixed versions. They say CISA added it to the Known Exploited Vulnerabilities catalog in April and that cPanel has published patched versions. In this story it is a side link: the testmetest worm operator's infrastructure was tied to a campaign exploiting this flaw. The worm itself abuses npm build behavior (binding.gyp) and is not a cPanel flaw.
Como funciona
The articles do not describe how the bypass works internally. They say Socket documented a large-scale campaign that abused GitHub Actions in compromised repositories to exploit CVE-2026-41940 and steal server credentials, using a shellpanel scanner. According to gbhackers.com, workflows in the hijacked repositories downloaded a file (/tmp/.svc) from 43[.]228[.]157[.]68 and attempted exploitation against cPanel services. JFrog did not confirm any successful downstream cPanel compromise.
Por que é vulnerável
The articles do not state the root cause of CVE-2026-41940 beyond classifying it as an authentication bypass, and they do not say what the cPanel fix changes. They only confirm that patched versions exist.
Como foi descoberta
The articles do not say who found CVE-2026-41940 or how it was reported. They show it was exploited in the wild: Socket documented a campaign abusing GitHub Actions to exploit it, and CISA added it to the KEV catalog in April. In its 26 October report, JFrog linked the testmetest operator's GitHub account (CementBeetleSteeple) to the shellpanel scanner and to the C2 infrastructure Socket had reported, through artifacts and workflows on the same hijacked owners. gbhackers.com adds that the shellpanel artifacts connect those owners to Socket's July investigation.
Explicação gerada por IA a partir da matéria e dos artigos, em 28/10/2026 03:17.
Exploit público
Há código de exploração publicado no Exploit-DB para CVE-2026-41940. O código não é reproduzido aqui: o link leva à fonte, e a explicação foi escrita pela IA a partir do arquivo publicado.
-
cPanel - CRLF Injection
The script abuses an authentication bypass in the cPanel/WHM daemon (cpsrvd), reachable over the network on the WHM admin port with no credentials. It sends an Authorization header with embedded line breaks plus a pre-login session cookie, which injects forged fields into the session file claiming root and passed two-factor. The server then issues a valid administrative session token, giving full WHM and root-level control. It is a working automated script, not verified by Exploit-DB; the 11.40 version in the title looks wrong.
Detalhes técnicos
- Delivery (safedep.io): each package has a 0.0.0 stub, a harmless 1.0.0 decoy, then a malicious patch version (e.g. 0.0.1) that becomes latest. There are no install scripts. A
binding.gypmakes npm runnode-gyp rebuild, and itssourcesfield executesnode index.jswith output hidden.index.js(14.8 KB) decrypts a Bun bootstrap andlib_native.dat(320 KB), writes the payload to/tmp/.b-*/index.js, runs it withbun runand deletes it. The loader uses Caesar-style character transforms and AES-128-GCM with a Bun 1.2.18 bootstrap; one early release carried both the full worm and a separate publisher-family payload (gbhackers.com). - Second build (theregister.com): it skips the encrypted file, forks, detaches and runs a hard-coded command that pulls a loader from a repository on the operator's GitHub account, which hosted 17 campaign repositories.
- Compiled-addon builds (gbhackers.com): later packages
@iobandamwer/cache-helper,@iobandamwer/native-helperandpath-stream-utils-testmetestreplace readable JavaScript loaders with compiled Node.js addons. They decrypt an adjacent.napi_cachefile with XOR key 0x96 and launch the recovered JavaScript in detached processes. - Import-time execution (gbhackers.com, citing SafeDep's 27 October update):
@testsecuiitytestme/cache-helperversions 1.0.1–1.0.3 trigger the worm when an application imports the package. - Evasion: exits on Russian and other CIS locales and on known analysis sandboxes (safedep.io). It also checks for CI runners, containers, sandboxes and debuggers and exits silently (theregister.com). Linux builds check CI variables, container markers, memory, processor counts and debugger status; Windows variants also detect Wireshark, Process Monitor and x64dbg (gbhackers.com). In GitHub Actions it kills StepSecurity Harden-Runner through docker.sock and points *.stepsecurity.io to localhost, exiting if that fails (safedep.io).
- Oversized payloads (theregister.com): polymorphic wrappers of 12.9 to 13.7 MB decode a hidden CI-publisher payload. Their size evades GitHub code search and the API paths normally used to detect this kind of compromise. Direct Git tree and blob enumeration found ten distinct wrappers that decrypt to the same publisher payload; differences reflect encoding, not extra capabilities (gbhackers.com).
- Hidden CI publisher (gbhackers.com): CementBeetleSteeple hosted publishing infrastructure on short-lived
chore/ci-<hex>branches carrying a root-levelci.jsand an Actions workflow. The recovered code harvests tokens, inspects trusted-publishing permissions and implements GitHub OIDC exchanges for npm publishing credentials; this shows the intended automation, not that every malicious release used it. Repositories also showed forged commit histories and.github/init.js. - Fake CodeQL workflows (gbhackers.com): they export environment variables into scan-output artifacts. Researchers recovered three distinct npm tokens across six repositories.
- Credential theft (safedep.io): SSH keys, npm, PyPI and Git credentials, .env files, browser logins, AI tool credentials (Claude, Codex, Gemini, Copilot), AWS/GCP/Azure/Vault/Kubernetes secrets, and GitHub Actions secrets read from Runner.Worker process memory.
- Exfiltration (safedep.io): encrypted data is committed to a new public repository on the victim's GitHub account (named like smart-workers-48213, description project-utils). The commit message starts with
AutoSyncComplete:and carries the encrypted GitHub token, which other infections reuse. Fallback endpoint: hxxps://aiarmor[.]website/v1/api. Separately, the repositorystable-scripts-9965held 27 encrypted snapshot files by 25 October; their metadata did not establish victim identities or plaintext contents (gbhackers.com). - Propagation (safedep.io): injects the loader into the victim's npm packages and publishes a new patch version; republishes to PyPI, RubyGems and JFrog; commits a fake CodeQL workflow, AI agent files (.claude/settings.json, .cursor/mcp.json, CLAUDE.md, AGENTS.md, .vscode/tasks.json) and a Windows loader .github/init.ps1 to GitHub and GitLab repositories, copying the author and message of the latest real commit; copies itself over SSH to hosts in known_hosts. JFrog describes execution hooks for Claude, Gemini, Cursor and VS Code (theregister.com); session-start and workspace-opening actions can launch the payload without an explicit developer command (gbhackers.com).
- Persistence and wiper (safedep.io):
net-health-checkerchecks the stolen token every 45 seconds for 48 hours and runsrm -rf ~/; rm -rf ~/Documentson a 401/403 response.pkg-runtimeruns sync.py, which hourly searches GitHub commits formsync-3f7aand executes a Python script from a URL signed with the attacker's RSA key. - Related activity: test repositories under CementBeetleSteeple share a commit email with the npm account testnewtestme (safedep.io). JFrog linked the C2 infrastructure Socket reported to the testmetest victim cluster through artifacts and workflows on the same hijacked owners (theregister.com); shellpanel artifacts connect the owner cluster to Socket's July investigation, and workflows download
/tmp/.svcfrom 43[.]228[.]157[.]68 and attempt CVE-2026-41940 exploitation against cPanel services, with no confirmed downstream compromise (gbhackers.com). CVE-2026-41940 was added to CISA's KEV catalog in April, and cPanel has released patched versions (theregister.com).
Remediação
Guidance from gbhackers.com, relaying the JFrog research: isolate affected hosts, preserve workflow evidence, enumerate repository trees directly (not via GitHub search), and remove unauthorized hooks, branches and workflows. Remove the net-health-checker and pkg-runtime persistence before revoking stolen GitHub tokens, because the wiper fires on revocation. Then rotate exposed credentials and rebuild compromised systems from trusted sources. Disabling npm install scripts alone does not stop the newer import-time execution path. Also review repositories and CI configurations of affected owners for the AI-assistant hooks, fake CodeQL workflow, .github/init.js and .github/init.ps1, chore/ci-* branches, AutoSyncComplete: commits and oversized payload files (12.9 to 13.7 MB). Look for unexpected public repositories with project-utils descriptions, unexpected patch releases of your packages, and binding.gyp files that execute node index.js. Apply the cPanel patches for CVE-2026-41940 where relevant.
Relatos divergentes
- Victims: SafeDep (22 October) found no compromised third-party packages or victims and said all activity belonged to the operator's own test accounts (safedep.io). JFrog, as reported on 26 October, found 42 real repositories across 11 owners armed, with hijacks dating to July (theregister.com); gbhackers.com repeats the 42 repositories and 11 owners. The later JFrog finding is more current and contradicts the no-victim assessment.
- Package count: SafeDep initially counted 15 packages ending in testmetest published between 19 and 22 October, with 4 still live and 11 removed on 21 October (safedep.io). The later report cites 18 packages tied to the operator between 19 and 25 October (theregister.com), which is the more recent figure.
- Lineage: both sources note shared code with Phantom Gyp and Mini Shai-Hulud, but SafeDep explicitly leaves the exact lineage and attribution to the original Miasma operators unconfirmed (safedep.io); gbhackers.com likewise says attribution to the original Miasma operators remains unproven.
Linha do tempo
-
testmetest npm worm hijacks 42 GitHub repositories across 11 owners, steals credentials and publishes malicious packages
gbhackers.com, relaying JFrog research of 26 October and a SafeDep update of 27 October, adds the later compiled-addon packages (XOR 0x96 .napi_cache), import-time execution in @testsecuiitytestme/cache-helper 1.0.1–1.0.3 (so disabling install scripts is insufficient), the chore/ci-<hex> CI publisher branches with GitHub OIDC exchange, three npm tokens recovered across six repositories, the stable-scripts-9965 snapshot files, the 43[.]228[.]157[.]68 /tmp/.svc download and CVE-2026-41940 attempts, plus explicit remediation guidance.
ler a análise desta fonte ocultar
gbhackers.com, relaying JFrog research of 26 October and a SafeDep update of 27 October, adds the later compiled-addon packages (XOR 0x96 .napi_cache), import-time execution in @testsecuiitytestme/cache-helper 1.0.1–1.0.3 (so disabling install scripts is insufficient), the chore/ci- CI publisher branches with GitHub OIDC exchange, three npm tokens recovered across six repositories, the stable-scripts-9965 snapshot files, the 43[.]228[.]157[.]68 /tmp/.svc download and CVE-2026-41940 attempts, plus explicit remediation guidance.
Researchers Guy Korolevski and Yair Benamou (JFrog Security Research) identified 42 weaponized GitHub repositories belonging to 11 legitimate owners in the testmetest npm worm campaign. The operation combines credential theft, AI-tool and IDE execution hooks, and malicious package publishing through a hidden CI publisher. The investigation, dated 26 October, shows the campaign went beyond attacker-controlled test packages into established developers' repositories. A 27 October SafeDep update documents newer packages that trigger the worm on import, so disabling install scripts alone is not enough. Attribution to the original Miasma operators remains unproven.
Technical Details
- Early loader: malicious releases ran
index.jsthrough command expansion inbinding.gypwithout conventional install scripts. The loader used Caesar-style character transforms, AES-128-GCM decryption and a Bun 1.2.18 bootstrap to launch the stealer. One early release carried both the full worm and a separate publisher-family payload. - Later packages:
@iobandamwer/cache-helper,@iobandamwer/native-helperandpath-stream-utils-testmetestuse compiled Node.js addons. These decrypt an adjacent.napi_cachefile with XOR key0x96and run the recovered JavaScript in detached processes. - Import-time execution:
@testsecuiitytestme/cache-helper1.0.1–1.0.3 trigger the worm when an application imports the package (SafeDep, 27 October). - Repository implants:
.github/init.jsplus Claude, Gemini, Cursor and VS Code execution configs can launch the payload on session start or workspace open. The files are about 12.9–13.7 MB, which evaded GitHub search and content-retrieval paths. Direct Git tree and blob enumeration found ten wrappers that decrypt to the same publisher payload. - Hidden CI publisher: the CementBeetleSteeple account hosted publishing infrastructure on short-lived
chore/ci-<hex>branches containing a rootci.jsand an Actions workflow. The code harvests tokens, inspects trusted-publishing permissions and implements GitHub OIDC exchanges for npm publishing credentials. This shows the intended automation, not that every malicious release used it. - Fake CodeQL workflows: they export environment variables into scan-output artifacts. Researchers recovered three distinct npm tokens across six repositories. Forged commit histories were also observed.
- Evasion: Linux builds check CI variables, container markers, memory, CPU count and debugger status. Windows variants also detect Wireshark, Process Monitor and x64dbg.
- Exfil staging:
stable-scripts-9965held 27 encrypted snapshot files by 25 October. Metadata did not establish victim identities or contents. - cPanel link: Shellpanel artifacts tie the compromised owner cluster to infrastructure in Socket's July investigation. Workflows download
/tmp/.svcfrom43[.]228[.]157[.]68and attempt CVE-2026-41940 exploitation against cPanel services. JFrog did not confirm successful downstream compromise. - Wiper: the worm includes a token-revocation-triggered wiper.
Remediation
- Isolate affected hosts and preserve workflow evidence.
- Enumerate repository trees directly rather than relying on GitHub search.
- Remove unauthorized hooks, branches and workflows.
- Remove the
net-health-checkerandpkg-runtimepersistence before revoking stolen GitHub tokens, because of the wiper. - Then rotate exposed credentials and rebuild compromised systems from trusted sources.
- Early loader: malicious releases ran
-
Miasma-family 'testmetest' npm worm armed 42 real GitHub repos across 11 owners with oversized payloads that evade GitHub search
ler a análise desta fonte ocultar
A new Miasma-family npm worm, tracked as the testmetest campaign and first reported by SafeDep as a test with no victims, had in fact armed 42 real GitHub repositories belonging to 11 owners, according to JFrog. Accounts were hijacked as early as July. The payload blobs (12.9 to 13.7 MB) were large enough to evade the GitHub code search and API paths normally used to detect this kind of compromise. SafeDep had identified 18 packages tied to the operator between October 19 and 25. JFrog also linked the operator's GitHub account CementBeetleSteeple to a shellpanel scanner that Socket previously documented in a campaign exploiting CVE-2026-41940 (cPanel/WHM authentication bypass). JFrog did not confirm any downstream cPanel compromises.
Technical Details
- The worm shares code with June's Miasma Phantom Gyp worm and adds the token-revocation wiper from Mini Shai-Hulud. It self-replicates, steals credentials and installs a wiper that deletes the victim's home directory when the stolen GitHub token is revoked.
- Attackers planted execution hooks for AI coding assistants and dev tools (Claude, Gemini, Cursor, VS Code) plus polymorphic wrappers of 12.9 to 13.7 MB that decode a hidden CI-publisher payload.
- The malware modifies repositories and CI configurations and spreads via npm packages.
- A compiled native add-on decrypts and launches a separate payload. The loader checks for CI runners, containers, sandboxes and debuggers and exits silently if it finds them.
- A second build skips the encrypted file: it forks, detaches and runs a hard-coded command that pulls a loader from a repository on the operator's GitHub account. That account hosted 17 campaign repositories.
- JFrog linked the C2 infrastructure reported by Socket to the testmetest victim cluster through artifacts and workflows on the same hijacked owners.
- CVE-2026-41940 was added to CISA's KEV catalog in April, and cPanel has since released patched versions.
Remediation
The article gives no explicit guidance. Note that revoking a stolen GitHub token can trigger the wiper, so defenders should take this into account before revoking tokens on potentially infected hosts. Defenders should also review repositories and CI configurations of affected owners for the hooks and oversized payload files described above.
-
testmetest npm packages carry Miasma-family worm with token-revocation wiper; operator testing in public
ler a análise desta fonte ocultar
Between 19 and 22 October 2026, an operator published 15 npm packages whose names end in testmetest, carrying a Miasma-family self-propagating worm. The malicious versions steal credentials, spread to other packages and repositories, and install a wiper that deletes the victim's home directory when the stolen GitHub token is revoked. SafeDep found shared code with Miasma "Phantom Gyp" (June 2026) and the token-revocation wiper from Mini Shai-Hulud, but has not confirmed the exact lineage and does not attribute it to the original Miasma operators. As of 22 October 2026, SafeDep found no compromised third-party packages or victims; all activity belongs to the operator's own test accounts. Four packages remain live, and the other eleven were removed on 21 October.
Technical Details
- Delivery: each package follows three steps: a 0.0.0 stub, a harmless 1.0.0 decoy, then a malicious patch version (e.g. 0.0.1) that becomes latest. There are no install scripts. A
binding.gypmakes npm runnode-gyp rebuild, and itssourcesfield executesnode index.jswith output hidden.index.js(14.8 KB) decrypts a Bun bootstrap andlib_native.dat(320 KB), writes the payload to/tmp/.b-*/index.js, runs it withbun runand deletes it. - Evasion: exits on Russian and other CIS locales and on known analysis sandboxes. In GitHub Actions it kills StepSecurity Harden-Runner through docker.sock and points *.stepsecurity.io to localhost, exiting if that fails.
- Credential theft: SSH keys, npm, PyPI and Git credentials, .env files, browser logins, AI tool credentials (Claude, Codex, Gemini, Copilot), AWS/GCP/Azure/Vault/Kubernetes secrets, and GitHub Actions secrets from Runner.Worker process memory.
- Exfiltration: commits encrypted data to a new public repository on the victim's GitHub account (named like smart-workers-48213, description project-utils). The commit message starts with
AutoSyncComplete:and carries the encrypted GitHub token, which other infections reuse. Fallback endpoint: hxxps://aiarmor[.]website/v1/api. - Propagation: injects the loader into the victim's npm packages and publishes a new patch version; republishes to PyPI, RubyGems and JFrog; commits a fake CodeQL workflow, AI agent files (.claude/settings.json, .cursor/mcp.json, CLAUDE.md, AGENTS.md, .vscode/tasks.json) and a Windows loader .github/init.ps1 to GitHub and GitLab repositories, copying the author and message of the latest real commit; copies itself over SSH to hosts in known_hosts.
- Persistence and wiper:
net-health-checkerchecks the stolen token every 45 seconds for 48 hours and runsrm -rf ~/; rm -rf ~/Documentson 401/403.pkg-runtimeruns sync.py, hourly searching GitHub commits formsync-3f7aand executing a Python script from a URL signed with the attacker's RSA key. - Related activity: test repositories under GitHub account CementBeetleSteeple (same commit email as npm account testnewtestme); account Meteordrewarm ran the first exfiltration test on 19 September; npm removed testmgkregme on 12 October. Accounts alexjoipamiba and testnewtestme published four of the packages. Hashes change per build, and the infrastructure and strings differ from Miasma, defeating published Miasma signatures.
- Detection: a binding.gyp target with
<!(nodein sources that hides output in a package with no C/C++ sources; a high-entropy .dat/.bin beside a small index.js with a large character-code array and eval; supporting signals are a bun dependency or a 0.0.x latest version published after 1.0.0.
Remediation
- Apply the binding.gyp detection rule to all packages; a real attack would come through compromised maintainer accounts with normal package names.
- On an infected host, disconnect from the network and remove persistence first (disable the net-health-checker and pkg-runtime systemd user services and delete their files on Linux; bootout and delete the com.user.* LaunchAgent plists on macOS).
- Rotate all credentials: Git hosts, package registries, cloud, Vault, Kubernetes, SSH and AI providers.
- Check accounts for new project-utils repositories, unexpected patch releases, commits adding agent files (.claude/, .cursor/, .gemini/, .vscode/tasks.json, CLAUDE.md, AGENTS.md) and commits starting with AutoSyncComplete:. The agent files can reinfect the host.
- Reinstall the operating system on the host. Do not clone or open the CementBeetleSteeple repositories.
- Delivery: each package follows three steps: a 0.0.0 stub, a harmless 1.0.0 decoy, then a malicious patch version (e.g. 0.0.1) that becomes latest. There are no install scripts. A