15 Commits
1.0.0 ... 1.0.8

Author SHA1 Message Date
Gabor Gyorvari
5883c68f54 Small example how to use as library, fix #61 2020-10-05 13:34:16 +02:00
Gabor Gyorvari
22b51a1ee3 Change addWordpressChecksums to public, fix #58 2020-10-05 10:59:13 +02:00
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 142 additions and 77 deletions

View File

@@ -35,6 +35,7 @@ Usage: php scan.php -d <directory>
-o --output-format Custom defined output format
-j --wordpress-version Version of wordpress to get md5 signatures
--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.
@@ -112,6 +113,22 @@ It is guaranteed that IF 'base64_decode' was present in the plain text code, the
The presence of 'YmFzZTY0X2RlY29kZ' in a block of code may be because 'ase64_decod' was in the original code.
ote the missing edge characters which is due to bit misalignment and character bleed.
Using as library
----------------
The scan.php perform a check, that it's called by commandline or not, so to use as library use different directory than scan.php it self.
```php
<?php
require_once '../scan.php';
$scan = new MalwareScanner();
$scan->setFlagHideWhitelist(true);
$scan->setFlagHideOk(true);
$scan->run('../samples/test');
```
Resources
---------

View File

@@ -1,7 +1,7 @@
#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.
# 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.
#List of security service providers that phishers often block.
# List of security service providers that phishers often block.
abovenet
avira
bitdefender
@@ -17,3 +17,6 @@ phishtank
sophos
surfright
symantec
# SEO poison, pharmacy redirect
dealonline.su

View File

