Comments on How To Find Outdated Wordpress Versions On Your Server To Reduce The Risk Of Being Hacked
How To Find Outdated Wordpress Versions On Your Server To Reduce The Risk Of Being Hacked Today we want to tell you how to find outdated Wordpress installations on your server. This can be of high risk, especially for shared hosting servers. Being attacked on massively used open source software like Wordpress is only a matter of time, once security exploits get published.
9 Comment(s)
Comments
To do this without php,
Nice script, but how to expand it to look for obsolete versions ?
Even before reading these comments I thought it would be less code in bash...
find / | grep "wp-includes/version.php" > wplist1
for f in $(cat /tmp/wplist1); do echo -n $f ;ver=$(grep "wp_version =" $f | cut -d\' -f2); echo -n " $ver"; if [[ "$ver" < "3.8.1" ]]; then echo " OLD"; fi; echo ''; done
And wrapped over more lines for readability:
find / | grep "wp-includes/version.php" > wplist1
for f in $(cat /tmp/wplist1); do
echo -n $f ;
ver=$(grep "wp_version =" $f | cut -d\' -f2);
echo -n " $ver";
if [[ "$ver" < "3.8.1" ]]; then
echo " OLD";
fi;
echo '';
done
LATEST_WORDPRESS=`curl -s http://api.wordpress.org/core/version-check/1.5/ | head -n 4 | tail -n 1`
find / | grep "wp-includes/version.php" > wplist1
for f in $(cat /tmp/wplist1); do
echo -n $f ;
ver=$(grep "wp_version =" $f | cut -d\' -f2);
echo -n " $ver";
if [[ "$ver" < "$LATEST_WORDPRESS" ]]; then
echo " OLD";
fi;
echo '';
done
Sorry, but this does not work!
E. g. if [[ "3.8.1" < "3.10.0" ]] would NOT be true.
Bash can only do string comparison and the string 3.10 is lower than the string 3.8!
So be cautious when using string for comparing numbers that are not of type int.
Change the if to:
if [[ ${ver//./} -lt ${LATEST_WORDPRESS//./} ]]; then
and it should work
Maybe you're intersted helping me at my small "BashUpdateChecker" project :)
https://github.com/ShrimpDev/BashUpdateChecker
I used some parts of your code, hope that's no problem :)
Thanks Croydon for a great script.
I've taken it a bit further and updated the script to automatically detect latest WordPress version by sending a HTTP HEAD request to http://wordpress.org/latest and parsing the Content-Disposition: attachment; filename=wordpress-A.B.C.tar.gz result as suggested at https://wordpress.org/support/topic/programmatically-check-latest-wp-release / http://www.stephen-scotter.net/computers/web-development/wordpress/how-to-check-wordpress-versions-on-your-server-are-up-to-date
Cheers
<?php /** * find outdated wordpress versions * (c) 2014 howtoforge.com (M. Cramer) <[email protected]> * Appended by Steve Scotter www.stephen-scotter.net */ 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(); /**/ function detech_latest_wordpress_version() { $pattern = "/Content-Disposition: attachment; filename=wordpress-(.*).tar.gz/"; $context = stream_context_create(array('http' =>array('method'=>'HEAD'))); $fd = fopen('http://wordpress.org/latest', 'rb', false, $context); $data = stream_get_meta_data($fd); fclose($fd); $WP_VERSION = ''; foreach ($data['wrapper_data'] as $key => $value) { if (preg_match($pattern, $value, $matches) == 1) { if (count($matches) == 2) { $WP_VERSION = $matches[1]; } } } return $WP_VERSION; } /* 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); } define('LATEST_VERSION', detech_latest_wordpress_version()); if (empty(LATEST_VERSION)) { die("Unable to detect latest version of WordPress available"); } else { print "[INFO] Latest version of wordpress detected as " . LATEST_VERSION . "\n"; } // 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"; ?>Tried it recently with PHP 7 (7.0.2) and it worked flawlessly. Good job!