19 Jun

Authenticated Local File Inclusion (LFI) Vulnerability in ChimpMate

In seeking to continue to improve our Plugin Security Checker, which does automated checks to try spot potential security issues in WordPress plugins, we log the results of checks of plugins in the Plugin Directory. The plugin ChimpMate was recently run through that and one of the issues identified in that was a possible local file inclusion vulnerability:

Since the check for that issue is based on a fairly limited number of previously identified vulnerabilities we decided to check on that to see if what was flagged was correctly identified.

For someone with the necessary knowledge to review possible security issues more closely they can use the Developer Mode of the tool, which is available to customers of our service, to see the details of what lead to the tool warning of the possible issue. What was shown was this:

In both of the instances shown there, user input is used to include a file through the function include_once(), in the first instance the user input is directly used and in the second it used through a variable. Those both would be accurate identifications of a possible issue.

When then decided to take a look to see if there was a vulnerability caused by either of those.

The first instance was located in the function preview() in the file /admin/class-chimpmate-wpmc-assistant-admin.php and looked like this:

219
220
221
222
223
public function preview(){
	if(!isset($_GET['type']) || !isset($_GET['theme']))die();
	include_once( 'includes/'.$_GET['type'].$_GET['theme'].'.php' );
	die();
}

That code simply checks if the GET inputs “type” and “theme” exist and if they do, it uses those with the include_once() function.

That function is accessible to anyone logged in to WordPress through its AJAX functionally:

52
add_action('wp_ajax_chimpmate_prev', array( $this, 'preview' ) );

That means there is authenticated local file inclusion vulnerability, which could allow an attacker who is able to log in to WordPress to cause any .php file on the website to be run. Through cross-site request forgery (CSRF) it would also be possible for an attacker to cause anyone logged in to WordPress do the same thing.

The second instance identified by the tool could be exploited in the same way.

We notified the developer of the issue a week ago. We haven’t heard back from them and no new version has been released to fix the issue. 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 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=chimpmate_prev&type=../../../../../&theme=test

Timeline

  • June 11,2018 – Developer notified.
12 Jun

Privilege Escalation Vulnerability in Quttera Web Malware Scanner

One of the big problems we see in trying to improve security is that so often security companies are promoting product and services that they claim will protect websites, but really only try to deal with the after effects of them being hacked. What seems like could explain a lot of that is that most of those companies don’t know or care about security and they are just trying to make a buck with little to no concern whether they are providing anything of value in exchange for that money. One of the things that seems to back that up is how often security companies fail to handle basic security when it comes to their own websites and product/services.

The latest example of that was something we ran across while discussing an example of security companies’ frequent misleading to outright false claims made about their products and services. As discussed over at our main blog the makers of the plugin Quttera Web Malware Scanner had recently claimed that the plugin had over 400,000 installations despite it actually only having 10,000+ active install according to wordpress.org. After running across that we started to take a quick look at the plugin’s security and immediately found it was failing to take some basic security measures.

The plugin makes a number of functions available through WordPress’ AJAX functionality to anyone logged in to WordPress:

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
add_action( 'wp_ajax_scanner-run_scan', 'CQtrAjaxHandler::RunExternalScan' );
 
 
/*
 * setup action @scanner-run_internal_scan mapped to callback qtr_wm_scanner_ajax_run_internal_scan
 * wp_ajax_ prefix used only for logged in users
 */ 
add_action( 'wp_ajax_scanner-run_internal_scan', 'CQtrAjaxHandler::RunInternalScan' );
 
add_action( 'wp_ajax_scanner-is_internal_scan_running', 'CQtrAjaxHandler::IsInternalScanNowRunning' );
 
add_action( 'wp_ajax_scanner-get_log_lines', 'CQtrAjaxHandler::GetLogLines' );
 
add_action( 'wp_ajax_scanner-clean_log', 'CQtrAjaxHandler::CleanLogLines' );
 
add_action( 'wp_ajax_scanner-get_stats', 'CQtrAjaxHandler::GetStats' );
 
add_action( 'wp_ajax_scanner-stop_internal_scan', 'CQtrAjaxHandler::StopInternalScan' );
 
add_action( 'wp_ajax_scanner-get_detected_threats', 'CQtrAjaxHandler::GetDetectedThreatsReport' );
 
