obfuscator-io-deobfuscator
obfuscator-io-deobfuscator copied to clipboard
Feature request: Remove canary traps/tamper proofing/self defense
The obfuscator can add a trap that checks if the code has been auto-formatted by checking for newlines in a few function definitions. For example, in the payload for the recent polyfill dot io supply chain attack there is a snippet that with better variable names looks like this:
const canary_checker_object = function (_0x51f4b1) {
this.cvuinS = _0x51f4b1;
this.fyrkaT = [1, 0, 0];
// This is the canary that is checked for newlines and spaces
this.canary = function(){return'newState';};
// This is the regex that checks it
this.IZqJeb = "\\w+ *\\(\\) *{\\w+ *";
this.kmcauN = "['|\"].+['|\"];? *}";
};
canary_checker_object.prototype.check_canary = function () {
const _0x551808 = new RegExp(this.IZqJeb + this.kmcauN);
const _0xec967d = _0x551808.test(this.canary.toString()) ? --this.fyrkaT[1] : --this.fyrkaT[0];
return this.KiEDhy(_0xec967d);
};
canary_checker_object.prototype.KiEDhy = function (_0xf8c99b) {
if (!Boolean(~_0xf8c99b)) {
return _0xf8c99b;
}
return this.canary_trap(this.cvuinS);
};
canary_checker_object.prototype.canary_trap = function (_0xe722ea) {
let _0x149a72 = 0;
// This is an infinitely allocating infinite loop
for (let _0x3fe735 = this.fyrkaT.length; _0x149a72 < _0x3fe735; _0x149a72++) {
this.fyrkaT.push(Math.round(Math.random()));
_0x3fe735 = this.fyrkaT.length;
}
return _0xe722ea(this.fyrkaT[0]);
};
new canary_checker_object(decode_string).check_canary();
which checks if the function canary
contains any newlines and if it doesn't, it causes an infinite loop that expands the array fyrkaT
indefinitely with random numbers.
After removing dead code, most of the code remaining are just different traps for causing infinite loops:
Full code with the entire trap but the actual payload removed
// This function calls the a0_0xa0b8 function which checks for tampering and causes infinite loops or incorrect values
// If the incorrect value is returned, this function loops infinitely
(function (_0x10c19b, _0x5753e1) {
const _0x208c16 = _0x10c19b();
while (true) {
try {
const _0x2ba9d2 = -parseInt(a0_0xa0b8(314, 'c@Hn')) / 1 * (-parseInt(a0_0xa0b8(275, 'OZos')) / 2) + parseInt(a0_0xa0b8(295, 'p6OJ')) / 3 * (parseInt(a0_0xa0b8(441, '!(Jy')) / 4) + parseInt(a0_0xa0b8(475, 'c@Hn')) / 5 + parseInt(a0_0xa0b8(418, 'Lvkz')) / 6 + -parseInt(a0_0xa0b8(428, 'cWDm')) / 7 * (parseInt(a0_0xa0b8(545, 'OZos')) / 8) + parseInt(a0_0xa0b8(669, 'llA^')) / 9 + -parseInt(a0_0xa0b8(480, 'OZos')) / 10;
if (_0x2ba9d2 === _0x5753e1) {
break;
} else {
_0x208c16.push(_0x208c16.shift());
}
} catch (_0x4f2418) {
_0x208c16.push(_0x208c16.shift());
}
}
})(a0_0x5173, 550813);
// Removed some actual payload
function a0_0xa0b8(_0x6db2f9, _0x437aca) {
const _0x58e91a = a0_0x5173();
a0_0xa0b8 = function (_0xf2c0d2, _0x1eeda0) {
_0xf2c0d2 = _0xf2c0d2 - 257;
let _0x530d4e = _0x58e91a[_0xf2c0d2];
if (a0_0xa0b8.UWwKby === undefined) {
var _0x562627 = function (_0x2686a4) {
let _0x370cb1 = '';
let _0x58f4ed = '';
// This is the source of the current function. It is checked for newlines
let _0x6790dd = _0x370cb1 + _0x562627;
let _0x4e439b = 0;
let _0x273cb0;
let _0x418acb;
for (let _0xa86a1c = 0; _0x418acb = _0x2686a4.charAt(_0xa86a1c++); ~_0x418acb && (_0x273cb0 = _0x4e439b % 4 ? _0x273cb0 * 64 + _0x418acb : _0x418acb, _0x4e439b++ % 4) ? _0x370cb1 += _0x6790dd.charCodeAt(_0xa86a1c + 10) - 10 !== 0 ? String.fromCharCode(255 & _0x273cb0 >> (-2 * _0x4e439b & 6)) : _0x4e439b : 0) {
_0x418acb = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/='.indexOf(_0x418acb);
}
let _0x166c6e = 0;
for (let _0x3e61bd = _0x370cb1.length; _0x166c6e < _0x3e61bd; _0x166c6e++) {
_0x58f4ed += '%' + ('00' + _0x370cb1.charCodeAt(_0x166c6e).toString(16)).slice(-2);
}
return decodeURIComponent(_0x58f4ed);
};
const _0x47f1dd = function (_0xc5bde6, _0x44884f) {
let _0x421af5 = [];
let _0x705d3f = 0;
let _0x16ba4e;
let _0x4f31ee = '';
_0xc5bde6 = _0x562627(_0xc5bde6);
let _0x29df4f;
for (_0x29df4f = 0; _0x29df4f < 256; _0x29df4f++) {
_0x421af5[_0x29df4f] = _0x29df4f;
}
for (_0x29df4f = 0; _0x29df4f < 256; _0x29df4f++) {
_0x705d3f = (_0x705d3f + _0x421af5[_0x29df4f] + _0x44884f.charCodeAt(_0x29df4f % _0x44884f.length)) % 256;
_0x16ba4e = _0x421af5[_0x29df4f];
_0x421af5[_0x29df4f] = _0x421af5[_0x705d3f];
_0x421af5[_0x705d3f] = _0x16ba4e;
}
_0x29df4f = 0;
_0x705d3f = 0;
for (let _0x235057 = 0; _0x235057 < _0xc5bde6.length; _0x235057++) {
_0x29df4f = (_0x29df4f + 1) % 256;
_0x705d3f = (_0x705d3f + _0x421af5[_0x29df4f]) % 256;
_0x16ba4e = _0x421af5[_0x29df4f];
_0x421af5[_0x29df4f] = _0x421af5[_0x705d3f];
_0x421af5[_0x705d3f] = _0x16ba4e;
_0x4f31ee += String.fromCharCode(_0xc5bde6.charCodeAt(_0x235057) ^ _0x421af5[(_0x421af5[_0x29df4f] + _0x421af5[_0x705d3f]) % 256]);
}
return _0x4f31ee;
};
a0_0xa0b8.WEMegZ = _0x47f1dd;
_0x6db2f9 = arguments;
a0_0xa0b8.UWwKby = true;
}
const _0x18b3a9 = _0x58e91a[0];
const _0x491855 = _0xf2c0d2 + _0x18b3a9;
const _0x125d04 = _0x6db2f9[_0x491855];
if (!_0x125d04) {
if (a0_0xa0b8.OJUoMm === undefined) {
const _0x2e77ae = function (_0x51f4b1) {
this.cvuinS = _0x51f4b1;
this.fyrkaT = [1, 0, 0];
this.rPgZEm = function () {
return 'newState';
};
this.IZqJeb = "\\w+ *\\(\\) *{\\w+ *";
this.kmcauN = "['|\"].+['|\"];? *}";
};
_0x2e77ae.prototype.sxNFHR = function () {
const _0x551808 = new RegExp(this.IZqJeb + this.kmcauN);
const _0xec967d = _0x551808.test(this.rPgZEm.toString()) ? --this.fyrkaT[1] : --this.fyrkaT[0];
return this.KiEDhy(_0xec967d);
};
_0x2e77ae.prototype.KiEDhy = function (_0xf8c99b) {
if (!Boolean(~_0xf8c99b)) {
return _0xf8c99b;
}
return this.aMpklD(this.cvuinS);
};
_0x2e77ae.prototype.aMpklD = function (_0xe722ea) {
let _0x149a72 = 0;
for (let _0x3fe735 = this.fyrkaT.length; _0x149a72 < _0x3fe735; _0x149a72++) {
this.fyrkaT.push(Math.round(Math.random()));
_0x3fe735 = this.fyrkaT.length;
}
return _0xe722ea(this.fyrkaT[0]);
};
new _0x2e77ae(a0_0xa0b8).sxNFHR();
a0_0xa0b8.OJUoMm = true;
}
_0x530d4e = a0_0xa0b8.WEMegZ(_0x530d4e, _0x1eeda0);
_0x6db2f9[_0x491855] = _0x530d4e;
} else {
_0x530d4e = _0x125d04;
}
return _0x530d4e;
};
return a0_0xa0b8(_0x6db2f9, _0x437aca);
}
// Removed some actual payload
// This is just used for a checksum to cause infinite loops on tampering
function a0_0x5173() {
const _0x1b091d = ['WPL9tgvD', 'rSkQESkIxq', 'W6ZcP8oaEhO', 'W6mYb2bA', 'dHDnimo6', 'xmouaaldSa', 'umk2ASk+Aa', 'su4YWOxcGq', 'tHddKCkblW', 'W6JcI8oXD3O', 'oejaWPXe', 'ccnenei', 'W5ZdH8o7W4i6', 'W53cMhBcLSkQ', 'uKODWPxcKa', 'acj7oCo5', 'W4PQmfyT', 'wmk7W67dMmo9', 'W4xcG8oBpI8', 'dCk6xmoBwa', 'W7JdRYGgbW', 'W5XIAwOF', 'WQpcTxiIDq', 'qNJcRMhcOa', 'W4NcU8oiW5rK', 'W4/dK8oXW4G9', 'W6NdSCkMW4Se', 'W5eZdSk6va', 'W4JdK8oFxau', 'WOhdN13dNI8', 'iSk9x8oJmb3dGSk5r8oTs8oLpG', 'oMmxjcVdKHHa', 'W6NcHCkta8oO', 'WQmmgXldUW', 'W6SSe2LB', 'nCkBbfrA', 'sImjdIy', 'WQtdJmkmomkr', 'mNRcIConFa', 'W6iiba', 'W7hdIbCbhq', 'BmoAkZPG', 'W5tdJ8oCW6Wr', 'vK7dLKlcMW', 'WOpdO8opWPWI', 'vZisW78', 'W6pcOmogCxK', 'DSoLedZdHa', 'ruGQ', 'WRJdN8oMWRL+', 'AZqthZe', 'W7qMW6b/W6NcTLHAW7ysW6y', 'WQpcVmkLWOb6', 'WPZcUfiFvq', 'gCkxBCoYDG', 'p8oqWOtcG8kW', 'EmoHArLS', 'e03cVf5E', 'WO3cPemhsG', 'ACoCcMyc', 'W7K5aNDb', 'ytuA', 'itjWd8of', 'tmoFBqvd', 'W7ddSmoOBGe', 'xSkSxG', 'ut7dLCkfkG', 'x8k/wSopxG', 'jvT/dmoZ', 'CSoHCtnH', 'bsxdIIddPHJcGmkDmCkeDW', 'W6/cG8ksgmoU', 'ae7cQSofFW', 'zmk0W73dOhC', 'bCkqy8oXCG', 'tCkoW4pcH8ke', 'WR7dI0ldTYW', 'ax7cT8ooxG', 'W5dcMCowsfK', 'W7WPkwzd', 'W5rPaeaU', 'W6m6mHuI', 'CdhdO8ktdW', 'W67dLmoGW4mP', 'WPpdKSkyWQSS', 'W4JdJHWEfq', 'tbNdLSkqoW', 'nLnQn8or', 'W6ddTmoLW4S0', 'W7/dUSoJW7af', 'W6uUdG', 'ruS7WOJcSa', 'u8o9WQvnuq', 'vYGpqYm', 'WQXix2nM', 'f8oAWRhcRSkI', 'FCo8WRddJSoj', 'CZmLCHi', 'a0nynCo7', 'uCo2WQu', 'rHuqWP5qkCkwWPiZ', 'W6tdKmo7W64n', 'cLH3WRL1', 'cIjHoa', 'W5JdISoXW7Cp', 'W6ldMrKCha', 'W63dHCoFsWm', 'dhflu8k6', 'WRVcVv0pxa', 'WRjVWQqQ', 'W4DAumksfG', 'r8oCtXldSG', 'u1q9', 'xmkRCG', 'ahhcOCoa', 'uGRdVSkqiG', 'B8oAeNKc', 'W4nOASkJma', 'f8oqWQddPCk5', 'vmobka', 'W7tcRCop', 'rCkJsmkcrG', 'FHK0gYm', 'WRj5WOC7WQi', 'W7u+aCksva', 'W6z0Frq2', 'vaiWFXi', 'D08WW5xdTG', 'WQumeXJdOG', 'WQBcUCkVWQLe', 'FSoSWPxdJCoo', 'omkSw8onvW', 'WPpdPmofWOy', 'WOqJvsf5', 'AaO6uX4', 'kxfXmSor', 'WOhdVmkyWOSK', 'W6GqbCkrBG', 'baqenSoJ', 'nrrHlMO', 'W4VcPmojwMe', 'WOddN0RdMrO', 'WOFdNSkaWPiO', 'CCo9W5ZdJSoq', 'W6tdImoIW4KF', 'khnBs8oH', 'W6yFlSkrtq', 'tCoXdh40', 'WPVdQmkWfSky', 'mxTmWQbl', 'uZGfW7hdMq', 'l8kXzCotDa', 'vb3dHSkuoG', 'ytqt', 'W6m9lvve', 'zSoUWOBdNa', 'CYqorrm', 'DIWtW6ldHW', 'kmkCdW', 'WRe4WRmGWR8', 'suG6WOpcVa', 'W5FcLCoiht0', 'd8kmiCo9Fa', 'WO/cU15eqq', 'W6zMESk+', 'saqVzHC', 'rCk6W7RdNSoO', 'W6JcOK7cP8kc', 'WPTZyhjK', 'sSkdW6hdLNy', 'yCk+W5BcMSkm', 'wmoPf8kOyW', 'WPC4DHDT', 'DHekW4RdLa', 'amoPaCkoeXhdRCo9WPBcLSouW6CL', 'abvDj8o+', 'WOVdKx4', 'qmodcCk2tq', 'WQRdKSoUWPn9', 'jfDJa8ot', 'qmoydSkPEG', 'D8kYFSoptG', 'smo5WONdSCoY', 'FCoLomk6xa', 'jCk5W5hcKmojWQtcIXxdG34', 'W7/dSSocAIK', 'W6uDjCkuFG', 'qCkYuSocta', 'vqBdUmknkG', 'WQeCtGfQ', 'W4PFcgGC', 'WOVcKgaUEa', 'WQT6W7SSWRG', 'WRZdLCoMWR4', 'FSk4Fmkata', 'W5T5FZaa', 'suaAWOtcGa', 'W5JdRaCaqCkOWPhdSCoZ', 'sYtdOSkhaq', 'WQ7dGSoYWQSK', 'W6OCl8kAqq', 't8knW7xdQmo3', 'BCk4W6ldOCoi', 'DmkBFCoDza', 'n8kye0rp', 'pmoJWPa', 'WQztshXZ', 'WOddM1hdQWS', 'iejRWPPY', 'ihLLWR9e', 'BCojWOzkwa', 'bXne', 'i03cGhD4', 'gWjBpSo9', 'WO/dVCooWPC5', 'WPVcL3e5ya', 'WRLlAKzn', 'mSkyAmoCsG', 'WPJdKNldUI8', 'WQZcTmkhph4vimkvWRddTgpcV8k4mq', 'WRy1CrnW', 'W7qPnbC4', 'W7GGpW', 'W43dJmoHsJa', 'W5PdAvTc', 'WQayAbDZ', 'W53cJYtcUhGbuCkFW6LwW6y', 'zZzsbde', 'W4tdU8oIW6CI', 'WRldNSoSWQ9Y', 'DmkAe19s', 'bcBdJsldOx7dVCk7lCkezLDh', 'WO5YuvPd', 'WRWBBGji', 'W6/dRmoNW4mc', 'W6ficMGk', 'oM1ix3ZcJLO+WPC6W67dLsFcKa', 'WR3dUSoNWQjT', 'BGmQbJu', 'xCoKp38z', 'W71GtZ0d', 'lSkcW4hdHCot', 'yCoUjSknBW', 'hgtcOCos', 'f3lcKSoTBq', 'WQtcKmk1WRbi', 'W7Prz8k7oq', 'WQtcJSku', 'qSkyW6/dP1a', 'rceNW6ddSa', 'wSolDqTX', 'zSk4WRtdOxy', 'DmoKamkWyq', 'W7ZcJuFcUSki', 'c8koF8oYAG', 'D8kyW5FcN8oy', 'FSoTDJn2', 'bYrRp3K', 'W6/dUCoBW4Ou', 'sIK7', 'b8kNrCopAW', 'Emo/eHhdUa', 'qXOwW40BE8onWReBrZ3dR8kz', 'WO7dGSoRWQbO', 'tI8BW6JdTa', 'W7W5W7SKWQu', 'W6q4adeJ', 'WRGkvq5+', 'rCoqfXhdOa', 'CSo9Ca', 'BtRdH8kHoa', 'WR9aA2zs', 't8koW6hdUmo6', 'rSoFbrxdQW', 'W5bvegC8', 'sHpdO8kboW', 'WRjft0Dc', 'rSk6zmoXxa', 'y8oKhmkZ', 'WOxcULCosW', 'gt/dLd3dVG', 'DCkqB8k2Bq', 'q2BdIfBcKG', 'FXG/pHy', 'W6FdM8o9FXC', 'bhRcPCoaFG', 'WQxcKmo4WR5o', 'WQFdHmkxEwi', 'WQhcKCkX', 'W601bIHd', 'dsrfmSoG', 'W4ZdTCo8rXe', 'sMm4WRlcHq', 'vCoTWQrABW', 'aq9nmSo1', 'WRFdUCkpWPSI', 'vYqXW67dHW', 'W67dPCofW58+', 'WRSeAqzU', 'WR0rDa9P', 'vxdcLgtcSG', 'p21npXhdRaT+WRu', 'rvldQ3BcTW', 'W7uGmHqG', 'sMldJepcJW', 'bKHi', 'vCoOWQfKra', 'WOtcOeCBqa', 'vNpdGeFdKW', 'W48giNXw', 'u8oWf2CM', 'CLeqWQ7cKG', 'vSk7r8o+rq', 'W6NcRmovycG', 'qc85xYy', 'WPtdQ8kKfmkf', 'FSobkMSw', 'cW5e', 'WRaFCH10', 'WRNdOmkPWPW8', 'B33cMq', 'umoxWRRcPG', 'W4iDdMTn', 'W6jJsXyi', 't1qZ', 'W7TynvG2', 'WQVdNmoPWR5S', 'umotWRRcPmk9', 'W4GykKfy', 'W5NdVYmWoW', 'W6PkyCkJmG', 'khRdRx9+', 'W5fOb0qI', 'W6FcRCoxxgi', 'cYLKowa', 'z8kRxSkGEq', 'WPTwAW', 'xSoqlMOZ', 'WPldSCkpWPSI', 'v8o3WR5Jva', 'W6BcJ8k6WRbj', 'x2BcKa', 'WQhcKCkYWRre', 'tSoefcldGq', 'WOeKxdX7', 'W5LIdKG0', 'lbbnleO', 'h8o6WPRcJCkd', 'WO7dTmkacmka', 'AZWpnaG', 'jgpdVhPJ', 'WOtdSCkXbCkH', 'W4j7EIeE', 'lSkZfNvj', 'tYiOvJy', 'D2ddV3FcVG', 'WPNdO8o4WPPZ', 'b3pcPCogEW', 'W4XNrcK8', 'vaiRW5NdNq', 'jh1nc8o2', 'W7eMW6z3WRVcU3fwW6eM', 'o8oLWR3cSYyIfCoRggpdTW', 'W6qAgN1A', 'nHjUeNm', 'W6HLzSkLla', 'b2r/pCoT', 'W6VdH8oBW60G', 'dsO9pNe', 'W5xdJ8ouAWG', 'jWnrjmoM', 'As4ipHC', 'w8k8FSk0', 'wCobjrZdTW', 'umkiW7BdU8oS', 'WPfUWQmLWPe', 'W6iFmwTw', 'saBdP8kNeW', 'W7Pve3eJ', 'W6tdTbqzfa', 'W4xdQmogW5qz', 'WRz0WRmOWQy', 'ymoQWPb4wa', 'hCoBWRJdPmkO', 'nxvqeCkT', 'WRWofGNdVa', 'lMjf', 'WOXJxKjD', 'cXnmnSo5', 'FSohfIRdHa', 'r8odbby', 'WOf8vezT', 'wCkSvSoq', 'dCkxASkZCG', 'ehpcT8oFuq', 'W7dcPmocBwG', 'BCkdWO/dKSou', 'xNNcMh3cSa', 'WPVdVgRdMIG', 'suKW', 'o2lcS21Q', 'W40Lj8kTtG', 'WQJdMmo9W6rP', 'WQhcTvaIxq', 'FsKhdwS', 'WPeJBszK', 'W6LnwSkpfq', 'cv3cOKL1', 'zCk6W6RdOMS', 'jSk7W5pcNmkuW7JdIYddNhn4xcK', 'nwvZWObu', 'cCk/cNfz', 'W6ddTCoV', 'ymk6W6C', 'W5ekbmk1uW', 'ECo5WRjHuW', 'WRZcP8k4WQbB', 'CCo7WORdMmow', 'udu/', 'F8obm0Gd', 'WOldOSkKWQC7', 'gCkGohvU', 'W6DVtCkOgG', 'DSoyWPxdOSoe', 'EZGpbtu', 'WQr5yvL1ksf0W63cRalcUKa', 'oCklffvC', 'Amobf21ghNCp', 'udOvlW4', 'owrEvmkS', 'W5hdVmoMW6Wv', 'W4lcP0CkrW', 'wJujgqS', 'o8kmchD6', 'W6VcQCk0lmos', 'W4tcHCoEiZW', 'BmktW4ddH2W', 'W7FcJCohkSkE', 'z8o0bWhdOa', 'WRRdP8kmCNS', 'W7VdPmoxEti', 'uwuDWQRcLq', 'W6ddRSoQW506', 'WRzbWRCdWRW', 'DCotfSkzqa', 'W6SalSkz', 'm17cK8obBG', 'CsKOqH8', 'A8kyB8kazG', 'WP1hDrPg', 'g0naWPbA', 'WQmxaXJdQa', 'rmolpSkWFW', 'W6ZcNSoAnJ0', 'rhVcJN4', 'WPddVmkaWOSR', 'W7NdSCo7', 'ACkbW4tdLmoe', 'W7hdSmoF', 'yrqSzYG', 'WRRdP8kmBNK', 'W6NcPSoe'];
a0_0x5173 = function () {
return _0x1b091d;
};
return a0_0x5173();
}
I unfortunately don't actually know how to detect it, since it might take different shapes, but it would be a very useful feature. The main thing to check for that I can think of would be any variable that contains a function which is later used with either fun_name.toString()
or something + fun_name
, which are the two ways of converting a function to a string that are used in the snippet above. the next question is what to do about it, since it's more difficult to know how many layers of functions are just tamper-proofing where the actual code starts.
Clicking the "self defending" button on obfuscator.io gives somewhat similar but slightly simpler code.