{"id":"MAL-2026-18180","summary":"Malicious code in pixel-map-testmetest (npm)","details":"pixel-map-testmetest 0.0.1 and 0.0.2 ship a rebuild of the data-pipeline-testmetest 2.0.1 credential stealer and run it on `npm install`: their `binding.gyp` source `\u003c!(env node index.js \u003e/dev/null 2\u003e&1; echo stub.c)` makes node-gyp run `index.js`, which decrypts `data.bin` and pipes it into Bun. The package.json poses as an npm staged-publishing placeholder (`\"stub\": true`, \"Temporary package placeholder for staged publishing\"). Published by npm account `newtestnewdont` on 2026-10-21 after a benign 1.0.0; the same account published benign-looking color-utils-testmetest, string-helpers-testmetest and byte-stride-testmetest. 0.0.2 (published 3.5 hours after 0.0.1) is the same loader and hook with a re-encrypted, additionally obfuscated payload.\n\n---\n_-= Per source details. Do not edit below this line.=-_\n\n## Source: amazon-inspector (65072803ff6a65eee326b518b2039415559b4f8582f44b2f2af2f871aea9f39e)\nOn npm install, node-gyp automatically processes binding.gyp. The binding.gyp here declares target type 'none' with no C/C++ sources and abuses GYP command-expansion `\u003c!(env node index.js...; echo stub.c)` to execute index.js at install time. index.js is a Caesar-cipher/charcode-obfuscated loader wrapped in eval that AES-128-GCM-decrypts a 319 KB sibling blob (data.bin) using hex key/iv/aad hardcoded in the loader, brotli-decompresses the result, writes it into a mkdtemp'd `.b-\u003crand\u003e` directory, and spawns the Bun runtime (declared as an npm dependency `bun ^1.2.18`) to execute the dropped file, bypassing Node-based inspection. package.json sets `stub: true` with description 'Temporary package placeholder for staged publishing' and the README claims a holding version, yet the tarball ships the obfuscated loader, the encrypted blob, the binding.gyp install hook, and the alternate runtime — the stated purpose contradicts the shipped behavior. The actual payload bytes are not inspectable statically; the combination of install-time execution, multi-layer obfuscation, hardcoded-key AES-encrypted blob, drop-to-temp, and alternate-runtime execution matches the npm alternate-runtime dropper pattern.\n","modified":"2026-10-22T06:45:05.786449822Z","published":"2026-10-21T18:00:00Z","database_specific":{"iocs":{"files":[{"digests":{"sha256":"fda4df745212660faa56de9d1f20739402b418aab082401c38a4d3c1304123d3"},"note":"hidden install hook: node-gyp runs `env node index.js` (identical in 0.0.1 and 0.0.2)","paths":["binding.gyp"],"source":"PACKAGE_ARCHIVE"},{"paths":["index.js"],"source":"PACKAGE_ARCHIVE","digests":{"sha256":"037eb654e4c93639e2cdec37957be72cc4ab846925d6822fe95b60f403001615"},"note":"0.0.1: obfuscated loader that decrypts `data.bin` and pipes it into `bun run -`"},{"source":"PACKAGE_ARCHIVE","digests":{"sha256":"74a728fb7ee7ac6c47263def3f104974a1b7032090c8f9005116526bc742e09c"},"note":"0.0.1: AES-GCM-encrypted stealer payload","paths":["data.bin"]},{"source":"IN_MEMORY","digests":{"sha256":"89c8129a165da5b6d02b24d7028be74ba7372c0eaa8847f24d1d939597a4d6db"},"note":"0.0.1: decrypted 949 KB Bun payload, a rebuild of the data-pipeline-testmetest 2.0.1 stealer"},{"paths":["index.js"],"source":"PACKAGE_ARCHIVE","digests":{"sha256":"63ffef158a79371383e9c8a67dfba6999c7601cd3555cc7b13c6d095b7871ee7"},"note":"0.0.2: obfuscated loader that decrypts `data.bin` and runs it with Bun"},{"digests":{"sha256":"066b6e27373fc5be3f0a5907ffbb945e3a502f8ee74edaf917ccdc011a9a7a0d"},"note":"0.0.2: AES-GCM-encrypted stealer payload","paths":["data.bin"],"source":"PACKAGE_ARCHIVE"},{"source":"IN_MEMORY","digests":{"sha256":"d5e5f243d464249d2d2607a2d01dbc7e7d6c897fa6b3c7d7c312d7caece9e1cf"},"note":"0.0.2: decrypted 1.1 MB Bun payload, the same stealer with additional obfuscation"}]},"malicious-packages-origins":[{"import_time":"2026-10-22T06:30:25.017029844Z","modified_time":"2026-10-22T06:11:58Z","sha256":"96016490b5f0c2f7a205f4108c012955c1bbaaff0d2ba1904d18747752a6c729","source":"amazon-inspector","versions":["0.0.3"],"id":"IN-MAL-2026-021579"},{"sha256":"a5c16a91271c0413b0f19842d37f3d94fdd9bf7edf2e70f67da4ae8bdc52cf5b","source":"amazon-inspector","versions":["0.0.1"],"id":"IN-MAL-2026-021574","import_time":"2026-10-22T06:30:24.440343164Z","modified_time":"2026-10-22T06:11:19Z"},{"source":"amazon-inspector","versions":["0.0.2"],"id":"IN-MAL-2026-021581","import_time":"2026-10-22T06:30:25.204140586Z","modified_time":"2026-10-22T06:12:15Z","sha256":"65072803ff6a65eee326b518b2039415559b4f8582f44b2f2af2f871aea9f39e"}]},"references":[{"type":"PACKAGE","url":"https://www.npmjs.com/package/pixel-map-testmetest/v/0.0.1"},{"type":"PACKAGE","url":"https://www.npmjs.com/package/pixel-map-testmetest/v/0.0.2"},{"type":"PACKAGE","url":"https://www.npmjs.com/package/pixel-map-testmetest/v/0.0.3"}],"affected":[{"package":{"name":"pixel-map-testmetest","ecosystem":"npm","purl":"pkg:npm/pixel-map-testmetest"},"versions":["0.0.1","0.0.2","0.0.3"],"database_specific":{"source":"https://github.com/ossf/malicious-packages/blob/main/osv/malicious/npm/pixel-map-testmetest/MAL-2026-18180.json","cwes":[{"cweId":"CWE-506","description":"The product contains code that appears to be malicious in nature.","name":"Embedded Malicious Code"},{"cweId":"CWE-506","description":"The product contains code that appears to be malicious in nature.","name":"Embedded Malicious Code"},{"cweId":"CWE-506","description":"The product contains code that appears to be malicious in nature.","name":"Embedded Malicious Code"},{"description":"The product contains code that appears to be malicious in nature.","name":"Embedded Malicious Code","cweId":"CWE-506"}],"indicators":{"package_integrity":[{"filename":"pixel-map-testmetest-0.0.3.tgz","hashes":{"sha1":"321ad3a46c29ad57cf619d5c1fac6071923318e1","sha512_sri":"sha512-21xTwtLwm4ZEc++yfo8TpaAjP00nzmS9tUMDtno7Ct5yPlvt8AT4KJptL1cd3+OctOGv8prMLke9F8wQD6ua3Q=="}}],"evidence_files":[{"path":"binding.gyp","sha256":"fda4df745212660faa56de9d1f20739402b418aab082401c38a4d3c1304123d3","tlsh":"e9c08c2cb838094539d91c3491a88402a4b242a3485a2d41fade60286fb841f288cb9d"},{"path":"index.js","sha256":"0cb9fc3dcb1ac21082de3d60eaaf91bea9b350489b42a8bc9e22003d29ca8155","tlsh":"336250a267891ba561c80cf6b39d7503a9a0e84f35b07b68ffd25597bd3d522bc20370"},{"path":"package.json","sha256":"640ddc300b1bc5ccebc574fffff56c6a9118bafeaba21b0f86ee6602428c1969","tlsh":"d3c01210a551d97640de136454a9e0675b7b9d1f104c64082b8b21484b1c5fb70bb646"}]}}}],"schema_version":"1.9.0","credits":[{"name":"Amazon Inspector","contact":["inspector-research@amazon.com"],"type":"FINDER"},{"name":"Robin Frehner, Protet","contact":["https://protet.io","mailto:hello@protet.io"],"type":"FINDER"}]}