mirror of
https://github.com/scr34m/php-malware-scanner.git
synced 2026-06-16 12:30:35 +00:00
Merge branch 'composer'
This commit is contained in:
13
composer.json
Normal file
13
composer.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "scr34m/php-malware-scanner",
|
||||||
|
"type": "library",
|
||||||
|
"description": "Scans PHP files for malwares and known threats",
|
||||||
|
"keywords": ["malware", "scanner", "commandline"],
|
||||||
|
"license": "GPL-3.0",
|
||||||
|
"homepage": "https://github.com/scr34m/php-malware-scanner",
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.2.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
}
|
||||||
|
}
|
||||||
156
scan.php
156
scan.php
@@ -26,7 +26,7 @@ class MalwareScanner
|
|||||||
private $ANSI_OFF = "\033[0m";
|
private $ANSI_OFF = "\033[0m";
|
||||||
|
|
||||||
private $dir = '';
|
private $dir = '';
|
||||||
private $extension = array ('.php');
|
private $extension = array('.php');
|
||||||
private $flagBase64 = false;
|
private $flagBase64 = false;
|
||||||
private $flagChecksum = false;
|
private $flagChecksum = false;
|
||||||
private $flagComments = false;
|
private $flagComments = false;
|
||||||
@@ -35,7 +35,8 @@ class MalwareScanner
|
|||||||
private $flagNoStop = false;
|
private $flagNoStop = false;
|
||||||
private $flagPattern = false;
|
private $flagPattern = false;
|
||||||
private $flagTime = false;
|
private $flagTime = false;
|
||||||
private $extraCheck = false;
|
private $flagExtraCheck = false;
|
||||||
|
private $flagFollowSymlink = false;
|
||||||
private $whitelist = array();
|
private $whitelist = array();
|
||||||
private $ignore = array();
|
private $ignore = array();
|
||||||
private $stat = array(
|
private $stat = array(
|
||||||
@@ -43,7 +44,6 @@ class MalwareScanner
|
|||||||
'files_scanned' => 0,
|
'files_scanned' => 0,
|
||||||
'files_infected' => 0,
|
'files_infected' => 0,
|
||||||
);
|
);
|
||||||
private $followSymlink = false;
|
|
||||||
|
|
||||||
//Pattern File Attributes
|
//Pattern File Attributes
|
||||||
private $patterns_raw = array();
|
private $patterns_raw = array();
|
||||||
@@ -52,14 +52,28 @@ class MalwareScanner
|
|||||||
private $patterns_b64functions = array();
|
private $patterns_b64functions = array();
|
||||||
private $patterns_b64keywords = array();
|
private $patterns_b64keywords = array();
|
||||||
|
|
||||||
//Constructor - Likes to do as little as possible.
|
/**
|
||||||
public function __construct()
|
* MalwareScanner constructor.
|
||||||
|
*
|
||||||
|
* @param bool $cli defines its calling from commandline or using as a library, default is true
|
||||||
|
*/
|
||||||
|
public function __construct($cli = true)
|
||||||
{
|
{
|
||||||
//Read Run Options
|
if ($cli === true) {
|
||||||
$this->parseArgs();
|
//Read Run Options
|
||||||
|
$this->parseArgs();
|
||||||
|
|
||||||
//Initiate Scan
|
//Make sure a directory was specified.
|
||||||
$this->run($this->dir);
|
if ($this->dir === '') {
|
||||||
|
$this->error('No directory specified');
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Initiate Scan
|
||||||
|
if (!$this->run($this->dir)) {
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Allows the -n/--no-color flag to easily remove color characters.
|
//Allows the -n/--no-color flag to easily remove color characters.
|
||||||
@@ -79,7 +93,6 @@ class MalwareScanner
|
|||||||
echo $this->ANSI_RED . 'Error: ' . $msg . $this->ANSI_OFF . PHP_EOL;
|
echo $this->ANSI_RED . 'Error: ' . $msg . $this->ANSI_OFF . PHP_EOL;
|
||||||
$this->showHelp();
|
$this->showHelp();
|
||||||
echo PHP_EOL . $this->ANSI_RED . 'Quiting' . PHP_EOL;
|
echo PHP_EOL . $this->ANSI_RED . 'Quiting' . PHP_EOL;
|
||||||
exit(-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Handles pattern loading and saving to the class object
|
//Handles pattern loading and saving to the class object
|
||||||
@@ -98,7 +111,7 @@ class MalwareScanner
|
|||||||
|
|
||||||
//Adds additional checks to patterns_raw
|
//Adds additional checks to patterns_raw
|
||||||
//This may be something to move into a pattern file rather than leave hardcoded.
|
//This may be something to move into a pattern file rather than leave hardcoded.
|
||||||
if ($this->extraCheck) {
|
if ($this->flagExtraCheck) {
|
||||||
$this->patterns_raw['googleBot'] = '# ';
|
$this->patterns_raw['googleBot'] = '# ';
|
||||||
$this->patterns_raw['htaccess'] = '# ';
|
$this->patterns_raw['htaccess'] = '# ';
|
||||||
}
|
}
|
||||||
@@ -203,61 +216,121 @@ class MalwareScanner
|
|||||||
if (!is_array($a)) {
|
if (!is_array($a)) {
|
||||||
$a = array($a);
|
$a = array($a);
|
||||||
}
|
}
|
||||||
$this->extension = array();
|
$this->setExtensions($a);
|
||||||
foreach ($a as $ext) {
|
|
||||||
if ($ext[0] != '.') {
|
|
||||||
$ext = '.' . $ext;
|
|
||||||
}
|
|
||||||
$this->extension[] = strtolower($ext);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (isset($options['ignore']) || isset($options['i'])) {
|
if (isset($options['ignore']) || isset($options['i'])) {
|
||||||
$tmp = isset($options['ignore']) ? $options['ignore'] : $options['i'];
|
$tmp = isset($options['ignore']) ? $options['ignore'] : $options['i'];
|
||||||
$this->ignore = is_array($tmp) ? $tmp : array($tmp);
|
$this->setIgnore(is_array($tmp) ? $tmp : array($tmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Simple Flag Options
|
//Simple Flag Options
|
||||||
if (isset($options['all-output']) || isset($options['a'])) {
|
if (isset($options['all-output']) || isset($options['a'])) {
|
||||||
$this->flagChecksum = true;
|
$this->setFlagChecksum(true);
|
||||||
$this->flagComments = true;
|
$this->setFlagComments(true);
|
||||||
$this->flagPattern = true;
|
$this->setFlagPattern(true);
|
||||||
$this->flagTime = true;
|
$this->setFlagTime(true);
|
||||||
}
|
}
|
||||||
if (isset($options['base64']) || isset($options['b'])) {
|
if (isset($options['base64']) || isset($options['b'])) {
|
||||||
$this->flagBase64 = true;
|
$this->setFlagBase64(true);
|
||||||
}
|
}
|
||||||
if (isset($options['checksum']) || isset($options['m'])) {
|
if (isset($options['checksum']) || isset($options['m'])) {
|
||||||
$this->flagChecksum = true;
|
$this->setFlagChecksum(true);
|
||||||
}
|
}
|
||||||
if (isset($options['comment']) || isset($options['c'])) {
|
if (isset($options['comment']) || isset($options['c'])) {
|
||||||
$this->flagComments = true;
|
$this->setFlagComments(true);
|
||||||
}
|
}
|
||||||
if (isset($options['extra-check']) || isset($options['x'])) {
|
if (isset($options['extra-check']) || isset($options['x'])) {
|
||||||
$this->extraCheck = true;
|
$this->setFlagExtraCheck(true);
|
||||||
}
|
}
|
||||||
if (isset($options['follow-symlink']) || isset($options['l'])) {
|
if (isset($options['follow-symlink']) || isset($options['l'])) {
|
||||||
$this->followSymlink = true;
|
$this->setFlagFollowSymlink(true);
|
||||||
}
|
}
|
||||||
if (isset($options['hide-ok']) || isset($options['k'])) {
|
if (isset($options['hide-ok']) || isset($options['k'])) {
|
||||||
$this->flagHideOk = true;
|
$this->setFlagHideOk(true);
|
||||||
}
|
}
|
||||||
if (isset($options['hide-whitelist']) || isset($options['w'])) {
|
if (isset($options['hide-whitelist']) || isset($options['w'])) {
|
||||||
$this->flagHideWhitelist = true;
|
$this->setFlagHideWhitelist(true);
|
||||||
}
|
}
|
||||||
if (isset($options['no-color']) || isset($options['n'])) {
|
if (isset($options['no-color']) || isset($options['n'])) {
|
||||||
$this->disableColor();
|
$this->disableColor();
|
||||||
}
|
}
|
||||||
if (isset($options['no-stop']) || isset($options['s'])) {
|
if (isset($options['no-stop']) || isset($options['s'])) {
|
||||||
$this->flagNoStop = true;
|
$this->setFlagNoStop(true);
|
||||||
}
|
}
|
||||||
if (isset($options['pattern']) || isset($options['p'])) {
|
if (isset($options['pattern']) || isset($options['p'])) {
|
||||||
$this->flagPattern = true;
|
$this->setFlagPattern(true);
|
||||||
}
|
}
|
||||||
if (isset($options['time']) || isset($options['t'])) {
|
if (isset($options['time']) || isset($options['t'])) {
|
||||||
$this->flagTime = true;
|
$this->setFlagTime(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setExtensions(array $a)
|
||||||
|
{
|
||||||
|
$this->extension = array();
|
||||||
|
foreach ($a as $ext) {
|
||||||
|
if ($ext[0] != '.') {
|
||||||
|
$ext = '.' . $ext;
|
||||||
|
}
|
||||||
|
$this->extension[] = strtolower($ext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setIgnore(array $a)
|
||||||
|
{
|
||||||
|
$this->ignore = $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFlagChecksum($b)
|
||||||
|
{
|
||||||
|
$this->flagChecksum = $b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFlagComments($b)
|
||||||
|
{
|
||||||
|
$this->flagComments = $b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFlagPattern($b)
|
||||||
|
{
|
||||||
|
$this->flagPattern = $b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFlagTime($b)
|
||||||
|
{
|
||||||
|
$this->flagTime = $b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFlagBase64($b)
|
||||||
|
{
|
||||||
|
$this->flagBase64 = $b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFlagExtraCheck($b)
|
||||||
|
{
|
||||||
|
$this->flagExtraCheck = $b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFlagFollowSymlink($b)
|
||||||
|
{
|
||||||
|
$this->flagFollowSymlink = $b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFlagHideOk($b)
|
||||||
|
{
|
||||||
|
$this->flagHideOk = $b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFlagHideWhitelist($b)
|
||||||
|
{
|
||||||
|
$this->flagHideWhitelist = $b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFlagNoStop($b)
|
||||||
|
{
|
||||||
|
$this->flagNoStop = $b;
|
||||||
|
}
|
||||||
|
|
||||||
// @see http://stackoverflow.com/a/13914119
|
// @see http://stackoverflow.com/a/13914119
|
||||||
private function pathMatches($path, $pattern, $ignoreCase = false)
|
private function pathMatches($path, $pattern, $ignoreCase = false)
|
||||||
{
|
{
|
||||||
@@ -370,7 +443,7 @@ class MalwareScanner
|
|||||||
if ($this->isIgnored($dir . $file)) {
|
if ($this->isIgnored($dir . $file)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!$this->followSymlink && is_link($dir . $file)) {
|
if (!$this->flagFollowSymlink && is_link($dir . $file)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (is_dir($dir . $file)) {
|
if (is_dir($dir . $file)) {
|
||||||
@@ -401,17 +474,13 @@ class MalwareScanner
|
|||||||
//Validates the input directory
|
//Validates the input directory
|
||||||
//Calls the load pattern and load whitelist functions
|
//Calls the load pattern and load whitelist functions
|
||||||
//Calls the process and report functions.
|
//Calls the process and report functions.
|
||||||
private function run($dir)
|
public function run($dir)
|
||||||
{
|
{
|
||||||
//Make sure a directory was specified.
|
|
||||||
if ($this->dir === '') {
|
|
||||||
$this->error('No directory specified');
|
|
||||||
}
|
|
||||||
|
|
||||||
//Make sure the input is a valid directory path.
|
//Make sure the input is a valid directory path.
|
||||||
$dir = rtrim($dir, '/');
|
$dir = rtrim($dir, '/');
|
||||||
if (!is_dir($dir)) {
|
if (!is_dir($dir)) {
|
||||||
$this->error('Specified path is not a directory: ' . $dir);
|
$this->error('Specified path is not a directory: ' . $dir);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Load Patterns
|
//Load Patterns
|
||||||
@@ -423,6 +492,7 @@ class MalwareScanner
|
|||||||
$start = time();
|
$start = time();
|
||||||
$this->process($dir . '/');
|
$this->process($dir . '/');
|
||||||
$this->report($start, $dir . '/');
|
$this->report($start, $dir . '/');
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Loads target file contents for scanning
|
//Loads target file contents for scanning
|
||||||
@@ -531,5 +601,7 @@ class MalwareScanner
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new MalwareScanner object which does all the work.
|
// script it's self called and not included
|
||||||
new MalwareScanner();
|
if (isset($argv[0]) && realpath($argv[0]) == realpath(__FILE__)) {
|
||||||
|
new MalwareScanner();
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user