Feature Request - Self Defending with String Array
See original GitHub issueHello!
I was fiddling around with code that I obfuscated with this tool, trying to figure out a way to manipulate things. I discovered, that I could easily edit the string array/map in obfuscated code with selfdefend
and stringarray
on. I was wondering if there was any security to prevent such editing.
For example, in the example (with hello world), I could make it print something else by modifying the string array in the beginning
// Hello world!
var a=['AdvLv','Hello\x20World!'];(function(c,d){var e=function(f){while(--f){c['push'](c['shift']());}};var g=function(){var h={'data':{'key':'cookie','value':'timeout'},'setCookie':function(i,j,k,l){l=l||{};var m=j+'='+k;var n=0x0;for(var n=0x0,p=i['length'];n<p;n++){var q=i[n];m+=';\x20'+q;var r=i[q];i['push'](r);p=i['length'];if(r!==!![]){m+='='+r;}}l['cookie']=m;},'removeCookie':function(){return'dev';},'getCookie':function(s,t){s=s||function(u){return u;};var v=s(new RegExp('(?:^|;\x20)'+t['replace'](/([.$?*|{}()[]\/+^])/g,'$1')+'=([^;]*)'));var w=function(x,y){x(++y);};w(e,d);return v?decodeURIComponent(v[0x1]):undefined;}};var z=function(){var A=new RegExp('\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*[\x27|\x22].+[\x27|\x22];?\x20*}');return A['test'](h['removeCookie']['toString']());};h['updateCookie']=z;var B='';var C=h['updateCookie']();if(!C){h['setCookie'](['*'],'counter',0x1);}else if(C){B=h['getCookie'](null,'counter');}else{h['removeCookie']();}};g();}(a,0x1cf));var b=function(c,d){c=c-0x0;var e=a[c];return e;};function hi(){var c=function(){var c=!![];return function(d,e){var f=c?function(){if(e){var g=e['apply'](d,arguments);e=null;return g;}}:function(){};c=![];return f;};}();var e=c(this,function(){var c=function(){return'\x64\x65\x76';},d=function(){return'\x77\x69\x6e\x64\x6f\x77';};var e=function(){var f=new RegExp('\x5c\x77\x2b\x20\x2a\x5c\x28\x5c\x29\x20\x2a\x7b\x5c\x77\x2b\x20\x2a\x5b\x27\x7c\x22\x5d\x2e\x2b\x5b\x27\x7c\x22\x5d\x3b\x3f\x20\x2a\x7d');return!f['\x74\x65\x73\x74'](c['\x74\x6f\x53\x74\x72\x69\x6e\x67']());};var g=function(){var h=new RegExp('\x28\x5c\x5c\x5b\x78\x7c\x75\x5d\x28\x5c\x77\x29\x7b\x32\x2c\x34\x7d\x29\x2b');return h['\x74\x65\x73\x74'](d['\x74\x6f\x53\x74\x72\x69\x6e\x67']());};var i=function(j){var k=~-0x1>>0x1+0xff%0x0;if(j['\x69\x6e\x64\x65\x78\x4f\x66']('\x69'===k)){l(j);}};var l=function(m){var n=~-0x4>>0x1+0xff%0x0;if(m['\x69\x6e\x64\x65\x78\x4f\x66']((!![]+'')[0x3])!==n){i(m);}};if(!e()){if(!g()){i('\x69\x6e\x64\u0435\x78\x4f\x66');}else{i('\x69\x6e\x64\x65\x78\x4f\x66');}}else{i('\x69\x6e\x64\u0435\x78\x4f\x66');}});e();var d={'AdvLv':b('0x0')};console['log'](d[b('0x1')]);}hi();
// Bye world! (modified)
var a=['AdvLv','Bye\x20World!'];(function(c,d){var e=function(f){while(--f){c['push'](c['shift']());}};var g=function(){var h={'data':{'key':'cookie','value':'timeout'},'setCookie':function(i,j,k,l){l=l||{};var m=j+'='+k;var n=0x0;for(var n=0x0,p=i['length'];n<p;n++){var q=i[n];m+=';\x20'+q;var r=i[q];i['push'](r);p=i['length'];if(r!==!![]){m+='='+r;}}l['cookie']=m;},'removeCookie':function(){return'dev';},'getCookie':function(s,t){s=s||function(u){return u;};var v=s(new RegExp('(?:^|;\x20)'+t['replace'](/([.$?*|{}()[]\/+^])/g,'$1')+'=([^;]*)'));var w=function(x,y){x(++y);};w(e,d);return v?decodeURIComponent(v[0x1]):undefined;}};var z=function(){var A=new RegExp('\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*[\x27|\x22].+[\x27|\x22];?\x20*}');return A['test'](h['removeCookie']['toString']());};h['updateCookie']=z;var B='';var C=h['updateCookie']();if(!C){h['setCookie'](['*'],'counter',0x1);}else if(C){B=h['getCookie'](null,'counter');}else{h['removeCookie']();}};g();}(a,0x1cf));var b=function(c,d){c=c-0x0;var e=a[c];return e;};function hi(){var c=function(){var c=!![];return function(d,e){var f=c?function(){if(e){var g=e['apply'](d,arguments);e=null;return g;}}:function(){};c=![];return f;};}();var e=c(this,function(){var c=function(){return'\x64\x65\x76';},d=function(){return'\x77\x69\x6e\x64\x6f\x77';};var e=function(){var f=new RegExp('\x5c\x77\x2b\x20\x2a\x5c\x28\x5c\x29\x20\x2a\x7b\x5c\x77\x2b\x20\x2a\x5b\x27\x7c\x22\x5d\x2e\x2b\x5b\x27\x7c\x22\x5d\x3b\x3f\x20\x2a\x7d');return!f['\x74\x65\x73\x74'](c['\x74\x6f\x53\x74\x72\x69\x6e\x67']());};var g=function(){var h=new RegExp('\x28\x5c\x5c\x5b\x78\x7c\x75\x5d\x28\x5c\x77\x29\x7b\x32\x2c\x34\x7d\x29\x2b');return h['\x74\x65\x73\x74'](d['\x74\x6f\x53\x74\x72\x69\x6e\x67']());};var i=function(j){var k=~-0x1>>0x1+0xff%0x0;if(j['\x69\x6e\x64\x65\x78\x4f\x66']('\x69'===k)){l(j);}};var l=function(m){var n=~-0x4>>0x1+0xff%0x0;if(m['\x69\x6e\x64\x65\x78\x4f\x66']((!![]+'')[0x3])!==n){i(m);}};if(!e()){if(!g()){i('\x69\x6e\x64\u0435\x78\x4f\x66');}else{i('\x69\x6e\x64\x65\x78\x4f\x66');}}else{i('\x69\x6e\x64\u0435\x78\x4f\x66');}});e();var d={'AdvLv':b('0x0')};console['log'](d[b('0x1')]);}hi();
If there is no security for that, I suggest hashing the string array (after joining it all with .join), and comparing it to a stored value.
var a=['AdvLv','Hello\x20World!'];
var toHash=a.join(','); // Make sure to join with a character in between for more security
var hash = 0;
for (var i = 0; i < toHash.length; i++) { // Hash function from here: https://stackoverflow.com/questions/6122571/simple-non-secure-hash-function-for-javascript
var c = toHash.charCodeAt(i);
hash = ((hash<<5)-hash)+c;
hash = hash & hash; // Convert to 32bit integer
}
if (hash !== -222186004) detectedModification(); // -222186004 is the precomputed hash
(For super long arrays where hashing is too slow, .length
comparisons could be also done for faster yet less secure checking)
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:6 (2 by maintainers)
Top Results From Across the Web
String array in response body of custom connector
I have a custom connector with a request having a JSON structure in the body with multiple elements (JIRA issues).
Read more >Why is my Java function in my Karate feature returning a ...
1 Answer 1 · When I read the part you wrote "string arrays are not being converted to JSON arrays properly", I realized...
Read more >Work with arrays | BigQuery
With Google Standard SQL, you can construct array literals, build arrays from subqueries using the ARRAY function, and aggregate values into an array...
Read more >JavaScript Obfuscator Tool
The obfuscated result will have the exact functionality of the original code. ... transformations and "traps", such as self-defending and debug protection.
Read more >String resources
String : XML resource that provides a single string. String Array: XML resource that provides an array of strings. Quantity Strings (Plurals) ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@sanex3339 I have achieved the above in my fork. Heres the link to check it out:
https://github.com/Andrews54757/javascript-obfuscator
Code output:
As you can see (if you beautify the code), you will NOT find rotation value (or hash) anywhere in the code. That is because it is calculated by the hash and validated by the syntax of the functional code. That way:
How it works:
Basically, if the string array rotate and self defend options are both checked, then the obfuscator will use the hash function output to calculate the rotate value. This is achieved like this:
The bitwise operators are there for two reasons:
Todo
@sanex3339 I thought about something cool. How about, when the hash is calculated, instead of just comparing it to a pre-generated hash, the hash is used to calculate the rotation of the array. It would provide lots of security to not just the string array hash function, but also the rotate function.
That way, one cannot figure out the rotation by looking at a number. Instead, they must run the hash function (which could be self-defended itself to prevent this).
Example of code that could do this: