Several Significant changes to scan.php

- Gave each flag option a short or long option; like i:ignore or d:directory or k:hide-ok
- Added a verbose option that instructs the scan to scan a file for ALL matches and not just stop at the first one.
- Restructured the output code to allow for the verbose flag, mainly a new function printPath and where the md5 hash is computed
- Modified the output to be cleaner, checksum is printed first as it is fix-width and to make it easier to paste into the whitelist file.
- Modified the output to be 'bash safe', ie when I accidentally paste my scan results into my terminal, the '#' should make sure everything is treated as a comment.  This is in contrast to possibly attempting to execute absolute paths to potentially malicious PHP scripts and the usage of the '>' which tells the shell to write to a file.  Also enclosed each path in {} for similar purposes.
- Printing the matched string/pattern in $color... might change later depending on  preference.
This commit is contained in:
nichogenius
2017-08-16 00:11:54 -06:00
committed by GitHub
parent b2099f2424
commit 62e25eb5f8

View File

@@ -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();
?>