diff --git a/scan.php b/scan.php index 5a4038e..964bf24 100644 --- a/scan.php +++ b/scan.php @@ -19,29 +19,30 @@ class MalwareScanner { //Pretty Colors - private $ANSI_GREEN = "\033[32m"; - private $ANSI_RED = "\033[31m"; - private $ANSI_YELLOW = "\033[33m"; - private $ANSI_BLUE = "\033[36m"; - private $ANSI_OFF = "\033[0m"; + private $ANSI_GREEN = "\033[32m"; + private $ANSI_RED = "\033[31m"; + private $ANSI_YELLOW = "\033[33m"; + private $ANSI_BLUE = "\033[36m"; + private $ANSI_OFF = "\033[0m"; - private $dir = ''; - private $extension = '.php'; - private $flagBase64 = false; - private $flagChecksum = false; - private $flagComments = false; - private $flagHideOk = false; + private $dir = ''; + private $extension = '.php'; + private $flagBase64 = false; + private $flagChecksum = false; + private $flagComments = false; + private $flagHideOk = false; private $flagHideWhitelist = false; - private $flagTime = false; - private $extraCheck = false; - private $verbose = false; - private $whitelist = array(); - private $ignore = array(); - private $stat = array( - 'directories' => 0, - 'files_scanned' => 0, - 'files_infected' => 0, - ); + private $flagNoStop = false; + private $flagPattern = false; + private $flagTime = false; + private $extraCheck = false; + private $whitelist = array(); + private $ignore = array(); + private $stat = array( + 'directories' => 0, + 'files_scanned' => 0, + 'files_infected' => 0, + ); private $followSymlink = false; //Pattern File Attributes @@ -86,13 +87,13 @@ class MalwareScanner { //Loads either the primary scanning patterns or the base64 patterns depending on -b/--base64 flag if (!$this->flagBase64) { - $this->patterns_raw = $this->loadPatterns(dirname(__FILE__) . '/patterns_raw.txt'); - $this->patterns_iraw = $this->loadPatterns(dirname(__FILE__) . '/patterns_iraw.txt'); - $this->patterns_re = $this->loadPatterns(dirname(__FILE__) . '/patterns_re.txt'); + $this->patterns_raw = $this->loadPatterns(dirname(__FILE__) . 'definitions/patterns_raw.txt'); + $this->patterns_iraw = $this->loadPatterns(dirname(__FILE__) . 'definitions/patterns_iraw.txt'); + $this->patterns_re = $this->loadPatterns(dirname(__FILE__) . 'definitions/patterns_re.txt'); } else { - $this->patterns_b64functions = $this->loadPatterns(dirname(__FILE__). '/php_functions.txt'); - $this->patterns_b64keywords = $this->loadPatterns(dirname(__FILE__). '/php_keywords.txt'); + $this->patterns_b64functions = $this->loadPatterns(dirname(__FILE__). 'base64_patterns/php_functions.txt'); + $this->patterns_b64keywords = $this->loadPatterns(dirname(__FILE__). 'base64_patterns/php_keywords.txt'); } //Adds additional checks to patterns_raw @@ -165,7 +166,25 @@ class MalwareScanner //All flag handling stuff should be setup here. private function parseArgs() { - $options = getopt('d:e:i:bmcxlhkwntv', array('directory:', 'extension:', 'ignore:', 'base', 'checksum', 'comment', 'extra-check', 'follow-link', 'help', 'hide-ok', 'hide-whitelist', 'no-color', 'time', 'verbose')); + $options = getopt( 'd:e:i:abmcxlhkwnspt', + array( + 'directory:', + 'extension:', + 'ignore:', + 'all-output', + 'base', + 'checksum', + 'comment', + 'extra-check', + 'follow-link', + 'help', + 'hide-ok', + 'hide-whitelist', + 'no-color', + 'no-stop', + 'pattern', + 'time' + )); //Help Option should be first if (isset($options['help']) || isset($options['h'])) { @@ -190,6 +209,9 @@ class MalwareScanner } //Simple Flag Options + if (isset($options['all-output']) || isset($options['a'])) { + $this->flagChecksum = true; $this->flagComments = true; $this->flagPattern = true; $this->flagTime = true; + } if (isset($options['base64']) || isset($options['b'])) { $this->flagBase64 = true; } @@ -214,12 +236,15 @@ class MalwareScanner if (isset($options['no-color']) || isset($options['n'])) { $this->disableColor(); } + if (isset($options['no-stop']) || isset($options['s'])) { + $this->flagNoStop = true; + } + if (isset($options['pattern']) || isset($options['p'])) { + $this->flagPattern = true; + } if (isset($options['time']) || isset($options['t'])) { $this->flagTime = true; } - if (isset($options['verbose']) || isset($options['v'])) { - $this->verbose = true; - } } // @see http://stackoverflow.com/a/13914119 @@ -266,6 +291,7 @@ class MalwareScanner if (!$found) { if ($this->flagHideOk){return;} $state = 'OK'; + $hash = ' '; $state_color = $this->ANSI_GREEN; } //WL @@ -301,10 +327,12 @@ class MalwareScanner //'#' added again as code snippets have the potential to be valid shell commands if ($found) { - $opatt = "# $pattern"; - $output_string = $output_string . $state_color . $opatt . $this->ANSI_OFF; + if ($this->flagPattern) { + $opatt = "# $pattern "; + $output_string = $output_string . $state_color . $opatt . $this->ANSI_OFF; + } if ($this->flagComments) { - $output_string = $output_string . ' ' . $comment; + $output_string = $output_string . $this->ANSI_BLUE . $comment . $this->ANSI_OFF; } } @@ -449,7 +477,7 @@ class MalwareScanner //Variables passed by reference for performance and modification access. private function scanLoop($scanFunction, &$fileContent, &$patterns, &$path, &$found, &$hash) { - if (!$found || $this->verbose) { + if (!$found || $this->flagNoStop) { foreach ($patterns as $pattern => $comment) { //Call the function that is named in $scanFunction //This allows multiple search/match functions to be used without duplicating the loop code. @@ -457,7 +485,7 @@ class MalwareScanner $found = true; if ($hash === ''){$hash = md5($fileContent);} $this->printPath($found, $path, $pattern, $comment, $hash); - if (!$this->verbose){return;} + if (!$this->flagNoStop){return;} } } } @@ -466,21 +494,23 @@ class MalwareScanner //Prints out the usage menu options. private function showHelp() { - echo 'Usage: scan.php -d ' . PHP_EOL; - echo ' -h --help Show this help message' . PHP_EOL; - echo ' -d --directory Directory for searching' . PHP_EOL; - echo ' -e --extension File Extension to Scan' . PHP_EOL; - echo ' -i --ignore Directory of file to ignore' . PHP_EOL; - echo ' -b --base64 Scan for base64 encoded PHP keywords' . PHP_EOL; - echo ' -m --checksum Display MD5 Hash/Checksum of file' . PHP_EOL; - echo ' -c --comment Display comments for matched patterns' . 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 ' -k --hide-ok Hide results with \'OK\' status' . PHP_EOL; - echo ' -w --hide-whitelist Hide results with \'WL\' status' . PHP_EOL; - echo ' -n --no-color Disable color mode' . PHP_EOL; - echo ' -t --time Show time of last file change' . PHP_EOL; - echo ' -v --verbose Continue scanning file after first hit' . PHP_EOL; + echo 'Usage: php scan.php -d ' . PHP_EOL; + echo ' -h --help Show this help message' . PHP_EOL; + echo ' -d --directory Directory for searching' . PHP_EOL; + echo ' -e --extension File Extension to Scan' . PHP_EOL; + echo ' -i --ignore Directory of file to ignore' . PHP_EOL; + echo ' -a --all-output Enables --checksum,--comment,--pattern,--time' . PHP_EOL; + echo ' -b --base64 Scan for base64 encoded PHP keywords' . PHP_EOL; + echo ' -m --checksum Display MD5 Hash/Checksum of file' . PHP_EOL; + echo ' -c --comment Display comments for matched patterns' . 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 ' -k --hide-ok Hide results with \'OK\' status' . PHP_EOL; + echo ' -w --hide-whitelist Hide results with \'WL\' status' . PHP_EOL; + echo ' -n --no-color Disable color mode' . PHP_EOL; + echo ' -s --no-stop Continue scanning file after first hit' . PHP_EOL; + echo ' -p --pattern Show Patterns next to the file name' . PHP_EOL; + echo ' -t --time Show time of last file change' . PHP_EOL; } }