13 Commits
1.0.1 ... 1.0.7

Author SHA1 Message Date
Gabor Gyorvari
2b1a0c1266 Signature update from new infections 2020-10-01 11:26:02 +02:00
Gabor Gyorvari
c495cc822c Signature update for a pattern $_uU(101).$_uU(118).$_uU(97) 2020-09-30 17:02:33 +02:00
Gabor Gyorvari
e9a45d4bdc Allowing multiple use of -d option and braces in path syntax, closes #56 2020-08-18 15:36:52 +02:00
Gabor Gyorvari
21185202f3 Combined whitelist updated 2020-06-25 17:10:40 +02:00
Győrvári Gábor
195717d625 Merge pull request #55 from scr34m/libmode
Change function visibility to allow usage as library
2020-06-24 10:17:19 +02:00
Gabor Gyorvari
2973e55871 Change function visibility to allow usage as library 2020-06-23 19:37:29 +02:00
Gabor Gyorvari
8b1994956e Whitelist for sucuri-scanner wordpress plugin reported in #54 2020-03-08 17:13:29 +01:00
Győrvári Gábor
46faa31c74 Merge pull request #52 from cbotsikas/fix-php-support
Use array() instead of the short array syntax []
2019-07-24 16:32:18 +02:00
Christos Botsikas
d67a865bf0 Use array() instead of the short array syntax []
Short array syntax [] was added in PHP 5.4 but the scanner should be able to work with [PHP >=5.2.0](https://github.com/scr34m/php-malware-scanner/blob/master/composer.json#L9).
2019-07-24 12:32:59 +02:00
Gabor Gyorvari
b290826f82 New option to disable statistics 2019-05-28 09:17:11 +02:00
Gabor Gyorvari
8030cec89f PR-47 comment and duplicate fix 2019-05-17 13:21:04 +02:00
Győrvári Gábor
9ec295f80d Merge pull request #47 from cconversion/master
Update patterns_raw.txt
2019-05-17 13:16:55 +02:00
cconversion
c1c71bd9ef Update patterns_raw.txt
Added WP-VCD Malware strings
2019-02-11 05:53:33 +11:00
7 changed files with 125 additions and 76 deletions

View File

@@ -35,6 +35,7 @@ Usage: php scan.php -d <directory>
-o --output-format Custom defined output format -o --output-format Custom defined output format
-j --wordpress-version Version of wordpress to get md5 signatures -j --wordpress-version Version of wordpress to get md5 signatures
--combined-whitelist Combined whitelist --combined-whitelist Combined whitelist
--disable-stats Disable statistics output
``` ```
Ignore argument could be used multiple times and accept glob style matching ex.: "`cache*`", "`??-cache.php`" or "`/cache`" etc. Ignore argument could be used multiple times and accept glob style matching ex.: "`cache*`", "`??-cache.php`" or "`/cache`" etc.

View File

@@ -1,7 +1,7 @@
#This file contains raw strings that will be matched case-insensitive. # This file contains raw strings that will be matched case-insensitive.
#Comments and whitespace are possible, but comments must have '#' at the first character of the line. # Comments and whitespace are possible, but comments must have '#' at the first character of the line.
#List of security service providers that phishers often block. # List of security service providers that phishers often block.
abovenet abovenet
avira avira
bitdefender bitdefender
@@ -17,3 +17,6 @@ phishtank
sophos sophos
surfright surfright
symantec symantec
# SEO poison, pharmacy redirect
dealonline.su

View File

@@ -261,6 +261,14 @@ tmhapbzcerff
IndoXploit IndoXploit
FaisaL Ahmed aka rEd X FaisaL Ahmed aka rEd X
# WP-VCD Malware https://www.getastra.com/blog/911/how-to-fix-wp-vcd-backdoor-hack-in-wordpress-functions-php/
wp-vcd
class.theme-modules.php
wp-tmp.php
tmpcontentx
function wp_temp_setupx
derna.top/code.php
stripos($tmpcontent, $wp_auth_key)
#Miscellaneous #Miscellaneous
uname -a uname -a
@@ -363,3 +371,7 @@ ZeroByte
# JS escaped: String.fromCharCode( # JS escaped: String.fromCharCode(
83, 116, 114, 105, 110, 103, 46, 102, 114, 111, 109, 67, 104, 97, 114, 67, 111, 100, 101, 40 83, 116, 114, 105, 110, 103, 46, 102, 114, 111, 109, 67, 104, 97, 114, 67, 111, 100, 101, 40
# SEO poisoning control site call
"http://$xxx
?useragent=$botbotbot

View File

@@ -4,10 +4,13 @@ eval\/\*[a-z0-9]+\*\/
# #
eval\([a-z0-9]{4,}\(\$[a-z0-9]{4,}, \$[0-9a-z]{4,}\)\); eval\([a-z0-9]{4,}\(\$[a-z0-9]{4,}, \$[0-9a-z]{4,}\)\);
# # chr(101).chr(118).chr(97)
(chr\(\d+\^\d+\)\.){4,} (chr\(\d+\^\d+\)\.){4,}
# # $_uU(101).$_uU(118).$_uU(97)
(\$\_[a-z0-9]{2,}\(\d+\)\.){4,}
# $uUx[101].$uUx[118].$uUx[97]
(\$[a-z0-9]{3,}\[\d+\]\.){4,} (\$[a-z0-9]{3,}\[\d+\]\.){4,}
# #
@@ -37,6 +40,9 @@ Googlebot['"]{0,1}\s*\)\){echo\s+file_get_contents
#execute base64 code #execute base64 code
eVaL\(\s*trim\(\s*baSe64_deCoDe\( eVaL\(\s*trim\(\s*baSe64_deCoDe\(
# execute escaped code
exec\("(\\[0-9a-fx]{2,3}){3,}
# #
if\s*\(\s*mail\s*\(\s*\$mails\[\$i\]\s*,\s*\$tema\s*,\s*base64_encode\s*\(\s*\$text if\s*\(\s*mail\s*\(\s*\$mails\[\$i\]\s*,\s*\$tema\s*,\s*base64_encode\s*\(\s*\$text
@@ -108,3 +114,6 @@ function\s+_[0-9]{8,}\(
# create_function is dangerous as like eval() see http://php.net/manual/en/function.create-function.php # create_function is dangerous as like eval() see http://php.net/manual/en/function.create-function.php
create_function\s*\(\s*['"]{2} create_function\s*\(\s*['"]{2}
# control concated from cookie at the call
(\$[a-z]{2,}=urldecode\(\$_COOKIE\['[a-z]{2,}'\]\);){3,}

View File

@@ -40,6 +40,7 @@ class MalwareScanner
private $flagLineNumber = false; private $flagLineNumber = false;
private $flagScanEverything = false; private $flagScanEverything = false;
private $flagCombinedWhitelist = false; private $flagCombinedWhitelist = false;
private $flagDisableStats = false;
private $outputFormat = ''; private $outputFormat = '';
private $whitelist = array(); private $whitelist = array();
private $ignore = array(); private $ignore = array();
@@ -68,16 +69,31 @@ class MalwareScanner
if ($cli === true) { if ($cli === true) {
//Read Run Options //Read Run Options
$this->parseArgs(); $this->parseArgs();
$this->dir = realpath($this->dir);
$dirs = array();
if (is_array($this->dir)) {
// allow multiple directory aka. array
foreach ($this->dir as $path) {
$dirs[] = realpath($path);
}
} elseif ($bpos = strpos($this->dir, '{')) {
// Check path has a "brace", expand it to subdirectories
foreach (glob($this->dir, GLOB_BRACE) as $path) {
$dirs[] = realpath($path);
}
} else {
// only one directory specified
$dirs = array (realpath($this->dir));
}
//Make sure a directory was specified. //Make sure a directory was specified.
if ($this->dir === '') { if (empty($dirs)) {
$this->error('No directory specified or directory doesn\'t exist'); $this->error('No directory specified or directory doesn\'t exist');
exit(-1); exit(-1);
} }
//Initiate Scan //Initiate Scan
if (!$this->run($this->dir)) { if (!$this->run($dirs)) {
exit(-1); exit(-1);
} }
} }
@@ -103,7 +119,7 @@ class MalwareScanner
} }
//Handles pattern loading and saving to the class object //Handles pattern loading and saving to the class object
private function initializePatterns() public function initializePatterns()
{ {
$dir = dirname(__FILE__); $dir = dirname(__FILE__);
//Loads either the primary scanning patterns or the base64 patterns depending on -b/--base64 flag //Loads either the primary scanning patterns or the base64 patterns depending on -b/--base64 flag
@@ -175,7 +191,7 @@ class MalwareScanner
} }
//Loads the whitelist file //Loads the whitelist file
private function loadWhitelist() public function loadWhitelist()
{ {
if (!is_file(__DIR__ . '/whitelist.txt')) { if (!is_file(__DIR__ . '/whitelist.txt')) {
return; return;
@@ -230,7 +246,8 @@ class MalwareScanner
'output-format:', 'output-format:',
'wordpress-version:', 'wordpress-version:',
'scan-everything', 'scan-everything',
'combined-whitelist' 'combined-whitelist',
'disable-stats'
) )
); );
@@ -313,6 +330,9 @@ class MalwareScanner
if (isset($options['combined-whitelist'])) { if (isset($options['combined-whitelist'])) {
$this->setFlagCombinedWhitelist(true); $this->setFlagCombinedWhitelist(true);
} }
if (isset($options['disable-stats'])) {
$this->setFlagDisableStats(true);
}
} }
public function setExtensions(array $a) public function setExtensions(array $a)
@@ -401,6 +421,11 @@ class MalwareScanner
$this->flagCombinedWhitelist = $b; $this->flagCombinedWhitelist = $b;
} }
public function setFlagDisableStats($b)
{
$this->flagDisableStats = $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)
{ {
@@ -501,7 +526,7 @@ class MalwareScanner
} }
if ($this->outputFormat) { if ($this->outputFormat) {
$map = [ $map = array(
'%S' => $state, '%S' => $state,
'%T' => $ctime, '%T' => $ctime,
'%M' => $hash, '%M' => $hash,
@@ -509,9 +534,9 @@ class MalwareScanner
'%P' => $pattern, '%P' => $pattern,
'%C' => $comment, '%C' => $comment,
'%L' => $lineNumber, '%L' => $lineNumber,
]; );
} else { } else {
$map = [ $map = array(
'%S' => $state_color . '# ' . $state . $this->ANSI_OFF, '%S' => $state_color . '# ' . $state . $this->ANSI_OFF,
'%T' => $this->ANSI_BLUE . $ctime . $this->ANSI_OFF, '%T' => $this->ANSI_BLUE . $ctime . $this->ANSI_OFF,
'%M' => $this->ANSI_BLUE . $hash . $this->ANSI_OFF, '%M' => $this->ANSI_BLUE . $hash . $this->ANSI_OFF,
@@ -519,7 +544,7 @@ class MalwareScanner
'%P' => $state_color . '#' . $pattern . $this->ANSI_OFF, '%P' => $state_color . '#' . $pattern . $this->ANSI_OFF,
'%C' => $this->ANSI_BLUE . $comment . $this->ANSI_OFF, '%C' => $this->ANSI_BLUE . $comment . $this->ANSI_OFF,
'%L' => $lineNumber, '%L' => $lineNumber,
]; );
} }
if ($this->outputFormat) { if ($this->outputFormat) {
@@ -582,18 +607,11 @@ class MalwareScanner
* - Fetch and load combined whitelist * - Fetch and load combined whitelist
* - Calls the process and report functions. * - Calls the process and report functions.
* *
* @param $dir * @param string|array $dir A directory path or a list of paths in array
* @return bool * @return bool
*/ */
public function run($dir) public function run($dir)
{ {
// Make sure the input is a valid directory path.
$dir = rtrim($dir, '/');
if (!is_dir($dir)) {
$this->error('Specified path is not a directory: ' . $dir);
return false;
}
$this->initializePatterns(); $this->initializePatterns();
$this->loadWhitelist(); $this->loadWhitelist();
@@ -603,8 +621,24 @@ class MalwareScanner
} }
$start = time(); $start = time();
$this->process($dir . '/');
$this->report($start, $dir . '/'); if (!is_array($dir)) {
$dir = array ($dir);
}
foreach ($dir as $path) {
// Make sure the input is a valid directory path.
$path = rtrim($path, '/');
if (!is_dir($path)) {
$this->error('Specified path is not a directory: ' . $path);
return false;
}
$this->process($path . '/');
}
if (!$this->flagDisableStats) {
$this->report($start, implode(', ', $dir));
}
return true; return true;
} }
@@ -757,7 +791,7 @@ class MalwareScanner
} }
$content = gzdecode(file_get_contents($file)); $content = gzdecode(file_get_contents($file));
$this->combined_whitelist = []; $this->combined_whitelist = array();
$this->combined_whitelist_count = 0; $this->combined_whitelist_count = 0;
foreach (explode("\n", $content) as $line) { // faster than strtok, but needs more memory foreach (explode("\n", $content) as $line) { // faster than strtok, but needs more memory
if ($line) { if ($line) {
@@ -795,6 +829,7 @@ class MalwareScanner
echo ' -o --output-format Custom defined output format' . PHP_EOL; echo ' -o --output-format Custom defined output format' . PHP_EOL;
echo ' -j --wordpress-version Version of wordpress to get md5 signatures' . PHP_EOL; echo ' -j --wordpress-version Version of wordpress to get md5 signatures' . PHP_EOL;
echo ' --combined-whitelist Combined whitelist' . PHP_EOL; echo ' --combined-whitelist Combined whitelist' . PHP_EOL;
echo ' --disable-stats Disable statistics output' . PHP_EOL;
} }

View File

@@ -15,7 +15,8 @@ function fetch($url, $file = false)
$headers = array( $headers = array(
// drupal suxx // drupal suxx
'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15', 'Cookie: _px2=eyJ1IjoiZDZhNGM3MjAtYjZmNC0xMWVhLWI2MzMtNzk5YzRmZjM4ZmJkIiwidiI6IjQ0ZTFiMDQwLTRkZGUtMTFlOC1iMWRjLWYxNWU4OTg1NTZjNyIsInQiOjE1OTMwOTc2Mjg2NzAsImgiOiIzNzk5N2RkYTU3ZTI1NGY0ZDM5MmRiMWExNWZhZjhjNTZkMmM5NTZkZDJiZWVkZGVlZDc1MThiNTE5MTFjYzgwIn0=; _ga=GA1.2.2042202377.1525247839; _gat=1; _gid=GA1.2.1034461360.1593095881; has_js=1; _pxff_fp=1; _pxff_rf=1; pxvid=44e1b040-4dde-11e8-b1dc-f15e898556c7',
'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15',
); );
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
@@ -89,7 +90,7 @@ function fetch_jquery($fp)
foreach ($m[1] as $k => $file) { foreach ($m[1] as $k => $file) {
if (!is_cached($file)) { if (!is_cached($file)) {
echo 'Downloading: ' . 'https://code.jquery.com/' . $file . PHP_EOL; echo 'Downloading: ' . 'https://code.jquery.com/' . $file . PHP_EOL;
$data = fetch('https://code.jquery.com/' . $file); $data = fetch('https://code.jquery.com/' . $file) . PHP_EOL;
if (base64_encode(hash('sha256', $data, true)) != $m[2][$k]) { if (base64_encode(hash('sha256', $data, true)) != $m[2][$k]) {
die('Hash mismatch' . PHP_EOL); die('Hash mismatch' . PHP_EOL);
} }
@@ -160,7 +161,7 @@ function fetch_typo3($fp)
continue; continue;
} }
$file = 'type3-' . $release->version . '.tar.gz'; $file = 'type3-' . $release->version . '.tar.gz';
fetch_archive($file, $release->url->tar, $release->checksums->tar->sha1, 'sha1'); fetch_archive($file, 'https://get.typo3.org' . $release->url->tar, $release->checksums->tar->sha1, 'sha1');
hash_archive($fp, $file); hash_archive($fp, $file);
} }
} }
@@ -184,38 +185,40 @@ function fetch_pagekit($fp)
} }
// Ignored releases are: alpha, beta, rc, dev // Ignored releases are: alpha, beta, rc, dev
function fetch_drupal($fp, $versions) function fetch_drupal($fp)
{ {
foreach ($versions as $version => $id) { echo 'Fetching Drupal ' . PHP_EOL;
echo 'Fetching Drupal ' . $version . PHP_EOL;
$page = 0; $page = 0;
$pages = false; $pages = false;
do { do {
$data = fetch('https://www.drupal.org/project/drupal/releases?api_version%5B%5D=' . $id . '&page=' .$page); $data = fetch('https://www.drupal.org/project/drupal/releases?page=' . $page);
// pagination init // pagination init
if ($pages === false && preg_match('/&amp;page=(\d+)">last »<\/a>/', $data, $m)) { if ($pages === false && preg_match('/\?page=(\d+)">last »<\/a>/', $data, $m)) {
$pages = $m[1]; $pages = $m[1];
}
preg_match_all(
'/<a href="(\/project\/drupal\/releases\/(\d\.\d\.\d))">drupal/i',
$data,
$m
);
foreach ($m[1] as $k => $ver_uri) {
$ver_data = fetch('https://www.drupal.org' . $ver_uri);
if (!preg_match('/<span class="field-content hash">([a-z0-9]+)<\/span>/i', $ver_data, $ver_m)) {
die('Missing hash info: ' . $m[2][$k]);
} }
$file = 'drupal-' . $m[2][$k] . '.tar.gz';
fetch_archive($file, 'https://ftp.drupal.org/files/projects/' . $file, $ver_m[1], 'md5');
hash_archive($fp, $file);
}
preg_match_all( if ($pages === false) {
'/data-th="Download">(.*?)<a href="(https:\/\/ftp\.drupal\.org\/files\/projects\/(drupal\-([0-9.]+)\.tar\.gz)).*?md5 hash">\s*([a-z0-9]{32})\s*<\/td>/is', break;
$data, }
$m $page++;
); } while ($page <= $pages);
foreach ($m[3] as $k => $file) {
fetch_archive($file, $m[2][$k], $m[5][$k], 'md5');
hash_archive($fp, $file);
}
if ($pages === false) {
break;
}
$page++;
}while($page <= $pages);
}
} }
function fetch_joomla($fp, $versions) function fetch_joomla($fp, $versions)
@@ -271,24 +274,7 @@ fetch_jquery($fp);
fetch_wordpress($fp); fetch_wordpress($fp);
fetch_typo3($fp); fetch_typo3($fp);
fetch_pagekit($fp); fetch_pagekit($fp);
fetch_drupal( fetch_drupal($fp);
$fp,
[
'9.x' => 39794,
'8.x' => 7234,
'7.x' => 103,
'6.x' => 87,
'5.x' => 78,
'4.7.x' => 79,
'4.6.x' => 80,
'4.5.x' => 81,
'4.4.x' => 82,
'4.3.x' => 83,
'4.2.x' => 84,
'4.1.x' => 85,
'4.0.x' => 86
]
);
fetch_joomla($fp, ['3.0' => 3, '2.5' => 25, '1.5' => 15, '1.0' => 10]); fetch_joomla($fp, ['3.0' => 3, '2.5' => 25, '1.5' => 15, '1.0' => 10]);
fclose($fp); fclose($fp);

View File

@@ -275,3 +275,6 @@ fc8f1e9f0ff666af7beb3f61b055c0e8 /core/model/smarty/sysplugins/smarty_internal_
bb127b5ce56b45e8b4b91de2e60dd9eb /assets/components/googleanalytics/js/mgr/libs/highcharts.js bb127b5ce56b45e8b4b91de2e60dd9eb /assets/components/googleanalytics/js/mgr/libs/highcharts.js
7d7958bb0a9438a8966807f9202d0bce /assets/components/tinymce/jscripts/tiny_mce/plugins/spellchecker/classes/PSpellShell.php 7d7958bb0a9438a8966807f9202d0bce /assets/components/tinymce/jscripts/tiny_mce/plugins/spellchecker/classes/PSpellShell.php
3ee0a4d8a06cedc0a56f29e8f351ef72 /pclzip-2-8-2/pclzip.lib.php 3ee0a4d8a06cedc0a56f29e8f351ef72 /pclzip-2-8-2/pclzip.lib.php
abfd2987afd1f66e3eed50bebbeb6750 /sucuri-scanner-1.8.24/src/base.lib.php
78477b67cb223e4504689fef33119884 /sucuri-scanner-1.8.24/src/sitecheck.lib.php
e48460f6ef0c911dc5ad558c57bfd52f /sucuri-scanner-1.8.24/src/integrity.lib.php