11 Commits
1.0.0 ... 1.0.6

Author SHA1 Message Date
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
5 changed files with 103 additions and 70 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

@@ -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
@@ -362,4 +370,4 @@ ZeroByte
100, 111, 99, 117, 109, 101, 110, 116, 46, 99, 114, 101, 97, 116, 101, 69, 108, 101, 109, 101, 110, 116, 40, 39, 115, 99, 114, 105, 112, 116, 39, 41, 59 100, 111, 99, 117, 109, 101, 110, 116, 46, 99, 114, 101, 97, 116, 101, 69, 108, 101, 109, 101, 110, 116, 40, 39, 115, 99, 114, 105, 112, 116, 39, 41, 59
# 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

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