diff --git a/README.md b/README.md index 832af26..b169be3 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,11 @@ Usage scan.php -d [-i=] [-e=.php] [--hide-ok] [--hid Ignore argument could be used multiple times and accept glob style matching ex.: "cache*", "??-cache.php" or "/cache" etc. +Patterns +-------- + +There are two different pattern source, each line in these files is a patter so patterns_raw.txt lines searched as-is, patterns_re.txt used with preg_match function. + Whitelisting ------------ diff --git a/patterns_raw.txt b/patterns_raw.txt new file mode 100644 index 0000000..1e2739f --- /dev/null +++ b/patterns_raw.txt @@ -0,0 +1,152 @@ +uname -a +/etc/shadow +/etc/passwd +WSOstripslashes +PD9waHA +c3lzdGVt +\x73\x79\x73\x74\x65\x6d' /* case, dec/hex issue? */, // system +cHJlZ19yZXBsYWNl +\x70\x72\x65\x67\x5f\x72\x65\x70\x6c\x61\x63\x65' /* case, dec/hex issue? */, // preg_replace +ZXhlYyg +\x65\x78\x65\x63' /* dec/hex issue? */, // exec +='base'.(32*2).'_de'.'code' +"base64_decode" +YmFzZTY0X2RlY29kZ +"p"."r"."e"."g"."_" +eval("?> +ev\x61l +\x65\166\x61\154\x28' /* dec/hex issue? */, +\x65\x76\x61\x6C' /* case, dec/hex issue? */, +ZXZhbCg +'ev'.'al'.' +eval(base64_decode( +\x47\x4c\x4f\x42\x41LS +SFRUUF9VU0VSX0FHRU5U +YWxsb3dfdXJsX2ZvcGVu +${${ +file_get_contents('http://codepad.org +PHPJiaMi +@include($_GET[ +system($_GET[ +md5($_GET[ +ShellBOT +bgeteam +DisablePHP= +moban.html +IrIsT +Hacked By EnDLeSs +Punker2Bot +Zed0x +darkminz +ReaL_PuNiShEr +OoN_Boy +__VIEWSTATEENCRYPTED +M4ll3r +createFilesForInputOutput +Pashkela +== "bindshell" +Webcommander at +YENI3ERI +d3lete +Made by Delorean +R0lGODlhEwAQALMAAAAAAP///5ycAM7OY///nP//zv/OnPf39////wAAAAAA +Cybester90 +ayu pr1 pr2 pr3 pr4 pr5 pr6 +f0VMRgEBAQA +0d0a0d0a676c6f62616c20246d795f736d7 +etalfnizg +JHZpc2l0Y291bnQgPSAkSFRUUF9DT09LSUVfV +edoced_46esab +VOBRA GANGO +itsoknoproblembro +HTTP flood complete after +exploitcookie +az88pix00q98 +The Dark Raver +Q3JlZGl0IDogVW5kZXJncm91bmQgRGV2aWwgJm5ic3A7ICB8DQo8YSBocmVmP +463839610c000b00800100ffffffffffff21f90401000001002c000 +AAAAAAAAMAAwABAAAAeAUAADQAAADsCQAAAAAAADQAIAADACgAFwAUAAEA +HJ3HjutckoRfpXf9A1zQO2AwDRrRey9uGvTeez79qAao1a0rgudkZkR8Ra +Ly83MTg3OWQyMTJkYzhjYmY0ZDRmZDA0NGEzZDE3Zjk3ZmI2N +DJ7VIU7RICXr6sEEV2cBtHDSOe9nVdpEGhEmvRVRNURfw1wQ +Asmodeus +Cautam fisierele de configurare +BRUTEFORCING +FaTaLisTiCz_Fx Fx29Sh +w4ck1ng shell +private Shell by m4rco +Shell by Mawar_Hitam +LS0gRHVtcDNkIGJ5IFBpcnVsaW4uUEhQIFdlYnNoM2xsIHYxLjAgYzBkZWQgYnkgcjBkcjEgOkw\= +5jb20iKW9yIHN0cmlzdHIoJHJlZmVyZXIsImFwb3J0Iikgb3Igc3RyaXN0cigkcmVmZXJlciwibmlnbWEiKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJ3ZWJhbHRhIikgb3Igc3RyaXN0cigk +X1NFU1NJT05bJ3R4dGF1dGhpbiddID0gdHJ1ZTsNCiAgICBpZiAoJF9QT1NUWydybSddKSB7DQogICAgICBzZXRjb29raWUoJ3R4dGF1dGhfJy4kcm1ncm91cCwgbW +zehirhacker +R0lGODlhFAAUAKIAAAAAAP///93d3cDAwIaGhgQEBP///wAAACH5BAEAAAYALAAAAAAUABQAA +m91dCwgJGVvdXQpOw0Kc2VsZWN0KCRyb3V0ID0gJHJpbiwgdW5kZWYsICRlb3V0ID0gJHJpbiwgMTIwKTsNCmlmICghJHJvdXQgICYmICAhJGVvdX +CB2aTZpIDEwMjQtDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KI3JlcXVp +DX_Header_drawn +BDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAQABADASIAAhEBA +casus15 +temp_r57_table +By Psych0 +c99ftpbrutecheck +K!LL3r +MrHazem +BY MMNBOBZ +ConnectBackShell +Hackeado +d3b~X +REREFER_PTTH +Joomla_brute_Force +/usr/sbin/httpd +tmhapbzcerff +IrSecTeam +Spammer +FLoodeR +eriuqer +sshkeys + +Backdoor +eggdrop +rwxrwxrwx +profexor.hell +GIF89A; /tmp/ +ncftpput -u +wsoEx( +WSOsetcookie( +Dr.abolalh +C0derz.com +Mr.HiTman diff --git a/patterns_re.txt b/patterns_re.txt new file mode 100644 index 0000000..e033050 --- /dev/null +++ b/patterns_re.txt @@ -0,0 +1,17 @@ +eval\/\*[a-z0-9]+\*\/ +eval\([a-z0-9]{4,}\(\$[a-z0-9]{4,}, \$[0-9a-z]{4,}\)\); +(chr\(\d+\)\.){4,} +(chr\(\d+\^\d+\)\.){4,} +(\$[a-z0-9]{3,}\[\d+\]\.){4,} +chr\(\d+\)\.""\.""\.""\.""\."" +\$GLOBALS\[\$GLOBALS['[a-z0-9]{4,}'\]\[\d+\]\.\$GLOBALS\['[a-z-0-9]{4,}'\]\[\d+\]. +\$GLOBALS\['[a-z0-9]{5,}'\] = \$[a-z]+\d+\[\d+\]\.\$[a-z]+\d+\[\d+\]\.\$[a-z]+\d+\[\d+\]\.\$[a-z]+\d+\[\d+\]\. +eval\([a-z0-9_]+\(base64_decode\( +\$[a-z]{3,}=\$[a-z]{3,}\("",\$[a-z]{3,}\);\$[a-z]{3,}\(\); +{\s*eval\s*\(\s*\$ +Googlebot['"]{0,1}\s*\)\){echo\s+file_get_contents +eVaL\(\s*trim\(\s*baSe64_deCoDe\( +if\s*\(\s*mail\s*\(\s*\$mails\[\$i\]\s*,\s*\$tema\s*,\s*base64_encode\s*\(\s*\$text +fwrite\s*\(\s*\$fh\s*,\s*stripslashes\s*\(\s*@*\$_(GET|POST|SERVER|COOKIE|REQUEST)\[ +echo\s+file_get_contents\s*\(\s*base64_url_decode\s*\(\s*@*\$_(GET|POST|SERVER|COOKIE|REQUEST) +chr\s*\(\s*101\s*\)\s*\.\s*chr\s*\(\s*118\s*\)\s*\.\s*chr\s*\(\s*97\s*\)\s*\.\s*chr\s*\(\s*108\s*\) diff --git a/scan.php b/scan.php index 45be34a..a0cad20 100644 --- a/scan.php +++ b/scan.php @@ -144,176 +144,25 @@ class MalwareScanner echo 'Total malware identified: ' . $this->stat['files_infected'] . PHP_EOL; } + private function loadPatterns($file) + { + $list = array(); + if (is_readable($file)) { + foreach (file($file) as $pattern) { + $list[] = trim($pattern); + } + } + return $list; + } + private function scan($path) { $this->stat['files_scanned']++; $fileContent = file_get_contents($path); $found = false; - // check against simple text matches - $patterns = array( - 'uname -a', - '/etc/shadow', - '/etc/passwd', - 'WSOstripslashes', - 'PD9waHA', // ', - 'ev\x61l', - '\x65\166\x61\154\x28' /* dec/hex issue? */, - '\x65\x76\x61\x6C' /* case, dec/hex issue? */, - 'ZXZhbCg', // eval - "'ev'.'al'.'", - '/eval\s*\(/i', - - 'eval(base64_decode(', - '\x47\x4c\x4f\x42\x41LS', // GLOBALS - 'SFRUUF9VU0VSX0FHRU5U', // HTTP_USER_AGENT - 'YWxsb3dfdXJsX2ZvcGVu', // allow_url_fopen - '${${', // ${${"\x47\x4c\x4f\x42... - 'file_get_contents(\'http://codepad.org', - 'PHPJiaMi', - '@include($_GET[', - 'system($_GET[', - - /* too open? */ - // 'gzinflate(base64_decode(', - 'md5($_GET[', // md5($_GET["ms-load"]) - 'ShellBOT', - 'bgeteam', - 'DisablePHP=', - 'moban.html', - 'IrIsT', - 'Hacked By EnDLeSs', - 'Punker2Bot', - 'Zed0x', - 'darkminz', - 'ReaL_PuNiShEr', - 'OoN_Boy', - '__VIEWSTATEENCRYPTED', - 'M4ll3r', - 'createFilesForInputOutput', - 'Pashkela', - '== "bindshell"', - 'Webcommander at', - 'YENI3ERI', - 'd3lete', - 'Made by Delorean', - 'R0lGODlhEwAQALMAAAAAAP///5ycAM7OY///nP//zv/OnPf39////wAAAAAA', - 'Cybester90', - 'ayu pr1 pr2 pr3 pr4 pr5 pr6', - 'f0VMRgEBAQA', - '0d0a0d0a676c6f62616c20246d795f736d7', - 'etalfnizg', - 'JHZpc2l0Y291bnQgPSAkSFRUUF9DT09LSUVfV', - 'edoced_46esab', - 'VOBRA GANGO', - 'itsoknoproblembro', - 'HTTP flood complete after', - 'exploitcookie', - 'az88pix00q98', - 'The Dark Raver', - 'Q3JlZGl0IDogVW5kZXJncm91bmQgRGV2aWwgJm5ic3A7ICB8DQo8YSBocmVmP', - '463839610c000b00800100ffffffffffff21f90401000001002c000', - 'AAAAAAAAMAAwABAAAAeAUAADQAAADsCQAAAAAAADQAIAADACgAFwAUAAEA', - 'HJ3HjutckoRfpXf9A1zQO2AwDRrRey9uGvTeez79qAao1a0rgudkZkR8Ra', - 'Ly83MTg3OWQyMTJkYzhjYmY0ZDRmZDA0NGEzZDE3Zjk3ZmI2N', - 'DJ7VIU7RICXr6sEEV2cBtHDSOe9nVdpEGhEmvRVRNURfw1wQ', - 'Asmodeus', - 'Cautam fisierele de configurare', - 'BRUTEFORCING', - 'FaTaLisTiCz_Fx Fx29Sh', - 'w4ck1ng shell', - 'private Shell by m4rco', - 'Shell by Mawar_Hitam', - 'LS0gRHVtcDNkIGJ5IFBpcnVsaW4uUEhQIFdlYnNoM2xsIHYxLjAgYzBkZWQgYnkgcjBkcjEgOkw\=', - '5jb20iKW9yIHN0cmlzdHIoJHJlZmVyZXIsImFwb3J0Iikgb3Igc3RyaXN0cigkcmVmZXJlciwibmlnbWEiKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJ3ZWJhbHRhIikgb3Igc3RyaXN0cigk', - 'X1NFU1NJT05bJ3R4dGF1dGhpbiddID0gdHJ1ZTsNCiAgICBpZiAoJF9QT1NUWydybSddKSB7DQogICAgICBzZXRjb29raWUoJ3R4dGF1dGhfJy4kcm1ncm91cCwgbW', - 'zehirhacker', - 'R0lGODlhFAAUAKIAAAAAAP///93d3cDAwIaGhgQEBP///wAAACH5BAEAAAYALAAAAAAUABQAA', - 'm91dCwgJGVvdXQpOw0Kc2VsZWN0KCRyb3V0ID0gJHJpbiwgdW5kZWYsICRlb3V0ID0gJHJpbiwgMTIwKTsNCmlmICghJHJvdXQgICYmICAhJGVvdX', - 'CB2aTZpIDEwMjQtDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KI3JlcXVp', - 'DX_Header_drawn', - 'BDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAQABADASIAAhEBA', - 'casus15', - 'temp_r57_table', - 'By Psych0', - 'c99ftpbrutecheck', - 'K!LL3r', - 'MrHazem', - 'BY MMNBOBZ', - 'ConnectBackShell', - 'Hackeado', - 'd3b~X', - 'REREFER_PTTH', - 'Joomla_brute_Force', - '/usr/sbin/httpd', - 'tmhapbzcerff', - 'IrSecTeam', - 'Spammer', - 'FLoodeR', - 'eriuqer', - 'sshkeys', - '', - 'Backdoor', - 'eggdrop', - 'rwxrwxrwx', - 'profexor.hell', - 'GIF89A; /tmp/', - 'ncftpput -u ', - 'wsoEx(', - 'WSOsetcookie(', - 'Dr.abolalh', - 'C0derz.com', - 'Mr.HiTman', - ); + $toSearch = ''; + $patterns = $this->loadPatterns(dirname(__FILE__) . '/patterns_raw.txt'); if ($this->extraCheck) { array_push($patterns, "googleBot", "htaccess"); } @@ -325,40 +174,8 @@ class MalwareScanner } } - // check against regexp patterns if (!$found) { - $patterns = array( - 'eval\/\*[a-z0-9]+\*\/', - // eval/*aw3*/ - 'eval\([a-z0-9]{4,}\(\$[a-z0-9]{4,}, \$[0-9a-z]{4,}\)\);', - // eval(v5JONDD($v5EKGVD, $vX3Z3DE)); - '(chr\(\d+\)\.){4,}', - // chr(22).chr(33).chr(22).chr(22) - '(chr\(\d+\^\d+\)\.){4,}', - // chr(95^57).chr(95^54).chr(95^51).chr(95^58) - '(\$[a-z0-9]{3,}\[\d+\]\.){4,}', - // $saz98[5].$saz98[2].$saz98[1].$saz98[3].$saz98[5] - 'chr\(\d+\)\.""\.""\.""\.""\.""', - // chr(88)."".""."".""."". - '\$GLOBALS\[\$GLOBALS[\'[a-z0-9]{4,}\'\]\[\d+\]\.\$GLOBALS\[\'[a-z-0-9]{4,}\'\]\[\d+\].', - // $GLOBALS[$GLOBALS['u101c7'][77].$GLOBALS['u101c7'][47]. - '\$GLOBALS\[\'[a-z0-9]{5,}\'\] = \$[a-z]+\d+\[\d+\]\.\$[a-z]+\d+\[\d+\]\.\$[a-z]+\d+\[\d+\]\.\$[a-z]+\d+\[\d+\]\.', - // $GLOBALS['qjyxw29'] = $z26[1].$z26[30].$z26[2]. - 'eval\([a-z0-9_]+\(base64_decode\(', - // eval(xxtea_decrypt(base64_decode( - '\$[a-z]{3,}=\$[a-z]{3,}\("",\$[a-z]{3,}\);\$[a-z]{3,}\(\);', - // $ewn=$ner("",$iqkpi);$ewn(); - '{\s*eval\s*\(\s*\$', - // {eval($ - - // imported manul samples - 'Googlebot[\'"]{0,1}\s*\)\){echo\s+file_get_contents', - 'eVaL\(\s*trim\(\s*baSe64_deCoDe\(', - 'if\s*\(\s*mail\s*\(\s*\$mails\[\$i\]\s*,\s*\$tema\s*,\s*base64_encode\s*\(\s*\$text', - 'fwrite\s*\(\s*\$fh\s*,\s*stripslashes\s*\(\s*@*\$_(GET|POST|SERVER|COOKIE|REQUEST)\[', - 'echo\s+file_get_contents\s*\(\s*base64_url_decode\s*\(\s*@*\$_(GET|POST|SERVER|COOKIE|REQUEST)', - 'chr\s*\(\s*101\s*\)\s*\.\s*chr\s*\(\s*118\s*\)\s*\.\s*chr\s*\(\s*97\s*\)\s*\.\s*chr\s*\(\s*108\s*\)', - ); + $patterns = $this->loadPatterns(dirname(__FILE__) . '/patterns_re.txt'); foreach ($patterns as $toSearch) { if (preg_match('/' . $toSearch . '/is', $fileContent)) { $found = true; @@ -402,9 +219,7 @@ class MalwareScanner return false; } - /** - * @see http://stackoverflow.com/a/13914119 - */ + // @see http://stackoverflow.com/a/13914119 private function pathMatches($path, $pattern, $ignoreCase = false) { $expr = preg_replace_callback(