{"id":"MAL-2026-13933","revision":null,"records":[{"revision":"90de8e3fd887449db142950b0f9ab38f","observedAt":"2026-10-24T13:17:17.793+00:00","statement":{"source":"osv","id":"MAL-2026-13933","aliases":[],"title":"Malicious code in cc-skills-helper (npm)","description":"The npm package `cc-skills-helper` is a Windows-only supply-chain dropper published as seven versions (1.0.0 through 1.0.6) in a single 8-hour burst on 2026-04-25 by npm user `betatester44676` (`mayukh.halder02@gmail.com`), then abandoned. `dist-tags.latest` points at 1.0.6.\n\nAll seven versions share the same postinstall behaviour. `scripts/postinstall.js` invokes `activateTool()` in `lib/index.js`, which:\n\n  1. Fetches a JSON config from the hard-coded C2 `https://kiro-cheap.pro/api/config` (rotatable via the `MY_TOOL_SERVER` env var); the config returns `{ archiveUrl, password, version }`.\n  2. Downloads a password-protected ZIP from `archiveUrl` (attacker-controlled, size-capped at 500 MiB).\n  3. Decrypts the ZIP with the returned `password` to recover a Windows PE (`MZ`/`PE` header-verified).\n  4. Stages the payload under `%LOCALAPPDATA%\\cc-skills-helper\\bin\\helper-<8-hex>.exe` — the install directory is chosen with a comment (in the shipped source) explaining that `%LOCALAPPDATA%` is scanned less aggressively by Windows Defender than `%TEMP%`.\n  5. Writes the payload as `.dat` first and atomic-renames to `.exe` right before spawn — commented as an evasion for Defender's real-time scanner (\"skips .dat extensions\").\n  6. Best-effort issues PowerShell `Add-MpPreference -ExclusionPath` on the install directory to add a Defender exclusion (works if the npm install is run from an elevated shell).\n  7. Spawns the `.exe`; on `UNKNOWN`/`EACCES`/`EPERM` from `CreateProcess` (\"Defender scanner-lock on freshly-written file\"), falls back to launching through `cmd.exe /d /s /c`.\n  8. The user-facing error message literally instructs the victim on how to add a Defender exclusion themselves.\n\nBecause the archive is password-protected, static analysis of the published npm tarball cannot see the payload — only the loader. The payload URL and password are fetched from the C2 at install time, so the same package version can serve different payloads to different victims or different times.\n\nVersion 1.0.6 (currently tagged `latest`) is obfuscator.io-hardened (`_0x<hex>` string-array + accessor-function scheme). 1.0.0-1.0.5 ship clear-code variants of the same logic. The `package.json` description is a legitimacy masquerade — it claims the design mirrors `esbuild`, `swc`, `sharp`, and `@parcel/watcher` native-companion distribution, but those all ship code-signed multi-platform binaries via npm tarballs and well-known CDNs; `cc-skills-helper` is Windows-only, hosted on an ad-hoc third-party domain, and encrypted.\n\nAt the time of this report, the C2 host `kiro-cheap.pro` is intercepted by Cloudflare with a `Suspected Phishing` interstitial (primary distribution path neutralised), but any Windows host that ran `npm install cc-skills-helper` between 2026-04-25 and the Cloudflare block executed attacker-supplied native code.","state":0,"publishedAt":"2026-08-12T00:00:00+00:00","modifiedAt":"2026-09-11T04:00:06.5787814+00:00","affected":[{"ecosystem":"npm","name":"cc-skills-helper","ranges":[],"versions":["1.0.0","1.0.1","1.0.2","1.0.3","1.0.4","1.0.5","1.0.6"],"rawVersionEvidence":null}],"metrics":[],"references":["https://research.codelake.dev/advisories/clr-2026-3044-cc-skills-helper"],"sourceUrl":"https://osv.dev/vulnerability/MAL-2026-13933","license":"OSV · upstream source license applies","key":"osv:MAL-2026-13933","identifiers":["MAL-2026-13933"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-15T01:46:55.4086044+00:00","complete":true,"records":1781,"lastAttemptAt":"2026-11-15T01:46:55.4086044+00:00","lastSuccessAt":"2026-11-15T01:46:55.6001265+00:00","error":null,"lastVerifiedAt":"2026-11-15T01:46:55.6001272+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-7de4d7559a5263003f03d9f70577ab06f92ba4178309f26fce53e22a4a959294-6d7324039073d7c231ba830a084e1f9dd49e3546760dbb1c1c5420bea3fe5eb4","complete":true,"records":425760,"lastAttemptAt":"2026-11-15T01:44:29.7063286+00:00","lastSuccessAt":"2026-11-15T01:44:29.696786+00:00","error":null,"lastVerifiedAt":"2026-11-15T01:44:29.7063286+00:00","snapshotPublishedAt":"2026-11-15T01:24:40+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-d9152245ba1543998e3cfd20d6aff81f","complete":false,"records":13821,"lastAttemptAt":"2026-11-15T01:47:18.6650027+00:00","lastSuccessAt":"2026-11-15T01:47:18.7556446+00:00","error":null,"lastVerifiedAt":"2026-11-15T01:47:18.7556446+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-15T01:46:55.4086044+00:00","complete":true,"records":1125,"lastAttemptAt":"2026-11-15T01:46:55.4086044+00:00","lastSuccessAt":"2026-11-15T01:46:55.6012797+00:00","error":null,"lastVerifiedAt":"2026-11-15T01:46:55.6012836+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-a2d6726fa6984ccea1afed1a3e59d87e","complete":false,"records":13833,"lastAttemptAt":"2026-11-15T01:47:00.8199552+00:00","lastSuccessAt":"2026-11-15T00:31:15.078+00:00","error":"13 identifier lookups failed; latest failures include HttpError (HTTP 503). Other identifiers were checked independently.","lastVerifiedAt":"2026-11-15T00:31:15.078+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13861,"expectedIdentifiers":13874,"failedIdentifiers":13},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-64eea06dbd27de8464d5dbce1b78cc794cc59e2d901516ae0d3ea76e624cdae0","complete":true,"records":9955,"lastAttemptAt":"2026-11-15T01:46:55.2267037+00:00","lastSuccessAt":"2026-11-14T13:57:23.1208135+00:00","error":null,"lastVerifiedAt":"2026-11-15T01:46:55.2267037+00:00","snapshotPublishedAt":"2026-11-14T13:17:57+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-f4424d7d4861b1af1404bd15abcb83f295dcd003412a9340ca99dc8200aa148a","complete":true,"records":2014,"lastAttemptAt":"2026-11-15T01:44:50.4630562+00:00","lastSuccessAt":"2026-11-13T19:57:08.2864435+00:00","error":null,"lastVerifiedAt":"2026-11-15T01:44:50.4630562+00:00","snapshotPublishedAt":"2026-11-13T19:33:10+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-012aff9b2fb349d53e2c4bace6ca57956b6f5f9d82c1dc9fdc1c9b3c738f8977","complete":true,"records":3148,"lastAttemptAt":"2026-11-15T01:46:55.3300683+00:00","lastSuccessAt":"2026-11-14T04:57:03.8279646+00:00","error":null,"lastVerifiedAt":"2026-11-15T01:46:55.3300683+00:00","snapshotPublishedAt":"2026-11-14T03:02:50+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-deb41cb32d3b3d67de7960b1647d789a5218551d33a54a4b027ba315bcba590f","complete":true,"records":232473,"lastAttemptAt":"2026-11-15T01:46:55.093583+00:00","lastSuccessAt":"2026-11-15T01:46:53.6377511+00:00","error":null,"lastVerifiedAt":"2026-11-15T01:46:55.093583+00:00","snapshotPublishedAt":"2026-11-15T00:48:23+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}