mirror of
https://github.com/scr34m/php-malware-scanner.git
synced 2026-06-16 12:30:35 +00:00
large 'scan' function broken up comment flag added
scan function has been broken up into a multiple functions which should make it more modular if future scan types are needed. --comment, -a flag was added which prints the first comment to appear prior to the matched pattern in the pattern file.
This commit is contained in:
129
scan.php
129
scan.php
@@ -27,7 +27,9 @@ class MalwareScanner
|
||||
|
||||
private $dir = '';
|
||||
private $extension = '.php';
|
||||
private $flagBase64 = false;
|
||||
private $flagChecksum = false;
|
||||
private $flagComments = false;
|
||||
private $flagHideOk = false;
|
||||
private $flagHideWhitelist = false;
|
||||
private $flagTime = false;
|
||||
@@ -42,9 +44,11 @@ class MalwareScanner
|
||||
);
|
||||
private $followSymlink = false;
|
||||
|
||||
private $patterns_raw = array();
|
||||
private $patterns_iraw = array();
|
||||
private $patterns_re = array();
|
||||
private $patterns_raw = array();
|
||||
private $patterns_iraw = array();
|
||||
private $patterns_re = array();
|
||||
private $patterns_b64functions = array();
|
||||
private $patterns_b64keywords = array();
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@@ -77,9 +81,17 @@ class MalwareScanner
|
||||
|
||||
private function initializePatterns()
|
||||
{
|
||||
$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');
|
||||
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');
|
||||
}
|
||||
|
||||
if ($this->flagBase64) {
|
||||
$this->patterns_b64functions = $this->loadPatterns(dirname(__FILE__). '/php_functions.txt');
|
||||
$this->patterns_b64keywrds = $this->loadPatterns(dirname(__FILE__). '/php_keywords.txt');
|
||||
}
|
||||
|
||||
if ($this->extraCheck) {
|
||||
array_push($this->patterns_raw, "googleBot", "htaccess");
|
||||
}
|
||||
@@ -103,6 +115,7 @@ class MalwareScanner
|
||||
|
||||
private function loadPatterns($file)
|
||||
{
|
||||
$last_comment = '';
|
||||
$list = array();
|
||||
if (is_readable($file)) {
|
||||
foreach (file($file) as $pattern) {
|
||||
@@ -112,9 +125,10 @@ class MalwareScanner
|
||||
}
|
||||
//Check if first char in pattern is a '#' which indicates a comment and skips.
|
||||
if ($pattern[0] === '#') {
|
||||
$last_comment = $pattern;
|
||||
continue;
|
||||
}
|
||||
$list[] = trim($pattern);
|
||||
$list[trim($pattern)] = trim($last_comment);
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
@@ -134,7 +148,7 @@ class MalwareScanner
|
||||
|
||||
private function parseArgs()
|
||||
{
|
||||
$options = getopt('d:e:i:cxlhkwntv', array('directory:', 'extension:', 'ignore:', 'checksum', 'extra-check', 'follow-link', 'help', 'hide-ok', 'hide-whitelist', 'no-color', 'time', 'verbose'));
|
||||
$options = getopt('d:e:i:bacxlhkwntv', array('directory:', 'extension:', 'ignore:', 'base', 'checksum', 'comment', 'extra-check', 'follow-link', 'help', 'hide-ok', 'hide-whitelist', 'no-color', 'time', 'verbose'));
|
||||
|
||||
//Help Option should be first
|
||||
if (isset($options['help']) || isset($options['h'])) {
|
||||
@@ -159,9 +173,15 @@ class MalwareScanner
|
||||
}
|
||||
|
||||
//Simple Flag Options
|
||||
if (isset($options['base64']) || isset($options['b'])){
|
||||
$this->flagBase64 = true;
|
||||
}
|
||||
if (isset($options['checksum']) || isset($options['c'])){
|
||||
$this->flagChecksum = true;
|
||||
}
|
||||
if (isset($options['comment']) || isset($options['a'])){
|
||||
$this->flagComments = true;
|
||||
}
|
||||
if (isset($options['extra-check']) || isset($options['x'])) {
|
||||
$this->extraCheck = true;
|
||||
}
|
||||
@@ -211,7 +231,7 @@ class MalwareScanner
|
||||
return (bool)preg_match($expr, $path);
|
||||
}
|
||||
|
||||
private function printPath($found, $path, $pattern, $hash)
|
||||
private function printPath(&$found, &$path, &$pattern, &$comment, &$hash)
|
||||
{
|
||||
$output_string = '# ';
|
||||
|
||||
@@ -256,6 +276,9 @@ class MalwareScanner
|
||||
if ($found) {
|
||||
$opatt = "# $pattern";
|
||||
$output_string = $output_string . $state_color . $opatt . $this->ANSI_OFF;
|
||||
if ($this->flagComments) {
|
||||
$output_string = $output_string . ' ' . $comment;
|
||||
}
|
||||
}
|
||||
|
||||
$output_string = $output_string . PHP_EOL;
|
||||
@@ -331,52 +354,20 @@ class MalwareScanner
|
||||
$found = false;
|
||||
$hash = '';
|
||||
$toSearch = '';
|
||||
|
||||
foreach ($this->patterns_raw as $toSearch) {
|
||||
if (strpos($fileContent, $toSearch) !== FALSE){
|
||||
$found = true;
|
||||
if ($hash === ''){
|
||||
$hash = md5($fileContent);
|
||||
}
|
||||
$this->printPath($found, $path, $toSearch, $hash);
|
||||
if (!$this->verbose){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found || $this->verbose) {
|
||||
foreach ($this->patterns_iraw as $toSearch) {
|
||||
if (stripos($fileContent, $toSearch) !== FALSE){
|
||||
$found = true;
|
||||
if ($hash === ''){
|
||||
$hash = md5($fileContent);
|
||||
}
|
||||
$this->printPath($found, $path, $toSearch, $hash);
|
||||
if (!$this->verbose){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$comment = '';
|
||||
|
||||
if (!$found || $this->verbose) {
|
||||
foreach ($this->patterns_re as $toSearch) {
|
||||
if (preg_match('/' . $toSearch . '/im', $fileContent)) {
|
||||
$found = true;
|
||||
if ($hash === ''){
|
||||
$hash = md5($fileContent);
|
||||
}
|
||||
$this->printPath($found, $path, $toSearch, $hash);
|
||||
if (!$this->verbose){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$this->flagBase64) {
|
||||
$this->scanLoop('scanFunc_STR', $fileContent, $this->patterns_raw, $path, $found, $hash);
|
||||
$this->scanLoop('scanFunc_STRI', $fileContent, $this->patterns_iraw, $path, $found, $hash);
|
||||
$this->scanLoop('scanFunc_RE', $fileContent, $this->patterns_re, $path, $found, $hash);
|
||||
}
|
||||
if ($this->flagBase64) {
|
||||
$this->scanLoop('scanFunc_STR', $fileContent, $this->patterns_b64functions, $path, $found, $hash);
|
||||
$this->scanLoop('scanFunc_STR', $fileContent, $this->patterns_b64keywords, $path, $found, $hash);
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
$this->printPath($found, $path, $toSearch, $hash);
|
||||
$this->printPath($found, $path, $toSearch, $comment, $hash);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -388,6 +379,40 @@ class MalwareScanner
|
||||
return true;
|
||||
}
|
||||
|
||||
private function scanFunc_STR(&$pattern, &$content)
|
||||
{
|
||||
return (strpos($content, $pattern) !== false);
|
||||
}
|
||||
|
||||
private function scanFunc_STRI(&$pattern, &$content)
|
||||
{
|
||||
return (stripos($content, $pattern) !== false);
|
||||
}
|
||||
|
||||
private function scanFunc_RE(&$pattern, &$content)
|
||||
{
|
||||
return preg_match('/' . $pattern . '/im', $content);
|
||||
}
|
||||
|
||||
private function scanLoop($scanFunction, &$fileContent, &$patterns, &$path, &$found, &$hash)
|
||||
{
|
||||
if (!$found || $this->verbose) {
|
||||
foreach ($patterns as $pattern => $comment) {
|
||||
if ($this->$scanFunction($pattern, $fileContent)) {
|
||||
$found = true;
|
||||
if ($hash === ''){
|
||||
$hash = md5($fileContent);
|
||||
}
|
||||
$this->printPath($found, $path, $pattern, $comment, $hash);
|
||||
if (!$this->verbose){
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function showHelp()
|
||||
{
|
||||
echo 'Usage: scan.php -d <directory>' . PHP_EOL;
|
||||
@@ -395,7 +420,9 @@ class MalwareScanner
|
||||
echo ' -d <directory> --directory Directory for searching' . PHP_EOL;
|
||||
echo ' -e <file extension> --extension File Extension to Scan' . PHP_EOL;
|
||||
echo ' -i <directory|file> --ignore Directory of file to igonre' . PHP_EOL;
|
||||
echo ' -b --base64 Scan for base64 encoded PHP keywords' . PHP_EOL;
|
||||
echo ' -c --checksum Display MD5 Checksum of file' . PHP_EOL;
|
||||
echo ' -a --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 OK aka not infected messages' . PHP_EOL;
|
||||
|
||||
Reference in New Issue
Block a user