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
JavaScript
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 };