add_action( 'wp_ajax_scanner-get_ignored_threats', 'CQtrAjaxHandler::GetIgnoredThreatsReport' );
 
add_action( 'wp_ajax_scanner-ignore_threat', 'CQtrAjaxHandler::IgnoreThreat' );
 
add_action( 'wp_ajax_scanner-get_file_report', 'CQtrAjaxHandler::ScannerReport' );
 
/* 
 * return threat back to report
 */
add_action( 'wp_ajax_scanner-unignore_threat', 'CQtrAjaxHandler::RemoveFromIgnoreList' );
 
add_action( 'wp_ajax_scanner-clean_ignore_list', 'CQtrAjaxHandler::CleanIgnoreList');
 
add_action( 'wp_ajax_scanner-whitelist_threat','CQtrAjaxHandler::WhiteListThreat' );
 
add_action( 'wp_ajax_scanner-clean_threats_whitelist', 'CQtrAjaxHandler::CleanThreatsWhiteList');
 
add_action( 'wp_ajax_scanner-whitelist_file', 'CQtrAjaxHandler::WhiteListFile');
 
add_action( 'wp_ajax_scanner-clean_files_whitelist', 'CQtrAjaxHandler::CleanFilesWhiteList');

The plugin’s admin pages, where at least most of those are intended to be accessed from, is only accessible to those with the “activate_plugins” capability, which would normally be only Administrator-level users. So there should be a check to make sure that users requesting those have that capability.

The first of the functions RunExternalScan() was restricted to those with the “manage_options” capability, which is also normally a capability only Administrator-level users have:

