mirror of
https://github.com/scr34m/php-malware-scanner.git
synced 2026-06-16 12:30:35 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1b8b89ca5 | ||
|
|
c6a52dc67e | ||
|
|
3b76a7270e | ||
|
|
f0bdb1f1e1 | ||
|
|
43876b337b | ||
|
|
1fad164790 | ||
|
|
f4d53e89d8 | ||
|
|
34ea02323b | ||
|
|
b74494a4f1 | ||
|
|
9624ec4403 | ||
|
|
335b13b7c4 | ||
|
|
78bee49176 | ||
|
|
cc0fdc7a9f | ||
|
|
ec8f9920ba | ||
|
|
5883c68f54 | ||
|
|
22b51a1ee3 | ||
|
|
2b1a0c1266 | ||
|
|
c495cc822c | ||
|
|
e9a45d4bdc | ||
|
|
21185202f3 | ||
|
|
195717d625 | ||
|
|
2973e55871 | ||
|
|
8b1994956e | ||
|
|
46faa31c74 | ||
|
|
d67a865bf0 |
18
README.md
18
README.md
@@ -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
|
||||
---------
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -108,11 +108,6 @@ SFRUUF9VU0VSX0FHRU5U
|
||||
hUVFBfVVNFUl9BR0VOV
|
||||
IVFRQX1VTRVJfQUdFTl
|
||||
|
||||
# "file" in base64
|
||||
ZmlsZ
|
||||
ZpbG
|
||||
maWxl
|
||||
|
||||
# "gzinflate" in base64
|
||||
Z3ppbmZsYXRl
|
||||
d6aW5mbGF0Z
|
||||
@@ -185,6 +180,7 @@ kZWZpbm
|
||||
|
||||
# Obfuscation related code
|
||||
eval("?>
|
||||
eval('?>
|
||||
"base64_decode"
|
||||
='base'.(32*2).'_de'.'code'
|
||||
"p"."r"."e"."g"."_"
|
||||
@@ -201,11 +197,14 @@ 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.
|
||||
http://www.fopo.com.ar/
|
||||
@eval("\
|
||||
";eval(
|
||||
eval(eval(
|
||||
|
||||
#Malware/Attack specific strings/fingerprints/signatures
|
||||
MagelangCyber
|
||||
@@ -260,6 +259,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 +373,17 @@ 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
|
||||
|
||||
# php://input encoded in base64
|
||||
cGhwOi8vaW5wdXQ=
|
||||
|
||||
# backdoor script
|
||||
<font color="red">Upload Gagal..</font><br />
|
||||
explode('?>',$shell
|
||||
|
||||
# common mobile agent check in SEO poison scripts
|
||||
Array("1207", "3gso", "4thp", "501i", "502i", "503i", "504i", "505i", "506i",
|
||||
@@ -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,29 @@ 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,}
|
||||
|
||||
# ${$O{18}.$O{7}.$O{24}.$O{2}.$O{50}.$O{8}
|
||||
(\$[A-Z]+\{\d+\}\.){3,}
|
||||
|
||||
# comment in variable name $_REQUEST /*YUsrqpbzvXTSa...QpDNTPYQvLSFPCqsSnWNVqPdSIAYaQj*/[
|
||||
\$_REQUEST\s*\/\*[A-Za-z]+\*\/\[
|
||||
|
||||
# cookie payload if(isset($_COOKIE)){$p=$_COOKIE;(count($p)==55&&in_array(gettype($p).count($p),$p))?(($p[68]=$p[68].$p[22])&&($p[35]=$p[68]($p[35]))&&($p=$p[35]($p[13],$p[68]($p[45])))&&$p()):$p;}
|
||||
\(count\(\$p\)==\d+&&in_array\(gettype\(\$p\)\.count\(\$p\),\$p\)\)
|
||||
|
||||
# gzipped payload post process
|
||||
explode\('\|\x01\|\x03\|\x03', gzinflate\(
|
||||
|
||||
# backdoor reported #71
|
||||
@header\(\w{3,5}::\w{1,2}\('_\w{1,3}' \. '\w{1,3}', '_\w{1,3}'\)\);
|
||||
@header\(\w{3,5}::\w{1,2}\('_\w{1,3}', '_' \. '\w{1,3}' . '\w{1,3}'\)\);
|
||||
|
||||
# backdoor reported #72
|
||||
@\$[a-z]{1}\[\d+\]\(\$[a-z]{1}\[\d+\]\);
|
||||
|
||||
# reported #77
|
||||
\$[a-z]11 \^ [a-z]8\(\$[a-z]6, \$[a-z]14, \$[a-z]6\[13\]\(\$[a-z]11\)\)\)\);
|
||||
120
scan.php
120
scan.php
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -104,7 +121,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,20 +192,25 @@ class MalwareScanner
|
||||
return $list;
|
||||
}
|
||||
|
||||
//Loads the whitelist file
|
||||
private 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;
|
||||
}
|
||||
@@ -511,7 +557,7 @@ class MalwareScanner
|
||||
}
|
||||
|
||||
if ($this->outputFormat) {
|
||||
$map = [
|
||||
$map = array(
|
||||
'%S' => $state,
|
||||
'%T' => $ctime,
|
||||
'%M' => $hash,
|
||||
@@ -519,9 +565,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,
|
||||
@@ -529,7 +575,7 @@ class MalwareScanner
|
||||
'%P' => $state_color . '#' . $pattern . $this->ANSI_OFF,
|
||||
'%C' => $this->ANSI_BLUE . $comment . $this->ANSI_OFF,
|
||||
'%L' => $lineNumber,
|
||||
];
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->outputFormat) {
|
||||
@@ -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;
|
||||
}
|
||||
@@ -769,7 +822,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) {
|
||||
@@ -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;
|
||||
|
||||
@@ -15,8 +15,8 @@ function fetch($url, $file = false)
|
||||
|
||||
$headers = array(
|
||||
// drupal suxx
|
||||
'Cookie: pxvid=44e1b040-4dde-11e8-b1dc-f15e898556c7; _ga=GA1.2.2042202377.1525247839; _gat=1; _gid=GA1.2.1601332121.1550831838; _px2=eyJ1IjoiZDM3OTk1MDAtMzY4ZC0xMWU5LWI3MDItYTdlMDI1ZWZhZmI2IiwidiI6IjQ0ZTFiMDQwLTRkZGUtMTFlOC1iMWRjLWYxNWU4OTg1NTZjNyIsInQiOjE1NTA4MzIxMzc5MjcsImgiOiJjMjBhNTQzNGIxYWQwNWFiOWUzNTI2OWRjNTM1MjgzNjkxNzg5OTIxNGM4YmIzZDBkZTg5ZTIxMzY0NTc5Zjk3In0=; has_js=1; _pxvid=44e1b040-4dde-11e8-b1dc-f15e898556c7',
|
||||
'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);
|
||||
|
||||
@@ -161,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);
|
||||
}
|
||||
}
|
||||
@@ -185,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('/&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)
|
||||
@@ -272,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);
|
||||
|
||||
@@ -256,22 +256,31 @@ e45b8afd0b65516c175ed23f7183bab1 /jquery-migrate-1.1.1.min.js
|
||||
dc0102c151c491b8a0f65a520e26e083 /jquery-migrate-1.1.0.min.js
|
||||
1f5980833a26b490296db71951e1024f /jquery-migrate-1.0.0.js
|
||||
dd6f8586a1afae562493e9c7cd1ffeea /jquery-migrate-1.0.0.min.js
|
||||
f2fc939d607b2e861af2701a15d14430 /ace/ace.min.js
|
||||
2954b8d06fd846e81c12b0fd0b3d2d35 /ace/ace/ace.js
|
||||
c333e22e892cd099e776e9384bbbaa63 /ace/ace/ext-beautify.js
|
||||
b391899e17b7aea2cf2998656c40f2c6 /core/components/phpthumbof/model/aws/_compatibility_test/sdk_compatibility_test.php
|
||||
6cfb5a3b2820fe378b73c901ee6fc031 /core/components/phpthumbof/model/aws/sdk.class.php
|
||||
dd894a093463d38f9c9fdbcb7c88cc23 /core/model/aws/sdk.class.php
|
||||
1ed9b9eea82c9f1ead337b67c188206b /core/model/phpthumb/phpthumb.class.php
|
||||
ef55bdc338994e87b650e2cf0f87df45 /core/model/smarty/sysplugins/smarty_internal_template.php
|
||||
f8f2e883e5323ed5935f42b17ceda6ba /core/model/smarty/sysplugins/smarty_template_compiled.php
|
||||
3d84a338c9daaacc711834cb7797ac98 /core/model/smarty/sysplugins/smarty_cacheresource_custom.php
|
||||
d6be1074d266aecb739352150798d97d /core/model/smarty/sysplugins/smarty_cacheresource_keyvaluestore.php
|
||||
c363512229135b182006a97ba43d31e7 /core/model/smarty/sysplugins/smarty_resource_recompiled.php
|
||||
fc8f1e9f0ff666af7beb3f61b055c0e8 /core/model/smarty/sysplugins/smarty_internal_cacheresource_file.php
|
||||
092a5a658bf49a3c1549f9bd809218ea /core/xpdo/compression/pclzip.lib.php
|
||||
761f1578928050a03f4aa4c789f1d136 /manager/assets/fileapi/FileAPI.js
|
||||
3c9137d88a00b1ae0b41ff6a70571615 /assets/components/tinymcewrapper/frontend/imogen_theme/js/jquery.js
|
||||
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
|
||||
f2fc939d607b2e861af2701a15d14430 /ace/ace.min.js
|
||||
2954b8d06fd846e81c12b0fd0b3d2d35 /ace/ace/ace.js
|
||||
c333e22e892cd099e776e9384bbbaa63 /ace/ace/ext-beautify.js
|
||||
b391899e17b7aea2cf2998656c40f2c6 /core/components/phpthumbof/model/aws/_compatibility_test/sdk_compatibility_test.php
|
||||
6cfb5a3b2820fe378b73c901ee6fc031 /core/components/phpthumbof/model/aws/sdk.class.php
|
||||
dd894a093463d38f9c9fdbcb7c88cc23 /core/model/aws/sdk.class.php
|
||||
1ed9b9eea82c9f1ead337b67c188206b /core/model/phpthumb/phpthumb.class.php
|
||||
ef55bdc338994e87b650e2cf0f87df45 /core/model/smarty/sysplugins/smarty_internal_template.php
|
||||
f8f2e883e5323ed5935f42b17ceda6ba /core/model/smarty/sysplugins/smarty_template_compiled.php
|
||||
3d84a338c9daaacc711834cb7797ac98 /core/model/smarty/sysplugins/smarty_cacheresource_custom.php
|
||||
d6be1074d266aecb739352150798d97d /core/model/smarty/sysplugins/smarty_cacheresource_keyvaluestore.php
|
||||
c363512229135b182006a97ba43d31e7 /core/model/smarty/sysplugins/smarty_resource_recompiled.php
|
||||
fc8f1e9f0ff666af7beb3f61b055c0e8 /core/model/smarty/sysplugins/smarty_internal_cacheresource_file.php
|
||||
092a5a658bf49a3c1549f9bd809218ea /core/xpdo/compression/pclzip.lib.php
|
||||
761f1578928050a03f4aa4c789f1d136 /manager/assets/fileapi/FileAPI.js
|
||||
3c9137d88a00b1ae0b41ff6a70571615 /assets/components/tinymcewrapper/frontend/imogen_theme/js/jquery.js
|
||||
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
|
||||
29f34168b7384cca58ba64885461e115 wp-admin/includes/class-pclzip.php -> Wordpress Core 6.0
|
||||
a54895edc1402cf1b7b5ecd3f5d85e6b wp-includes/formatting.php -> Wordpress Core 6.0
|
||||
178f2fbc6a48f605ed84b156103d5366 wp-content/plugins/wordpress-seo/vendor_prefixed/guzzlehttp/guzzle/src/Middleware.php -> Yoast SEO plugin 19.2
|
||||
1e2d246c57d2123aa8938c8263cb1d3d wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-server-data.php -> Yoast SEO plugin 19.2
|
||||
cacb5670ebb2de31976a4b2eb06cac86 wp-content/plugins/worker/src/MWP/ServiceContainer/Abstract.php -> managewp plugin 4.9.14 from managewp.com
|
||||
ffa76b9ff298702a733747521cfdee69 wp-content/plugins/worker/src/MWP/Action/GetState.php -> managewp plugin 4.9.14 from managewp.com
|
||||
|
||||
Reference in New Issue
Block a user