Skip to main content.

Fri, 01 Jan 2010

Detecting stale versions of WordPress

I run a personal server that hosts web space for a few friends. Probably the most popular thing to do with the space is to install WordPress and run a personal blog.

A few days ago, I discovered some attackers were abusing one of the sites. Once we upgraded the site to the latest version of WordPress, the attack went away. So I wrote a tool that, every night, emails me a report of the locations of old versions of WordPress. A sample email:

Current version of WordPress: 2.9

oldroommate has WordPress 2.5 in /home/oldroommate/web/oldroommate.com/

Eek! WordPress 2.5 is old!

How it works

Each time it runs, it looks at wordpress.org to see what the current version is. The code to do that is written in Python and uses lxml.html. It prints the current version in the report, and it uses it when analyzing WordPress installs.

To analyze WordPress installs, it executes locate readme.html, looking for WordPress's tell-tale documentation file. For every such readme.html, if it matches a simple regular expression suggesting it's a WordPress readme file, it performs the following analysis:

If it found any installs of old WordPress, it prints a report like the one blockquoted above to stdout.

How to use it

To get emails, I run it with cron. You can add a stanza like this to your crontab (edit it with crontab -e):

@daily cd find-out-of-date-wordpress; ./look.sh

Ta-da, nightly reports.

To get a copy

Do a git clone:

git clone git://git.asheesh.org/find-out-of-date-wordpress.git

or browse its gitweb.

Feedback

I'm quite interested to hear what others do to avoid old web apps being attacked. If there's another bit of software that monitors web apps for needing upgrades, I'd love to hear about it! Obviously if you have feedback on this tidbit I wrote, let me know.

(To me, apt-get doesn't seem to be the answer. Web apps (especially PHP ones) don't usually seem to support keeping the code in one place with multiple different configuration files. And users get excited about the latest and greatest and don't want to wait for me to upgrade, and I can't blame them.)

If some of you don't like the Python dependency or anything else, I do welcome patches!

[] permanent link and comments

The idea of this is good, and I've done something similar in the past.  However my approach was slightly different. I assume that the only reason wordpress will end up installed upon my host(s) is if I do it manually - so I don't need to use "locate" to find rogue installations.

Instead I start from the premise:  " I have wordpress installed on blog.example.com, and blog.example.net - are they current?".

That question is more easily solved, and you might find the switch in mindset useful.

For example I can reliably poll the version of a remote wordpress installation by looking at the "generator" attribute of the RSS feed.

skx@gold:~$ wget -q -O- http://blog.larskjensen.dk/feed/  | grep gener
<generator>http://wordpress.org/?v=2.7</generator>

Obviously to do this you need to know where the feed is installed, but that's pretty simple.  For example.com you can get the RSS link with:


http://example.com/index.php?feed=rss
Using that method is much cleaner than poking around with random regexps IMHO.

Posted by Steve Kemp at Sat Jan 2 10:51:13 2010

Steve, thanks for this!

Yeah, I'd do it that way if these weren't, as you say, "rogue" installs made by users. I'd rather discover these myself than be surprised by attackers.

What I want to move to is fingerprinting the WordPress installs by keeping SHA1 sums of these readme.html instead. But that's for another day. (-:

Posted by Asheesh Laroia at Sat Jan 2 13:31:04 2010

Thank you, I needed this.

Now we only need one for gallery2, phpbb, typo3, drupal... cough.

Posted by Seegras at Wed Jan 6 09:26:23 2010

Comment form

  • The following HTML is supported: <a href>, <em>, <i>, <b>, <blockquote>, <br/>, <p>, <abbr>, <acronym>, <big>, <cite>, <code>, <dfn>, <kbd>, <pre>, <small> <strong>, <sub>, <sup>, <tt>, <var>
  • I do not display your email address. It is for my personal use only.

Name: 
Your email address: 
Your website: 
 
Comment: