{"dataType":"CVE_RECORD","dataVersion":"1.0","cveMetadata":{"cveId":"GCVE-110-OSM-2026-14716","assignerOrgId":"","assignerShortName":"Vulnetix","state":"PUBLISHED","datePublished":"2026-11-07T09:01:01Z","dateUpdated":"2026-11-06T18:52:57Z","dateReserved":""},"containers":{"cna":{"providerMetadata":null,"title":"","descriptions":[{"lang":"en","value":"Standalone RubyGems package posing as a string helper library that runs a self-propagating credential-stealing worm when it is installed. It steals cloud, CI, package registry, SSH, AI coding tool and wallet credentials, republishes itself into other packages with stolen registry tokens, installs a persistent backdoor, poisons AI coding tool configuration, and deletes the user's home directory if a stolen GitHub token is revoked. It is a later build of the Miasma-family (testmetest) worm that descends from TeamPCP's open-sourced Mini Shai-Hulud worm. Removing the gem does not remove the infection.\n\n## Payload 1: install-time loader\n\nMalicious payload found in: `ext/strutil-core/extconf.rb`\n\n- Trigger: RubyGems runs the native extension script during `gem install` or `bundle install`. The gem does not need to be required.\n- Behavior: On Linux and macOS (x86-64 and ARM64) it creates `/tmp/.b_\u003cpid\u003e`, downloads Bun 1.2.18 from the official oven-sh GitHub releases, and runs `ext/strutil-core/index.js` with it. It then writes a Makefile with empty targets so the install finishes without errors.\n- Note: the file is identical to the output of the worm's own RubyGems injection module, and the gem's `VERSION` constant still says 1.0.0 inside the 1.0.1 release.\n\n## Payload 2: worm bundle\n\nMalicious payload found in: `ext/strutil-core/index.js`\n\n- Size and obfuscation: 5.48 MB Bun bundle with a rotated string table, a PBKDF2-keyed string cipher, and AES-256-GCM encrypted embedded components.\n- Locale check: exits on Russian, Belarusian, Kazakh, Uzbek, Kyrgyz, Tajik, Armenian, Azerbaijani, Ukrainian, Georgian, Turkmen and Moldovan locales.\n- Collection: AWS, Azure, Google Cloud, Kubernetes, Vault, npm, PyPI, RubyGems, Docker, SSH, password managers, keychains, wallets and AI coding tool credential files (for example `.claude/.credentials.json` and `.codex/auth.json`).\n- GitHub Actions: reads the Runner.Worker process memory through `/proc/\u003cpid\u003e/mem`, kills the StepSecurity Harden-Runner container, grants the runner passwordless sudo, and redirects stepsecurity[.]io hostnames to localhost.\n- Exfiltration: results are encrypted and posted to `hxxps://paleasbest[.]top/v1/api`. Fallbacks are a public GitHub repository described as `project-utils` with a generated adjective-noun-number name, or GitLab. Commits carrying stolen tokens use the `AutoSyncComplete` prefix.\n- Propagation: republishing routines for RubyGems, npm and PyPI, JFrog Artifactory, GitHub and GitLab spreading, a fake CodeQL workflow that uploads secrets as an artifact, and SSH spreading through `known_hosts`.\n- Persistence: `~/.local/share/runtimes/sync.py` registered as the `pkg-runtime` systemd user service or `com.user.pkg-runtime` LaunchAgent. It polls public GitHub commits for the marker `msync-3f7a` and runs any script URL carrying a valid signature from the threat actor.\n- AI tool poisoning: adds a `workspace-tools` MCP server and SessionStart hooks to local configs, and commits `.github/init.js`, `.claude/settings.json`, `.cursor/mcp.json`, `CLAUDE.md`, `AGENTS.md` and a `.vscode/tasks.json` task into repositories reachable with stolen Git credentials.\n- Wiper: when a stolen GitHub token is accepted, `net-health-checker` checks it against the GitHub API every 45 seconds for 48 hours. A 401 or 403 response runs `rm -rf ~/; rm -rf ~/Documents`. Stop `net-health-checker` and `pkg-runtime` before revoking the token.","supportingMedia":null}],"references":[{"url":"https://opensourcemalware.com/threats/0265ba6a-9130-4f39-a2a2-aca584bc6af2","name":"Malicious rubygems package: strutil-core","tags":["advisory"]},{"url":"https://rubygems.org/strutil-core","name":"","tags":["vendor"]}],"metrics":[{"format":"CVSS_V3","scenarios":null,"cvssV2_0":null,"cvssV3_0":null,"cvssV3_1":{"version":"3.1","vectorString":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H","baseScore":9.6,"baseSeverity":"CRITICAL"},"cvssV4_0":null,"other":null}],"problemTypes":[{"descriptions":[{"lang":"en","description":"Embedded Malicious Code","cweId":"CWE-506","type":"CWE"}]}],"affected":[{"vendor":"unknown","product":"strutil-core","collectionURL":"https://rubygems.org","packageName":"strutil-core","repo":"","defaultStatus":"affected","versions":[{"version":"all","status":"affected","versionType":"","lessThan":"","lessThanOrEqual":"","changes":null}],"cpes":null,"modules":null,"programFiles":null,"platforms":null}],"cpeApplicability":null,"rejectedReasons":null,"replacedBy":null},"adp":null}}