12 Commits

Author SHA1 Message Date
Gabor Gyorvari
34ea02323b New flag to specify custom white list file 2021-04-01 12:44:15 +02:00
Gabor Gyorvari
b74494a4f1 base64 sample for "file" too short and causes false positive 2021-02-26 13:27:58 +01:00
Gabor Gyorvari
9624ec4403 README update with new -r flag 2021-02-24 16:47:13 +01:00
Győrvári Gábor
335b13b7c4 Merge pull request #67 from mitchobrian/master
Feature flagHideErr #66
2021-02-24 16:45:34 +01:00
Michael Palmer
78bee49176 https://github.com/scr34m/php-malware-scanner/issues/66 2021-02-24 13:36:10 +01:00
Győrvári Gábor
cc0fdc7a9f Merge pull request #63 from aldavigdis/patch-1
Adding definitions based on recent code injection
2020-11-17 08:07:52 +01:00
Alda Vigdis Skarphedinsdottir
ec8f9920ba Adding definitions based on recent code injection 2020-11-17 04:06:03 +01:00
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
5 changed files with 125 additions and 38 deletions

View File

@@ -26,6 +26,7 @@ Usage: php scan.php -d <directory>
-x --extra-check Adds GoogleBot and htaccess to Scan List
-l --follow-symlink Follow symlinked directories
-k --hide-ok Hide results with 'OK' status
-r --hide-err Hide results with 'ER' status
-w --hide-whitelist Hide results with 'WL' status
-n --no-color Disable color mode
-s --no-stop Continue scanning file after first hit
@@ -35,6 +36,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
--custom-whitelist Loads whitelist from specified file and merge with existing
--disable-stats Disable statistics output
```
@@ -113,6 +115,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

@@ -108,11 +108,6 @@ SFRUUF9VU0VSX0FHRU5U
hUVFBfVVNFUl9BR0VOV
IVFRQX1VTRVJfQUdFTl
# "file" in base64
ZmlsZ
ZpbG
maWxl
# "gzinflate" in base64
Z3ppbmZsYXRl
d6aW5mbGF0Z
@@ -201,6 +196,7 @@ eval(base64_decode(
$data = base64_decode("
edoced_46esab
base=base64_encode
'b'.'ase6'.'4_e'.'ncode'
cr"."eat"."e_fun"."cti"."on
gz'.'inf'.'late
# fopo.com.ar - free online php obfuscator. It conveniently leaves comments in the code.
@@ -260,6 +256,9 @@ itsoknoproblembro
tmhapbzcerff
IndoXploit
FaisaL Ahmed aka rEd X
smisbot
smotherbot
Indonesian Hacker Rulez
# WP-VCD Malware https://www.getastra.com/blog/911/how-to-fix-wp-vcd-backdoor-hack-in-wordpress-functions-php/
wp-vcd
@@ -371,3 +370,7 @@ ZeroByte
# JS escaped: String.fromCharCode(
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,}

108
scan.php
View File

@@ -2,13 +2,13 @@
/*
* Copyright (c) 2016 Gabor Gyorvari
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -31,6 +31,7 @@ class MalwareScanner
private $flagChecksum = false;
private $flagComments = false;
private $flagHideOk = false;
private $flagHideErr = false;
private $flagHideWhitelist = false;
private $flagNoStop = false;
private $flagPattern = false;
@@ -41,6 +42,7 @@ class MalwareScanner
private $flagScanEverything = false;
private $flagCombinedWhitelist = false;
private $flagDisableStats = false;
private $customWhitelist = array();
private $outputFormat = '';
private $whitelist = array();
private $ignore = array();
@@ -69,16 +71,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);
}
}
@@ -175,20 +192,25 @@ class MalwareScanner
return $list;
}
//Loads the whitelist file
public function loadWhitelist()
/**
* Loads the whitelist files
*/
public function loadWhitelists()
{
if (!is_file(__DIR__ . '/whitelist.txt')) {
return;
}
$fp = fopen(__DIR__ . '/whitelist.txt', 'r');
while (!feof($fp)) {
$line = fgets($fp);
$this->whitelist[] = substr($line, 0, 32);
$a = array_merge([__DIR__ . '/whitelist.txt'], $this->customWhitelist);
foreach ($a as $file) {
if (is_file($file)) {
$fp = fopen($file, 'r');
while (!feof($fp)) {
$line = fgets($fp);
$this->whitelist[] = substr($line, 0, 32);
}
fclose($fp);
}
}
}
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));
@@ -232,6 +254,7 @@ class MalwareScanner
'wordpress-version:',
'scan-everything',
'combined-whitelist',
'custom-whitelist:',
'disable-stats'
)
);
@@ -283,6 +306,9 @@ class MalwareScanner
if (isset($options['hide-ok']) || isset($options['k'])) {
$this->setFlagHideOk(true);
}
if (isset($options['hide-err']) || isset($options['r'])) {
$this->setFlagHideErr(true);
}
if (isset($options['hide-whitelist']) || isset($options['w'])) {
$this->setFlagHideWhitelist(true);
}
@@ -315,6 +341,13 @@ class MalwareScanner
if (isset($options['combined-whitelist'])) {
$this->setFlagCombinedWhitelist(true);
}
if (isset($options['custom-whitelist'])) {
$a = $options['custom-whitelist'];
if (!is_array($a)) {
$a = array($a);
}
$this->setCustomWhitelist(array_unique($a));
}
if (isset($options['disable-stats'])) {
$this->setFlagDisableStats(true);
}
@@ -381,6 +414,11 @@ class MalwareScanner
$this->flagHideOk = $b;
}
public function setFlagHideErr($b)
{
$this->flagHideErr = $b;
}
public function setFlagHideWhitelist($b)
{
$this->flagHideWhitelist = $b;
@@ -411,6 +449,11 @@ class MalwareScanner
$this->flagDisableStats = $b;
}
public function setCustomWhitelist($a)
{
$this->customWhitelist = $a;
}
// @see http://stackoverflow.com/a/13914119
private function pathMatches($path, $pattern, $ignoreCase = false)
{
@@ -475,6 +518,9 @@ class MalwareScanner
$state = 'WL';
$state_color = $this->ANSI_YELLOW;
} else {
if ($this->flagHideErr) {
return;
}
$state = 'ER';
$state_color = $this->ANSI_RED;
}
@@ -592,30 +638,37 @@ 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();
$this->loadWhitelists();
if ($this->flagCombinedWhitelist && !$this->updateCombinedWhitelist()) {
return false;
}
$start = time();
$this->process($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, $dir . '/');
$this->report($start, implode(', ', $dir));
}
return true;
}
@@ -798,6 +851,7 @@ class MalwareScanner
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 results with \'OK\' status' . PHP_EOL;
echo ' -r --hide-err Hide results with \'ER\' status' . PHP_EOL;
echo ' -w --hide-whitelist Hide results with \'WL\' status' . PHP_EOL;
echo ' -n --no-color Disable color mode' . PHP_EOL;
echo ' -s --no-stop Continue scanning file after first hit' . PHP_EOL;