UNPKG

stencyption

Version:

Military-grade JavaScript encryption with AES-256-GCM, polymorphic obfuscation, and anti-debugging protection. Each file gets unique encryption keys embedded in heavily obfuscated code.

159 lines (129 loc) 5.53 kB
const crypto = require('crypto'); const fs = require('fs'); const path = require('path'); const MASTER_KEY = 'StEncRyPt10N_M4sT3r_K3y_2024_S3cUr3_C0d3_Pr0T3cT10N_SySt3m'; const ENCRYPTION_ALGORITHM = 'aes-256-cbc'; class StencryptionRuntime { static getMasterKey() { return crypto.createHash('sha256').update(MASTER_KEY).digest(); } static decryptAES(encryptedData) { const [ivHex, encryptedHex] = encryptedData.split(':'); const iv = Buffer.from(ivHex, 'hex'); const encrypted = Buffer.from(encryptedHex, 'hex'); const key = this.getMasterKey(); const decipher = crypto.createDecipheriv(ENCRYPTION_ALGORITHM, key, iv); let decrypted = decipher.update(encrypted); decrypted = Buffer.concat([decrypted, decipher.final()]); return decrypted.toString('utf8'); } static multiLayerDeobfuscate(str) { let result = str; for (let layer = 4; layer >= 0; layer--) { result = Buffer.from(result, 'base64').toString('utf8'); result = result.split('').map((c, i) => { const shift = ((i * 13 + layer * 7) % 94) + 33; const code = c.charCodeAt(0); return String.fromCharCode(((code - 33 - shift + 9400) % 94) + 33); }).join(''); } return result; } static unwrapStealth(payload) { const decoded = Buffer.from(payload, 'base64').toString('utf8'); const unshifted = decoded.split('').map((c, i) => { const shift = (i * 17 + 23) % 126; return String.fromCharCode(((c.charCodeAt(0) - shift + 12600) % 126)); }).join(''); return unshifted; } static isESModule(code) { return /^\s*(import\s+.*\s+from|export\s+(default|const|let|var|function|class))/m.test(code); } static run(payload, importData = '', callerModule = null, callerRequire = null, callerFilename = null, callerDirname = null) { try { const unwrapped = this.unwrapStealth(payload); const deobfuscated = this.multiLayerDeobfuscate(unwrapped); const decrypted = this.decryptAES(deobfuscated); const finalCode = decrypted; if (this.isESModule(finalCode)) { const tmpFile = path.join(require('os').tmpdir(), `stenc_${Date.now()}_${Math.random().toString(36).substr(2, 9)}.mjs`); fs.writeFileSync(tmpFile, finalCode, 'utf8'); const importModule = new Function('filepath', 'return import(filepath)'); return importModule(tmpFile).then(module => { try { fs.unlinkSync(tmpFile); } catch (e) {} return module; }).catch(err => { try { fs.unlinkSync(tmpFile); } catch (e) {} throw err; }); } else { // If we have the caller's module context, use Module._compile to preserve global state if (callerModule && typeof callerModule._compile === 'function') { try { // Use the caller's module to compile the code, preserving its context callerModule._compile(finalCode, callerFilename || 'encrypted-module.js'); return callerModule.exports; } catch (err) { throw err; } } else { // Fallback to the old method if module context is not available let callerPath = process.cwd(); const stack = new Error().stack; const stackLines = stack.split('\n'); for (const line of stackLines) { if (line.includes('.js') && !line.includes('runtime.js') && !line.includes('index.js') && !line.includes('node_modules')) { const match = line.match(/\((.+\.js):\d+:\d+\)/) || line.match(/at\s+(.+\.js):\d+:\d+/); if (match && match[1]) { const encryptedFilePath = match[1]; if (fs.existsSync(encryptedFilePath)) { callerPath = path.dirname(path.resolve(encryptedFilePath)); break; } } } } const tmpFile = path.join(callerPath, `stenc_${Date.now()}_${Math.random().toString(36).substr(2, 9)}.js`); fs.writeFileSync(tmpFile, finalCode, 'utf8'); try { delete require.cache[path.resolve(tmpFile)]; const Module = require('module'); const originalRequire = Module.prototype.require; Module.prototype.require = function(id) { if (id.startsWith('.')) { const resolvedPath = path.resolve(callerPath, id); if (fs.existsSync(resolvedPath) || fs.existsSync(resolvedPath + '.js')) { return originalRequire.call(this, resolvedPath); } } return originalRequire.call(this, id); }; const loadedModule = require(tmpFile); Module.prototype.require = originalRequire; try { fs.unlinkSync(tmpFile); } catch (e) {} return loadedModule; } catch (err) { try { fs.unlinkSync(tmpFile); } catch (e) {} throw err; } } } } catch (error) { throw new Error(`Stencyption execution error: ${error.message}`); } } } if (typeof global !== 'undefined') { global.__stencyption__ = StencryptionRuntime; } module.exports = { StencryptionRuntime };