mirror of
https://github.com/scr34m/php-malware-scanner.git
synced 2026-06-16 12:30:35 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55e75079df | ||
|
|
c9e4050b7d | ||
|
|
31fa36c82a | ||
|
|
ba466dc1ff | ||
|
|
201ab77516 |
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.idea/
|
||||
whitelist.dat
|
||||
vendor/
|
||||
@@ -6,7 +6,7 @@
|
||||
"license": "GPL-3.0",
|
||||
"homepage": "https://github.com/scr34m/php-malware-scanner",
|
||||
"require": {
|
||||
"php": ">=5.2.0"
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"autoload": {
|
||||
},
|
||||
|
||||
@@ -25,6 +25,7 @@ ShellBOT
|
||||
".\x00..\x20"
|
||||
FM_SESSION_ID
|
||||
HACKED BY
|
||||
_Mybb
|
||||
|
||||
#Remote Code
|
||||
curl_get_from_webpage
|
||||
@@ -35,6 +36,9 @@ leafmailer.pw
|
||||
|
||||
#Base64 String Samples. Each plain text string should have 3 base64 equivalents
|
||||
|
||||
# https://
|
||||
aHR0cHM6Ly
|
||||
|
||||
# "shell" in base64
|
||||
c2hlbG
|
||||
NoZWxs
|
||||
@@ -184,15 +188,23 @@ RlZmluZ
|
||||
kZWZpbm
|
||||
|
||||
# Obfuscation related code
|
||||
'.'6'.'4'.'_'.'
|
||||
bas'.'e64_dec
|
||||
file'.'_put_co
|
||||
fil'.'e_ex
|
||||
Pz4=
|
||||
L3gvaQ==
|
||||
eval("?>
|
||||
eval('?>
|
||||
@eval(
|
||||
"base64_decode"
|
||||
='base'.(32*2).'_de'.'code'
|
||||
"p"."r"."e"."g"."_"
|
||||
WSOstripslashes
|
||||
\x73\x79\x73\x74\x65\x6d' /* case, dec/hex issue? */, // system
|
||||
\x70\x72\x65\x67\x5f\x72\x65\x70\x6c\x61\x63\x65' /* case, dec/hex issue? */, // preg_replace
|
||||
\x65\x78\x65\x63' /* dec/hex issue? */, // exec
|
||||
\x5f\x43\x4f\x4f\x4b\x49\x45
|
||||
\x73\x79\x73\x74\x65\x6d
|
||||
\x70\x72\x65\x67\x5f\x72\x65\x70\x6c\x61\x63\x65
|
||||
\x65\x78\x65\x63
|
||||
ev\x61l
|
||||
\x65\166\x61\154\x28' /* dec/hex issue? */,
|
||||
\x65\x76\x61\x6C' /* case, dec/hex issue? */,
|
||||
@@ -205,12 +217,12 @@ 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.
|
||||
http://www.fopo.com.ar/
|
||||
@eval("\
|
||||
";eval(
|
||||
eval(eval(
|
||||
@eval(`
|
||||
eVaL('?>
|
||||
eval($_REQUEST
|
||||
convert_uudecode(convert_uuencode
|
||||
"64_decode"
|
||||
'f' . 'il' . 'e' . '_'
|
||||
@@ -218,6 +230,9 @@ convert_uudecode(convert_uuencode
|
||||
'h' . 'tm' . 'l' . 'sp'
|
||||
'ha' . 'r' . 's'
|
||||
|
||||
# fopo.com.ar - free online php obfuscator. It conveniently leaves comments in the code.
|
||||
http://www.fopo.com.ar/
|
||||
|
||||
#Malware/Attack specific strings/fingerprints/signatures
|
||||
MagelangCyber
|
||||
//rasta//
|
||||
@@ -397,6 +412,7 @@ ZeroByte
|
||||
# SEO poisoning control site call
|
||||
"http://$xxx
|
||||
?useragent=$botbotbot
|
||||
[#*#*#]
|
||||
|
||||
# php://input encoded in base64
|
||||
cGhwOi8vaW5wdXQ=
|
||||
|
||||
@@ -146,6 +146,8 @@ eval\([A-Za-z0-9]{5,}\(\) \. '
|
||||
# eval function return, parameter is a hex string
|
||||
eval\([A-Za-z0-9]{5,}\(\"[A-Z0-9]{16,}
|
||||
|
||||
eval\(\s+'\?>'
|
||||
|
||||
# gzip payload called by variable named function
|
||||
\$[a-zA-Z0-9]{6,}\('\x78\x9C\xAD\x90\x41\x0E
|
||||
|
||||
@@ -159,4 +161,7 @@ return @\$[a-z]{2}\d+\[\d+\]\(\$[a-z]{2}\d+\[\d+\],
|
||||
|
||||
# JS - escaped command
|
||||
\.fromCharCode\([0-9,]{4,}\)
|
||||
\+-parseInt\(\w\('0x[0-9a-z]+'\)\)\/
|
||||
\+-parseInt\(\w\('0x[0-9a-z]+'\)\)\/
|
||||
|
||||
# concated hash value
|
||||
('[a-z0-9]{2,}'\.){4,}
|
||||
|
||||
54
scan.php
54
scan.php
@@ -203,7 +203,10 @@ class MalwareScanner
|
||||
$fp = fopen($file, 'r');
|
||||
while (!feof($fp)) {
|
||||
$line = fgets($fp);
|
||||
$this->whitelist[] = substr($line, 0, 32);
|
||||
$hash = substr($line, 0, 32);
|
||||
if (strlen($hash) === 32) {
|
||||
$this->whitelist[] = $hash;
|
||||
}
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
@@ -212,16 +215,32 @@ class MalwareScanner
|
||||
|
||||
public function addWordpressChecksums($wp_version)
|
||||
{
|
||||
$apiurl = 'https://api.wordpress.org/core/checksums/1.0/?version=' . $wp_version;
|
||||
$json = json_decode(file_get_contents($apiurl));
|
||||
$checksums = $json->checksums;
|
||||
if (!preg_match('/^\d+\.\d+(\.\d+)?$/', $wp_version)) {
|
||||
$this->error('Invalid WordPress version format: ' . $wp_version);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ($checksums->$wp_version == false) { #no checksum returned
|
||||
$apiurl = 'https://api.wordpress.org/core/checksums/1.0/?version=' . $wp_version;
|
||||
$raw = file_get_contents($apiurl);
|
||||
if ($raw === false) {
|
||||
$this->error('Cannot load wordpress checksums from: ' . $apiurl);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
foreach ($checksums->$wp_version as $file => $checksum) {
|
||||
$json = json_decode($raw);
|
||||
if ($json === null || !isset($json->checksums)) {
|
||||
$this->error('Invalid response from WordPress checksums API');
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
$checksums = $json->checksums;
|
||||
if ($checksums === false || empty((array)$checksums)) {
|
||||
$this->error('No checksums returned for WordPress version: ' . $wp_version);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
$entries = isset($checksums->$wp_version) ? $checksums->$wp_version : $checksums;
|
||||
foreach ($entries as $file => $checksum) {
|
||||
$this->whitelist[] = $checksum;
|
||||
}
|
||||
}
|
||||
@@ -623,8 +642,8 @@ class MalwareScanner
|
||||
private function report($start, $dir)
|
||||
{
|
||||
$end = time();
|
||||
echo 'Start time: ' . date('Y-m-d H:m:s', $start) . PHP_EOL;
|
||||
echo 'End time: ' . date('Y-m-d H:m:s', $end) . PHP_EOL;
|
||||
echo 'Start time: ' . date('Y-m-d H:i:s', $start) . PHP_EOL;
|
||||
echo 'End time: ' . date('Y-m-d H:i:s', $end) . PHP_EOL;
|
||||
echo 'Total execution time: ' . ($end - $start) . PHP_EOL;
|
||||
echo 'Base directory: ' . $dir . PHP_EOL;
|
||||
echo 'Total directories scanned: ' . $this->stat['directories'] . PHP_EOL;
|
||||
@@ -680,6 +699,12 @@ class MalwareScanner
|
||||
{
|
||||
$this->stat['files_scanned']++;
|
||||
$fileContent = file_get_contents($path);
|
||||
if ($fileContent === false) {
|
||||
if (!$this->flagHideErr) {
|
||||
echo $this->ANSI_RED . '# ER' . $this->ANSI_OFF . ' # {' . $path . '} (unreadable)' . PHP_EOL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
$found = false;
|
||||
$inWhitelist = false;
|
||||
$hash = md5($fileContent);
|
||||
@@ -725,7 +750,10 @@ class MalwareScanner
|
||||
//Patterns will match multiple lines, though you can use ^$ to match the beginning and end of a line.
|
||||
private function scanFunc_RE(&$pattern, &$content)
|
||||
{
|
||||
$ret = preg_match('/' . $pattern . '/im', $content, $match, PREG_OFFSET_CAPTURE);
|
||||
$ret = @preg_match('/' . $pattern . '/im', $content, $match, PREG_OFFSET_CAPTURE);
|
||||
if ($ret === false) {
|
||||
return false;
|
||||
}
|
||||
if ($ret) {
|
||||
return $match[0][1];
|
||||
}
|
||||
@@ -790,11 +818,14 @@ class MalwareScanner
|
||||
|
||||
private function updateCombinedWhitelist($url = 'https://scr34m.github.io/php-malware-scanner')
|
||||
{
|
||||
$latest_hash = trim(file_get_contents($url . '/database/compressed.sha256'));
|
||||
$ctx = stream_context_create(array('http' => array('timeout' => 30)));
|
||||
|
||||
$latest_hash = file_get_contents($url . '/database/compressed.sha256', false, $ctx);
|
||||
if ($latest_hash === false) {
|
||||
$this->error('Unable to download database checksum');
|
||||
return false;
|
||||
}
|
||||
$latest_hash = trim($latest_hash);
|
||||
|
||||
$file = __DIR__ . '/whitelist.dat';
|
||||
if (is_readable($file)) {
|
||||
@@ -809,7 +840,7 @@ class MalwareScanner
|
||||
}
|
||||
|
||||
if ($download) {
|
||||
$data = file_get_contents($url . '/database/compressed.dat');
|
||||
$data = file_get_contents($url . '/database/compressed.dat', false, $ctx);
|
||||
if ($data === false) {
|
||||
$this->error('Unable to download database');
|
||||
return false;
|
||||
@@ -819,6 +850,7 @@ class MalwareScanner
|
||||
$hash = hash_file('sha256', $file);
|
||||
if ($hash != $latest_hash) {
|
||||
$this->error('Downloaded database hash mismatch');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user