32
33
34
35
36
37
public static function RunExternalScan()
{
	if(!current_user_can('manage_options'))
	{
		wp_die(__('You do not have sufficient permissions to access this page.') );
	}

But that was missing from other functions. For example the GetLogLines() contains no check, so anyone logged in to WordPress could access it:

237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
public static function GetLogLines()
{
	$index  = 0;
	$logger = new CQtrLogger();
 
	if( isset( $_GET['start_line']) ) 
	{
		$index = intval( $_GET['start_line']);
	}
 
	else if( isset( $_POST['start_line']) ) 
	{
		$index = intval( $_POST['start_line']);
	}
 
 
	// $lines = $logger->GetFromLine($index);
	$lines = $logger->GetAllLines();
	echo json_encode($lines);
	exit();
}

In that case of that function, it would lead to a full path disclosure since it will display the full path to files that have been scanned.

What also was missing in all the functions we looked at was protection against cross-site request forgery (CSRF), so an attacker could cause someone logged in to WordPress to access the various functions without intending it.

After we notified the developer they released version 3.0.9.1, which partially resolves this.

The new version introduces a function __can_access() that ends the running of the code using exit() if the user doesn’t have the “manage_options” capability:

32
33
34
35
36
private static function __can_access(){
	if(!current_user_can('manage_options')){
		wp_die(__('You do not have sufficient permissions to access this page.') );
	}
}

That function is called first when those AJAX accessible functions mentioned above are run. Here, for example, is that with GetLogLines():

231
232
233
public static function GetLogLines()
{
	self::__can_access();

There still is a lack of protection against CSRF.

Proof of Concept

The following proof of concept will show the last few log lines from the plugin’s scanner, 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=scanner-get_log_lines

Timeline

  • June 7, 2018 – Developer notified.
  • June 7, 2018 – Developer responds.
  • June 8, 2018 – Version 3.0.9.1 released, which partially fixes the issue.
04 Jun

Trying To Determine If WordPress Plugins Are Being Exploited Is Harder When Hackers Do Odd Things

One of the things that we do to make sure our customer are getting the best protection against vulnerabilities in WordPress plugins is to do monitoring to try to spot when hackers are looking to exploit vulnerabilities in those plugins. In doing that we have found that other security companies that make extraordinary claims about protection they provide don’t do that, even one that claims to have “unmatched access to information about how hackers compromise sites”, despite their ability to provide protection being limited without knowing about vulnerabilities that are being exploited. Something else we have found is that hackers do some odd things, including trying on a large scale to exploit vulnerabilities that have never existed. When security companies are not putting in the work that particular situation can lead to situation like when Wordfence was leading people to believe that a popular plugin had a vulnerability it had never had.

One of the areas of odd activity we have been seeing a fair amount of recently has been what looks to be hackers trying to access malicious files that others hackers may have placed in modified copies of legitimate plugins. This doesn’t make a whole lot of sense since the success rate of those types of attack would be incredibly small. Looking into one recent example of that lead to us finding what looks to be attempts to exploit an unfixed vulnerability that we recently disclosed.

Last week we had a request on this website for a file that would be at /wp-content/plugins/background-image-cropper/image/ico/search.php. That would appear at first glance to be a file for the plugin Background Image Cropper, which currently has 500+ active installs. But in looking at the plugin we found that not only has there not been that file in any version of the plugin, but the plugin doesn’t contain a directory /image/ico/ or /image/ (or any directories for that matter). In looking at the small amount of code in the plugin there was nothing that could have been exploited that could have lead to another file being added to the plugin’s directory.

What looks to have happened is that for whatever reason a hacker had decided to use that particular plugin as part of getting malicious code on to websites by installing a modifed version of the plugin after they have gained access to the admin area of WordPress as Administrator level user. That possibility would match with what is mentioned in a review of the plugin. Then some other hacker was trying to in turn exploit a file added to the plugin by the first hacker. Considering that including legitimate installs the plugin has less than 600 active installs, the success rate for that type of attack is going to be incredibly small.

While reviewing logs files on a hacked WordPress website we were cleaning up over at our main business several days after that, we ran across another attempt to access a file that would ostentatiously be in that plugin, /wp-content/plugins/background-image-cropper/wp-post.php, but again it isn’t in the plugin. In looking at all the requests sent from the same IP address we could see that two other files were attempting to be accessed:

178.170.82.27 - - [23/May/2018:04:04:07 -0600] "POST /wp-uti.php HTTP/1.1" 500 0 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36"
178.170.82.27 - - [23/May/2018:04:04:06 -0600] "POST /wp-uti.php HTTP/1.1" 500 303 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36"
178.170.82.27 - - [23/May/2018:04:04:12 -0600] "POST /wp-content/uploads/kc_extensions/background-image-cropper/wp-post.php HTTP/1.1" 500 0 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36"
178.170.82.27 - - [23/May/2018:04:04:11 -0600] "POST /wp-content/uploads/kc_extensions/background-image-cropper/wp-post.php HTTP/1.1" 500 303 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36"
178.170.82.27 - - [23/May/2018:04:04:58 -0600] "POST /wp-content/plugins/background-image-cropper/wp-post.php HTTP/1.1" 500 0 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36"
178.170.82.27 - - [23/May/2018:04:04:53 -0600] "POST /wp-content/plugins/background-image-cropper/wp-post.php HTTP/1.1" 500 303 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36"

One of those interesting, /wp-content/uploads/kc_extensions/background-image-cropper/wp-post.php, because part of the path/file name structure was the same as the previously mentioned request. The rest of path, /wp-content/uploads/kc_extensions/, looked like it could be related to exploitation of a vulnerability in KingComposer we recently disclosed after spotting it due to proactive monitoring to catch vulnerabilities before they can be exploited, as exploitation would lead to files being placed in that location. That vulnerability has yet to be fixed by the developer despite us notifying them of it back on April 16.

Nowhere in that set of requests or the others in the logging was there an attempt to exploit the vulnerability in KingComposer, so we couldn’t be sure what was going on there.

In doing some other looking into that, we found what looks like pretty conclusive evidence that there are attempts now to exploit that vulnerability. There are various reports of abusive activity for an IP address that include trying to access a file in the directory that files would go if it was exploited, /wp-content/uploads/kc_extensions/reup/upload.php, and to access the address needed to exploit the vulnerability,
POST //wpadmin/adminpost.phpactionupload. What is also notable there is that the hacker has some understanding of things beyond just looking at our report because in our explanation we showed sending the input “action” as a POST input, but their requests do it as a GET. It is even possible that the hacking is unrelated to our disclosure, as it isn’t unreasonable to believe that hackers could be do the exact same type of monitoring that we do catch that type of thing.

If you were using our service and KingComposer you would have already been warned about the unfixed issue weeks ago and we would have been available to determine how best to handle the situation. Since we have now seen evidence it is being exploited we had the vulnerability to the free data that comes with the companion plugin for our service, so even those not using our service can be warned about. If you are relying on another data source for info WordPress plugin vulnerabilities there is a good chance you still are not being warned since most of those still have not added the vulnerability despite our public disclosure of it over two weeks ago.

If you want to get ahead of vulnerabilities like this, the same check that lead to us identifying the possibility of that vulnerability in KingComposer is included in our Plugin Security Checker tool (which is accessible through a WordPress plugin of its own), so you can identify if a plugin might have the same type of issue and is in need of further checking by using that too.

04 Jun

Vulnerability Details: Reflected Cross-Site Scripting (XSS) Vulnerability in Form Maker

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.

We often find that the various things that we do come to together to help improve each other and that ...


Our Vulnerability Details posts provide the details of vulnerabilities we didn't discover and access to them is limited to customers of our service due to other security companies trying to sponge off the work needed to create those instead of doing their own work.

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

If you are not currently a customer, 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 WordPress plugin security researcher please contact us to get free access to all of our Vulnerability Details posts.

25 May

Our Proactive Monitoring Caught a PHP Object Injection Vulnerability in WordPress Survey & Poll

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. That again has lead to us catching a vulnerability of a type that hackers are likely to exploit if they know about it. Since the check used to spot this is also included in our Plugin Security Checker (which is accessible through a WordPress plugin of its own), it is another of reminder of how that can help to indicate which plugins are in greater need of security review (for which we do as part of our main service as well as separately).

In the plugin WordPress Survey & Poll the value of a cookie, “wp_sap”, was passed through the unserialize() function in several locations, which could lead to PHP object injection. One of those locations was in the function enqueue_custom_scripts_and_styles() in the file /wordpress-survey-and-poll.php:

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
function enqueue_custom_scripts_and_styles() {
	global $wpdb;
	wp_enqueue_style( 'wp_sap_style', plugins_url( '/templates/assets/css/wp_sap.css', __FILE__ ) );
	wp_enqueue_style( 'jquery_ui_style', plugins_url( '/templates/assets/css/jquery-ui.css', __FILE__ ) );
	wp_enqueue_script( 'jquery' );
	wp_enqueue_script( 'jquery-ui-core', array( 'jquery' ) );
	wp_enqueue_script( 'jquery-effects-core', array( 'jquery' ) );
	wp_enqueue_script( 'jquery-effects-slide', array( 'jquery-effects-core' ) );
	wp_enqueue_script( 'jquery-visible',plugins_url( '/templates/assets/js/jquery.visible.min.js', __FILE__ ), array( 'jquery' ), '1.10.2' );
	wp_register_script('wp_sap_script', plugins_url( '/templates/assets/js/wp_sap.js' , __FILE__ ), array( 'jquery' ), '1.0.0.2', true );
		$survey_viewed = array();
		$sv = '';
		$sv_condition = '';
			if ( isset( $_COOKIE[ 'wp_sap' ] ) ) {
				$survey_viewed = unserialize( stripslashes( $_COOKIE[ 'wp_sap' ] ) );

That function gets called during init if the page being requested is not an admin page of WordPress and if the GET or POST input “sspcmd” exists:

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
if ( is_admin() ) {
	require_once( sprintf( "%s/settings.php", dirname( __FILE__ ) ) );
	$wp_sap_settings = new wp_sap_settings();
	$plugin = plugin_basename( __FILE__ );
	add_filter( "plugin_action_links_$plugin", array( &$this, 'plugin_settings_link' ) );
}
else {
	$wp_sap_url = $_SERVER[ 'HTTP_HOST' ] . $_SERVER[ 'REQUEST_URI' ];
	$wp_sap_load = true;
	if ( ( strpos( $wp_sap_url, 'wp-login' ) ) !== false ) {
		$wp_sap_load = false;
	}
	if ( ( strpos( $wp_sap_url, 'wp-admin' ) ) !== false ) {
		$wp_sap_load = false;
	}
	if ( $wp_sap_load || isset( $_REQUEST[ 'sspcmd' ] ) ) {
		//integrate the public functions
		add_action( 'init', array( &$this, 'enqueue_custom_scripts_and_styles' ) );

That made the vulnerable code accessible to anyone.

We notified the developer of the issue yesterday and a couple of hours later they released version 1.5.6, which resolves the vulnerability by replacing usage of unserialize() with and json_decode() (along with related usage of serialize() with json_encode()).

Proof of Concept

With our plugin for testing for PHP object injection installed and activated, set the value of the cookie “wp_sap” to “O:20:”php_object_injection”:0:{}” and then when you visit the following URL the message “PHP object injection has occurred.” will be shown.

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

http://[path to WordPress]/?sspcmd=test

Timeline

  • May 24, 2018 – Developer notified.
  • Mary 24, 2018 – Developer responds.
  • May 24, 2018 – Version 1.5.6 released, which fixes vulnerability.
21 May

Our Plugin Security Checker Found a Reflected XSS Vulnerability in WordPress Plugin with 100,000+ Active Installs

In a reminder of the rather poor state of security of WordPress plugins and how our Plugin Security Checker tool (which is accessible through a WordPress plugin of its own) can help you to get a better idea if they are in need of additional security scrutiny when we ran the plugin WP Google Map Plugin through the tool to check to see if it would have spotted a recently fixed reflected cross-site scripting (XSS) vulnerability in the plugin we found that the plugin still contained another vulnerability of the same type (it also would have identified the possibility of the previous vulnerability if it had been checked).

In the file /core/class.initiate-core.php the function fc_geocoding() outputs the value of the variable $_POST, which contains any POST inputs sent with a request, without escaping that:

32
33
34
35
function fc_geocoding() {
	print_r($_POST);
	exit;
}

That would lead to a reflected cross-site (XSS) vulnerability depending on if and how it can be accessed. The function is registered to be accessible through WordPress’ AJAX functionality to anyone logged in to WordPress:

23
add_action( 'wp_ajax_fc_geocoding',array( $this, 'fc_geocoding' ) );

So it would be exploitable, though that isn’t a type of vulnerability that hackers are likely to exploit on the average website and therefore there isn’t a lot of risk due to it.

We notified the developer of the issue a week ago. We haven’t heard back from them (other than an automated response that they received our form submission) and no new version has been released to fix the issue. 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 cause any available cookies to be shown in alert box, when logged in to WordPress. 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.

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin-ajax.php?action=fc_geocoding" method="POST">
<input type="hidden" name="test" value="<script>alert(document.cookie);</script>" />
<input type="submit" value="Submit" />
</form>
</body>

Timeline

  • May 14, 2018 – Developer notified.
21 May

Vulnerability Details: Cross-Site Request Forgery (CSRF)/Cross-Site Scripting (XSS) Vulnerability in Ultimate Member

One of the things that we appear to uniquely do in compiling data on vulnerabilities in WordPress plugins is that is that we fully review and test out vulnerabilities when adding them to our data set. That means that unlike other sources we won’t falsely tell people that an unfixed vulnerability has been fixed. It also means that we don’t include false reports of ...


Our Vulnerability Details posts provide the details of vulnerabilities we didn't discover and access to them is limited to customers of our service due to other security companies trying to sponge off the work needed to create those instead of doing their own work.

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

If you are not currently a customer, 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 WordPress plugin security researcher please contact us to get free access to all of our Vulnerability Details posts.

21 May

Vulnerability Details: Reflected Cross-Site Scripting (XSS) Vulnerability in Open Graph for Facebook, Google+ and Twitter Card Tags

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.

The changelog entry for version 2.2.41 of the plugin Open Graph for Facebook, Google+ and Twitter Card Tags is ...


Our Vulnerability Details posts provide the details of vulnerabilities we didn't discover and access to them is limited to customers of our service due to other security companies trying to sponge off the work needed to create those instead of doing their own work.

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

If you are not currently a customer, 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 WordPress plugin security researcher please contact us to get free access to all of our Vulnerability Details posts.

21 May

Vulnerability Details: Reflected Cross-Site Scripting (XSS) Vulnerability in Custom css-js-php

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.

A week and a half ago we detailed a reflected cross-site scripting (XSS) vulnerability that had been fixed in ...


Our Vulnerability Details posts provide the details of vulnerabilities we didn't discover and access to them is limited to customers of our service due to other security companies trying to sponge off the work needed to create those instead of doing their own work.

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

If you are not currently a customer, 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 WordPress plugin security researcher please contact us to get free access to all of our Vulnerability Details posts.