@@ -261,6 +261,14 @@ tmhapbzcerff
IndoXploit
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
uname -a
@@ -362,4 +370,8 @@ 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
# 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,}\)\);
#
# chr(101).chr(118).chr(97)
(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,}
#
@@ -37,6 +40,9 @@ Googlebot['"]{0,1}\s*\)\){echo\s+file_get_contents
#execute base64 code
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
@@ -107,4 +113,7 @@ function\s+_[0-9]{8,}\(
@include ".*?(\\x[0-9a-f]{2,}.*?){2,}.*?";
# 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 $flagScanEverything = false;
private $flagCombinedWhitelist = false;
private $flagDisableStats = false;
private $outputFormat = '';
private $whitelist = array();
private $ignore = array();
@@ -68,16 +69,31 @@ class MalwareScanner
if ($cli === true) {
//Read Run Options
$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.
if ($this->dir === '') {
if (empty($dirs)) {
$this->error('No directory specified or directory doesn\'t exist');
exit(-1);
}
//Initiate Scan
if (!$this->run($this->dir)) {
if (!$this->run($dirs)) {
exit(-1);
}
}
@@ -103,7 +119,7 @@ class MalwareScanner
}
//Handles pattern loading and saving to the class object
private function initializePatterns()
public function initializePatterns()
{
$dir = dirname(__FILE__);
//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
private function loadWhitelist()
public function loadWhitelist()
{
if (!is_file(__DIR__ . '/whitelist.txt')) {
return;
@@ -187,7 +203,7 @@ class MalwareScanner
}
}
private function addWordpressChecksums($wp_version)
public function addWordpressChecksums($wp_version)
{
$apiurl = 'https://api.wordpress.org/core/checksums/1.0/?version=' . $wp_version;
$json = json_decode(file_get_contents($apiurl));
@@ -230,7 +246,8 @@ class MalwareScanner
'output-format:',
'wordpress-version:',
'scan-everything',
'combined-whitelist'
'combined-whitelist',
'disable-stats'
)
);
@@ -313,6 +330,9 @@ class MalwareScanner
if (isset($options['combined-whitelist'])) {
$this->setFlagCombinedWhitelist(true);
}
if (isset($options['disable-stats'])) {
$this->setFlagDisableStats(true);
}
}
public function setExtensions(array $a)
@@ -401,6 +421,11 @@ class MalwareScanner
$this->flagCombinedWhitelist = $b;
}
public function setFlagDisableStats($b)
{
$this->flagDisableStats = $b;
}
// @see http://stackoverflow.com/a/13914119
private function pathMatches($path, $pattern, $ignoreCase = false)
{
@@ -501,7 +526,7 @@ class MalwareScanner
}
if ($this->outputFormat) {
$map = [
$map = array(
'%S' => $state,
'%T' => $ctime,
'%M' => $hash,
@@ -509,9 +534,9 @@ class MalwareScanner
'%P' => $pattern,
'%C' => $comment,
'%L' => $lineNumber,
];
);
} else {
$map = [
$map = array(
'%S' => $state_color . '# ' . $state . $this->ANSI_OFF,
'%T' => $this->ANSI_BLUE . $ctime . $this->ANSI_OFF,
'%M' => $this->ANSI_BLUE . $hash . $this->ANSI_OFF,
@@ -519,7 +544,7 @@ class MalwareScanner
'%P' => $state_color . '#' . $pattern . $this->ANSI_OFF,
'%C' => $this->ANSI_BLUE . $comment . $this->ANSI_OFF,
'%L' => $lineNumber,
];
);
}
if ($this->outputFormat) {
@@ -582,18 +607,11 @@ class MalwareScanner
* - Fetch and load combined whitelist
* - Calls the process and report functions.
*
* @param $dir
* @param string|array $dir A directory path or a list of paths in array
* @return bool
*/
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->loadWhitelist();
@@ -603,8 +621,24 @@ class MalwareScanner
}
$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;
}
@@ -757,7 +791,7 @@ class MalwareScanner
}
$content = gzdecode(file_get_contents($file));
$this->combined_whitelist = [];
$this->combined_whitelist = array();
$this->combined_whitelist_count = 0;
foreach (explode("\n", $content) as $line) { // faster than strtok, but needs more memory
if ($line) {
@@ -795,6 +829,7 @@ class MalwareScanner
echo ' -o --output-format Custom defined output format' . PHP_EOL;
echo ' -j --wordpress-version Version of wordpress to get md5 signatures' . 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(
// 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);
@@ -89,7 +90,7 @@ function fetch_jquery($fp)
foreach ($m[1] as $k => $file) {
if (!is_cached($file)) {
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]) {
die('Hash mismatch' . PHP_EOL);
}
@@ -160,7 +161,7 @@ function fetch_typo3($fp)
continue;
}
$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);
}
}
@@ -184,38 +185,40 @@ function fetch_pagekit($fp)
}
// Ignored releases are: alpha, beta, rc, dev
function fetch_drupal($fp, $versions)
function fetch_drupal($fp)
{
foreach ($versions as $version => $id) {
echo 'Fetching Drupal ' . $version . PHP_EOL;
echo 'Fetching Drupal ' . PHP_EOL;
$page = 0;
$pages = false;
do {
$data = fetch('https://www.drupal.org/project/drupal/releases?api_version%5B%5D=' . $id . '&page=' .$page);
$page = 0;
$pages = false;
do {
$data = fetch('https://www.drupal.org/project/drupal/releases?page=' . $page);
// pagination init
if ($pages === false && preg_match('/&amp;page=(\d+)">last »<\/a>/', $data, $m)) {
$pages = $m[1];
// pagination init
if ($pages === false && preg_match('/\?page=(\d+)">last »<\/a>/', $data, $m)) {
$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(
'/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',
$data,
$m
);
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);
}
if ($pages === false) {
break;
}
$page++;
} while ($page <= $pages);
}
function fetch_joomla($fp, $versions)
@@ -271,24 +274,7 @@ fetch_jquery($fp);
fetch_wordpress($fp);
fetch_typo3($fp);
fetch_pagekit($fp);
fetch_drupal(
$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_drupal($fp);
fetch_joomla($fp, ['3.0' => 3, '2.5' => 25, '1.5' => 15, '1.0' => 10]);
fclose($fp);

View File

@@ -275,3 +275,6 @@ fc8f1e9f0ff666af7beb3f61b055c0e8 /core/model/smarty/sysplugins/smarty_internal_
bb127b5ce56b45e8b4b91de2e60dd9eb /assets/components/googleanalytics/js/mgr/libs/highcharts.js
7d7958bb0a9438a8966807f9202d0bce /assets/components/tinymce/jscripts/tiny_mce/plugins/spellchecker/classes/PSpellShell.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