diff --git a/scan.php b/scan.php index de3fa94..6d001d9 100644 --- a/scan.php +++ b/scan.php @@ -21,12 +21,14 @@ class MalwareScanner const ANSI_GREEN = "\033[32m"; const ANSI_RED = "\033[31m"; const ANSI_YELLOW = "\033[33m"; + const ANSI_BLUE = "\033[36m"; const ANSI_OFF = "\033[0m"; private $extension = '.php'; private $flagHideOk = false; private $flagHideWhitelist = false; private $extraCheck = false; + private $verbose = false; private $whitelist = array(); private $ignore = array(); private $stat = array( @@ -38,7 +40,7 @@ class MalwareScanner public function __construct() { - $options = getopt('he:i:kwxd:l', array('help', 'extension:', 'ignore:', 'hide-ok', 'hide-whitelist', 'extra-check', 'directory:', 'follow-symlink')); + $options = getopt('he:i:kwxd:lv', array('help', 'extension:', 'ignore:', 'hide-ok', 'hide-whitelist', 'extra-check', 'directory:', 'follow-symlink', 'verbose')); if (isset($options['help']) || isset($options['h'])) { $this->showHelp(); exit; @@ -66,6 +68,9 @@ class MalwareScanner if (isset($options['follow-symlink']) || isset($options['l'])) { $this->followSymlink = true; } + if (isset($options['verbose']) || isset($options['v'])){ + $this->verbose = true; + } if (isset($options['directory']) || isset($options['d'])) { $tmp = isset($options['directory']) ? $options['directory'] : $options['d']; $this->run($tmp); @@ -163,6 +168,7 @@ class MalwareScanner $fileContent = file_get_contents($path); $found = false; + $hash = ''; $toSearch = ''; $patterns = $this->loadPatterns(dirname(__FILE__) . '/patterns_raw.txt'); if ($this->extraCheck) { @@ -177,7 +183,13 @@ class MalwareScanner } if (strpos($fileContent, $toSearch) !== FALSE){ $found = true; - break; + if ($hash === ''){ + $hash = md5($fileContent); + } + $this->printPath($found, $path, $toSearch, $hash); + if (!$this->verbose){ + break; + } } } @@ -192,7 +204,13 @@ class MalwareScanner } if (stripos($fileContent, $toSearch) !== FALSE){ $found = true; - break; + if ($hash === ''){ + $hash = md5($fileContent); + } + $this->printPath($found, $path, $toSearch, $hash); + if (!$this->verbose){ + break; + } } } } @@ -208,33 +226,50 @@ class MalwareScanner } if (preg_match('/' . $toSearch . '/im', $fileContent)) { $found = true; - break; + if ($hash === ''){ + $hash = md5($fileContent); + } + $this->printPath($found, $path, $toSearch, $hash); + if (!$this->verbose){ + break; + } } } } if (!$found) { - if (!$this->flagHideOk) { - $this->out(self::ANSI_GREEN, 'OK', $path); - } + $this->printPath($found, $path, $toSearch, $hash); return false; } - // file hash is on whithelist hash then skip - $hash = md5($fileContent); + if ($found && $this->inWhitelist($hash)) { + return false; + } + + $this->stat['files_infected']++; + return true; + } + + private function printPath($found, $path, $pattern, $hash) + { + $blank_hash = ' '; + $blank_pattern = ''; + $safe_path = '{' . $path . '}'; if ($found && $this->inWhitelist($hash)) { if (!$this->flagHideWhitelist) { - $this->out(self::ANSI_YELLOW, 'WL', $path); + $this->out(self::ANSI_YELLOW, 'WL', $blank_hash, $safe_path, $blank_pattern); } - return false; } - if ($found) { - $this->stat['files_infected']++; - $this->out(self::ANSI_RED, 'ER', $path . ' -> ' . $toSearch . ' ' . $hash); + elseif ($found) { + $this->out(self::ANSI_RED, 'ER', $hash, $safe_path, $pattern); } - return true; + else { + if (!$this->flagHideOk) { + $this->out(self::ANSI_GREEN, 'OK', $blank_hash, $safe_path, $blank_pattern); + } + } } private function isIgnored($pathname) @@ -274,9 +309,9 @@ class MalwareScanner return (bool)preg_match($expr, $path); } - private function out($color, $serv, $text) + private function out($color, $serv, $hash, $path, $pattern) { - echo $color . ' ' . $serv . ' ' . self::ANSI_OFF . $text . PHP_EOL; + echo $color . '#' . ' ' . $serv . self::ANSI_BLUE . " $hash " . self::ANSI_OFF . "# " . $path . $color . ' # ' . $pattern . self::ANSI_OFF . PHP_EOL; } private function showHelp() @@ -290,8 +325,10 @@ class MalwareScanner echo ' -w --hide-whitelist Hide whitelisted messages' . PHP_EOL; echo ' -x --extra-check Adds GoogleBot and htaccess to Scan List' . PHP_EOL; echo ' -l --follow-symlink Follow symlinked directories' . PHP_EOL; + echo ' -v --verbose Continue scanning file afater first hit' . PHP_EOL; } } new MalwareScanner(); +?>