Quantcast
Channel: WordPress Security Archives - Wordfence
Viewing all 426 articles
Browse latest View live

Critical Vulnerabilities Patched in MapPress Maps Plugin

$
0
0

On April 1, 2020, the Wordfence Threat Intelligence Team discovered two vulnerabilities in MapPress Maps for WordPress, a WordPress plugin with over 80,000 installations. One vulnerability that allowed stored Cross-Site Scripting (XSS) was present in both the free and pro versions of the plugin, while a far more critical vulnerability that allowed Remote Code Execution (RCE) was present in the pro version.

We reached out to the plugin’s author the next day, April 2, 2020 and received a response within a few hours. A patched version of both MapPress Free and MapPress Pro were released within hours. We strongly recommend updating both the free and pro versions to the latest version, 2.54.2, as soon as possible.

Wordfence Premium users received a new firewall rule on April 2, 2020 to protect against exploits targeting these vulnerabilities. Wordfence users still using the free version will receive the rule after thirty days on May 2, 2020.


Description: Authenticated Map Creation/Deletion Leading to Stored Cross-Site Scripting (XSS)
Affected Plugin: MapPress Maps for WordPress
Plugin Slug: mappress-google-maps-for-wordpress
Affected Versions: <=2.53.8 Free and Pro
CVE ID: CVE-2020-12077
CVSS Score: 6.5(Medium)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:L
Fully Patched Version: 2.53.9

MapPress Maps for WordPress allows site owners to add custom maps on their site, using both the Google Maps API and the open-source Leaflet engine. Both the free and pro versions of this plugin registered AJAX actions that called functions lacking capability checks and nonce checks. The affected AJAX hooks:

add_action('wp_ajax_mapp_delete', array(__CLASS__, 'ajax_delete'));
add_action('wp_ajax_mapp_save', array(__CLASS__, 'ajax_save'));

As such, it was possible for a logged-in attacker with minimal permissions, such as a subscriber, to add a map containing malicious JavaScript to an arbitrary post or page by sending a $_POST request to wp-admin/admin-ajax.php with the action parameter set to mapp_save, the postid parameter set to the post to add the map to, and the map parameter containing JSON data representing the map to be added. Malicious JavaScript could be added to the title and body parameters of a “Point of Interest” in the saved map, which would be executed whenever a visitor to the site clicked on the mapping pin denoting that Point of Interest (POI). Alternatively, if the global setting for “Show a list of POIs with each map” was enabled, the JavaScript would be executed immediately upon visiting a page with an impacted map.

This vulnerability could redirect a site visitor to a malicious site, or even use an administrator’s session to take over the site by adding a malicious administrative user.

The vulnerable function:

   static function ajax_save() {
       ob_start();

       $mapdata = (isset($_POST['map'])) ? json_decode(stripslashes($_POST['map']), true) : null;
       $postid = (isset($_POST['postid'])) ? $_POST['postid'] : null;

       if (!$mapdata)
           Mappress::ajax_response('Internal error, your data has not been saved!');

       $map = new Mappress_Map($mapdata);
       $mapid = $map->save($postid);

       if ($mapid === false)
           Mappress::ajax_response('Internal error, your data has not been saved!');

       do_action('mappress_map_save', $mapid);     // Use for your own developments

       // Return saved mapid
       Mappress::ajax_response('OK', array('mapid' => $mapid));
   }

Alternatively, an attacker could delete an existing map by sending a $_POST request to wp-admin/admin-ajax.php with the action parameter set to mapp_delete and the mapid parameter of the map to delete. While this would be significantly less impactful, it could still be used by an attacker to remove any of the original maps on the site, potentially prompting an administrator to investigate and trigger a script inserted into a malicious map.

The vulnerable function:

   static function ajax_delete() {
       ob_start();

       $mapid = (isset($_POST['mapid'])) ? $_POST['mapid'] : null;
       $result = Mappress_Map::delete($mapid);

       if (!$result)
           Mappress::ajax_response("Internal error when deleting map ID '$mapid'!");

       do_action('mappress_map_delete', $mapid);   // Use for your own developments
       Mappress::ajax_response('OK', array('mapid' => $mapid));
   }

Description: Authenticated File Upload, Deletion, and Disclosure Leading to RCE or Site Reset
Affected Plugin: MapPress Maps for WordPress
Plugin Slug: mappress-google-maps-for-wordpress
Affected Versions: <=2.53.8 Pro
CVE ID: CVE-2020-12077
CVSS Score: 9.9(Critical)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Fully Patched Version: 2.53.9

The pro version of the MapPress plugin offers the ability to create templates controlling how maps are displayed. It saves these templates as custom .php files. Unfortunately, the plugin registered several AJAX actions that called functions without capability checks or nonce checks:

add_action('wp_ajax_mapp_tpl_get', array(__CLASS__, 'ajax_get'));
add_action('wp_ajax_mapp_tpl_save', array(__CLASS__, 'ajax_save'));
add_action('wp_ajax_mapp_tpl_delete', array(__CLASS__, 'ajax_delete'));

Note that while the names of some of these functions are identical to functions in the previous vulnerability, they are located in another file and belong to a different class. The file containing this vulnerable code was present in both the free and pro versions of the MapPress plugin, but was only active in the pro version.

As such, it was possible for an authenticated attacker with minimal permissions to upload an executable PHP file such as a backdoor or webshell. This could easily lead to complete site takeover, as an attacker with backdoor access could then modify any file on the site, upload additional files, or connect to the database and insert an administrative user.

An attacker could exploit this vulnerability by sending a $_POST request to wp-admin/admin-ajax.php with the action parameter set to mapp_tpl_save, the name parameter set to the base name of the file they wanted to create, and the content parameter set to executable PHP code. This file would then be created and could be executed from the directory of the currently active theme, resulting in Remote Code Execution.

The vulnerable function:

   static function ajax_save() {
       $name = (isset($_POST['name'])) ? $_POST['name'] : null;
       $content = (isset($_POST['content'])) ? stripslashes($_POST['content']) : null;
       $filepath = get_stylesheet_directory() . '/' . $name . '.php';

       $result = @file_put_contents($filepath, $content);
       if ($result === false)
           Mappress::ajax_response('Unable to save');

       // Return filepath after save
       Mappress::ajax_response('OK', $filepath);
   }

An authenticated attacker could also delete any existing PHP file on the site by sending a $_POST request to wp-admin/admin-ajax.php with the action parameter set to mapp_tpl_delete, and the name parameter set to the basename of the file to delete.

For example, to delete wp-config.php a directory traversal attack could be used, with the name parameter set to ../../../wp-config. This would cause the site to be reset, at which point an attacker could gain control of the site by setting it up from scratch and connecting it to a remotely hosted malicious database.

The vulnerable function:

   static function ajax_delete() {
       $name = (isset($_POST['name'])) ? $_POST['name'] : null;
       $filepath = get_stylesheet_directory() . '/' . $name . '.php';

       $result = @unlink($filepath);
       if ($result === false)
           Mappress::ajax_response('Unable to delete');

       Mappress::ajax_response('OK');
   }

Finally, an authenticated attacker could view the contents of any existing PHP file on the site by sending a $_GET request to wp-admin/admin-ajax.php with the action parameter set to mapp_tpl_get, and the name parameter of the file to disclose. For example, to view the contents of wp-config.php, an attacker could set the name parameter to ../../../../wp-config. This could allow an attacker to determine the site’s database credentials. If the site’s database allowed remote access, the attacker could then use this to add an administrative user or make any other desired changes to the database, up to and including deleting nearly all of the site’s content.

The vulnerable function:

   static function ajax_get() {
       $name = (isset($_GET['name'])) ? $_GET['name'] : null;

       $filename = $name . '.php';
       $filepath = get_stylesheet_directory() . '/' . $filename;

       $html = @file_get_contents($filepath);
       $standard = @file_get_contents(Mappress::$basedir . "/templates/$filename");

       if (!$standard)
           Mappress::ajax_response('Invalid template');

       $template = new Mappress_Template(array(
           'name' => $name,
           'content' => ($html) ? $html : $standard,
           'path' => $filepath,
           'standard' => $standard,
           'exists' => ($html) ? true : false
       ));

       Mappress::ajax_response('OK', $template);
   }

Disclosure Timeline

April 1, 2020 – Wordfence Threat Intelligence discovers and analyzes vulnerabilities.
April 2, 2020 – Firewall rule released for Wordfence Premium users. Initial contact with plugin developer. Developer releases patch before the end of day.
May 2, 2020 – Firewall rule becomes available to Wordfence free users.

Conclusion

In today’s post, we detailed two vulnerabilities in the MapPress Maps for WordPress plugin, including a stored Cross-Site Scripting (XSS) and a more critical Remote Code Execution (RCE), File Disclosure, and File deletion vulnerability. These vulnerabilities have been fully patched in version 2.53.9 and we strongly recommend that all users of this plugin upgrade to the latest version available immediately. Sites running Wordfence Premium have been protected against these vulnerabilities since April 2, 2020. Sites still running the free version of Wordfence will receive the firewall rule update on May 1, 2020.

Special thanks to Chris Richardson, the developer of the MapPress Maps for WordPress plugin, for his extremely rapid and professional handling of our disclosure. Patching a vulnerability on the same day the vulnerability disclosure is received by the developer is an exemplary response.

The post Critical Vulnerabilities Patched in MapPress Maps Plugin appeared first on Wordfence.


High Severity Vulnerability Patched in Real-Time Find and Replace Plugin

$
0
0

On April 22, 2020, our Threat Intelligence team discovered a vulnerability in Real-Time Find and Replace, a WordPress plugin installed on over 100,000 sites. This flaw could allow any user to inject malicious Javascript anywhere on a site if they could trick a site’s administrator into performing an action, like clicking on a link in a comment or email.

We reached out to the plugin developer on April 22, 2020, and they released a patch just a few hours after we disclosed the vulnerability to them. This is considered a high-severity security issue, therefore we strongly recommend an immediate update to the latest version available, which at the time of writing is version 4.0.2.

Both Wordfence Premium and Free Wordfence users are protected from XSS attempts against this vulnerability by the Wordfence firewall’s built-in XSS protection.

Description: Cross-Site Request Forgery to Stored Cross-Site Scripting
Affected Plugin: Real-Time Find and Replace
Plugin Slug: real-time-find-and-replace
Affected Versions: <= 3.9
CVE ID: Will be updated once identifier is supplied.
CVSS Score: 8.8 (High)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Fully Patched Version: 4.0.2

Real-Time Find and Replace provides functionality to dynamically replace any HTML content on WordPress sites with new content without permanently changing the source content. The replacement data loads immediately before it is delivered to the user’s browser. The plugin is very easy to use due to its limited functionality.

To provide this functionality, the plugin registers a sub-menu page tied to the function far_options_page with a capability requirement to “activate_plugins.”

 function far_add_pages() {
	$page = add_submenu_page( 'tools.php', 'Real-Time Find and Replace', 'Real-Time Find and Replace', 'activate_plugins', 'real-time-find-and-replace', 'far_options_page' );
	add_action( "admin_print_scripts-$page", "far_admin_scripts" );

The far_options_page function contains the core of the plugin’s functionality for adding new find and replace rules. Unfortunately, that function failed to use nonce verification, so the integrity of a request’s source was not verified during rule update, resulting in a Cross-Site Request Forgery vulnerability.

function far_options_page() {    
	if ( isset( $_POST['setup-update'] ) ) {
		$_POST = stripslashes_deep( $_POST );
		
		// If atleast one find has been submitted
		if ( isset ( $_POST['farfind'] ) && is_array( $_POST['farfind'] ) ) { 
			foreach ( $_POST['farfind'] as $key => $find ){

Any attacker capable of tricking a site owner into executing an unwanted action could replace any content or HTML on a vulnerable site with new content or malicious code. This replacement code or content would then execute anytime a user navigated to a page that contained the original content.

An attacker could use this vulnerability to replace a HTML tag like <head> with malicious Javascript. This would cause the malicious code to execute on nearly every page of the affected site, as nearly all pages start with a <head> HTML tag for the page header, creating a significant impact if successfully exploited. The malicious code could be used to inject a new administrative user account, steal session cookies, or redirect users to a malicious site, allowing attackers the ability to obtain administrative access or to infect innocent visitors browsing a compromised site.

Example of <head> HTML tag being replaced with Javascript.

In the most up to date version, a nonce has been added along with a check_admin_referer nonce verification function to ensure the legitimacy of the source of a request.

function far_options_page() {    
	if ( isset( $_POST['setup-update'] ) ) {
        check_admin_referer( 'far_rules_form' );
		$_POST = stripslashes_deep( $_POST );
		
		// If atleast one find has been submitted
		if ( isset ( $_POST['farfind'] ) && is_array( $_POST['farfind'] ) ) { 
			foreach ( $_POST['farfind'] as $key => $find ){

Disclosure Timeline

April 22, 2020 – Initial discovery and analysis of vulnerability. We verify the Wordfence built-in XSS firewall rule is sufficient. Initial outreach to plugin developer.
April 22, 2020 8:51 AM UTC – Developer responds confirming appropriate inbox.
April 22, 2020 9:34 AM UTC – We provide the full disclosure.
April 22, 2020 1:30 PM UTC – We receive notification that patch has been released.

Conclusion

In today’s post, we detailed a Cross-Site Request Forgery flaw in the Real-Time Find and Replace plugin. This flaw has been fully patched in version 4.0.2. We recommend that users update to the latest version, which is available immediately. Sites running Wordfence Premium, as well as sites using the free version of Wordfence, are protected from Cross-Site Scripting attacks against this vulnerability due to the Wordfence firewall’s built-in protection. If you are aware of a friend or colleague using this plugin, we recommend you forward this security advisory to them as soon as possible to help secure their site.

The post High Severity Vulnerability Patched in Real-Time Find and Replace Plugin appeared first on Wordfence.

High-Severity Vulnerabilities Patched in LearnPress

$
0
0

On March 16, 2020, LearnPress – WordPress LMS Plugin, a WordPress plugin with over 80,000 installations, patched a high-severity vulnerability that allowed subscriber-level users to elevate their permissions to those of an “LP Instructor”, a custom role with capabilities similar to the WordPress “author” role, including the ability to upload files and create posts containing unfiltered HTML, both of which could be used as part of an exploit chain allowing site takeover.

Our Threat Intelligence team analyzed the vulnerability in order to create a firewall rule to protect Wordfence customers. In the process, we discovered two additional vulnerabilities. One of these vulnerabilities was almost identical in consequences to the original vulnerability in that it allowed an attacker to elevate the permissions of any user to “LP Instructor”. The other allowed a logged-in user with minimal permissions, such as a subscriber, to create new pages on the site with arbitrary titles and to change the status of any existing post or page.

We privately disclosed these vulnerabilities to the plugin’s author the next day, on March 17, 2020, and quickly received a response. Unfortunately, however, no patch was released for more than a month. We followed up with the plugin’s author on April 16, 2020, and after receiving no response, contacted the WordPress plugins team. A few hours later, the plugin developer got back in touch and let us know that a patch was in the works. A sufficiently patched version was finally released on April 22, 2020.

We highly recommend updating to version 3.2.6.9 immediately as these security issues are fully patched in that version.

Wordfence Premium users received a new firewall rule on March 16, 2020 to protect against exploits targeting both the original vulnerability and the newly discovered flaws. Free Wordfence users received this rule on April 15, 2020.


Description: Privilege Escalation
Affected Plugin: LearnPress
Plugin Slug: learnpress
Affected Versions: < 3.2.6.9
CVE ID: CVE-2020-11511
CVSS Vecto: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:L/E:P/RL:O/RC:C
CVSS Score: 8.6(High)
Patched Version: 3.2.6.9

LearnPress is a WordPress plugin that allows site owners to create an online learning portal, including the ability to assign users as “LP Instructors” capable of adding their own course material to the site. One functionality of the plugin sends an email to the administrator whenever a user requests to become an instructor, allowing that administrator to approve the request by clicking a link. The function that handles this request runs automatically as soon as plugins are loaded and as such is always ‘listening’ for specific parameters:

function learn_press_accept_become_a_teacher() {
   $action  = ! empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';
   $user_id = ! empty( $_REQUEST['user_id'] ) ? $_REQUEST['user_id'] : '';
   if ( ! $action || ! $user_id || ( $action != 'accept-to-be-teacher' ) ) {
       return;
   }

   if ( ! learn_press_user_maybe_is_a_teacher( $user_id ) ) {
       $be_teacher = new WP_User( $user_id );
       $be_teacher->set_role( LP_TEACHER_ROLE );
       delete_transient( 'learn_press_become_teacher_sent_' . $user_id );
       do_action( 'learn_press_user_become_a_teacher', $user_id );
       $redirect = add_query_arg( 'become-a-teacher-accepted', 'yes' );
       $redirect = remove_query_arg( 'action', $redirect );
       wp_redirect( $redirect );
   }
}

add_action( 'plugins_loaded', 'learn_press_accept_become_a_teacher' );

Due to the way this function was added, it was possible for an attacker to send a request to any valid location within wp-admin with the action parameter set to accept-to-be-teacher and the user_id parameter set to the ID of the user to be granted instructor privileges. This meant that even an unauthenticated attacker could send a request to wp-admin/admin-post.php containing these parameters and elevate the permissions of a user of their choice, though they would need their own user ID to take full advantage of the vulnerability.

Once a user was granted the LP Instructor role, they had access to create new posts, courses, lessons, and quizzes. Additionally, LP Instructor users were granted a capability typically reserved only for editors and administrators: the unfiltered_html capability, which would allow them to insert custom code into any of the pages they created. With this capability, an attacker could easily insert malicious JavaScript into any posts they created, which could then be used to redirect visitors to malvertising sites or even be used for site takeover if a logged-in administrator viewed one of these posts.


Description: Authenticated Page Creation and Status Modification
Affected Plugin: LearnPress
Plugin Slug: learnpress
Affected Versions: < 3.2.6.9
CVE ID: CVE-2020-11510
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:H/E:F/RL:U/RC:C
CVSS Score: 7.1(High)
Patched Version: 3.2.6.9

The LearnPress plugin also handled several tasks via AJAX actions that lacked nonce checks and capability checks. It registers AJAX actions in a loop, though many of these functions did at least use capability checks:

			$ajaxEvents = array(
				'create_page'             => false,
				'plugin_action'           => false,
				'modal_search_items'      => false,
				'dismiss_notice'          => false,
				'search_users'            => false,
				'load_chart'              => false,
				'search_course_category'  => false,
				/////////////
				//'be_teacher'              => false,
				'custom_stats'            => false,
				'ignore_setting_up'       => false,
				'get_page_permalink'      => false,
				'dummy_image'             => false,
				'update_add_on_status'    => false,
				//'plugin_install'          => false,
				'bundle_activate_add_ons' => false,
				'install_sample_data'     => false,

				// Remove Notice
				'remove_notice_popup'     => false,
				// Update order status
				'update_order_status'     => false,
			);
			foreach ( $ajaxEvents as $ajaxEvent => $nopriv ) {
				add_action( 'wp_ajax_learnpress_' . $ajaxEvent, array( __CLASS__, $ajaxEvent ) );

One action, update_order_status, is intended to allow administrators to mark LearnPress orders as paid or refunded. Unfortunately, the function accepted any post ID and any status, even nonexistent ones. As such, it was possible for an attacker to send a request to wp-admin/admin-ajax.php with the action parameter set to learnpress_update_order_status, the order_id set to the Post ID to modify, and the value parameter set to the desired post status. This would allow the attacker to publish or trash any existing post or page, or even set it to a nonexistent status, at which point it would no longer appear on the site or be accessible from wp-admin, and could only be recovered by modifying its status in the database.

       public static function update_order_status() {

           $order_id = learn_press_get_request( 'order_id' );
           $value    = learn_press_get_request( 'value' );

           $order = array(
               'ID'          => $order_id,
               'post_status' => $value,
           );

           wp_update_post( $order ) ? $response['success'] = true : $response['success'] = false;

           learn_press_send_json( $response );

           die();
       }

The other vulnerable action calls a function, create_page, which is intended to be used during the setup wizard, in order to create the default pages LearnPress needs to function. This means that an attacker could send a request to wp-admin/admin-ajax.php with the action parameter set to learnpress_create_page and the page_name parameter set to a value of their choice.

		public static function create_page() {
			$page_name = ! empty( $_REQUEST['page_name'] ) ? $_REQUEST['page_name'] : '';
			$response  = array();
			if ( $page_name ) {

				if ( $page_id = LP_Helper::create_page( $page_name ) ) {
					$response['page'] = get_post( $page_id );
					$html             = learn_press_pages_dropdown( '', '', array( 'echo' => false ) );
					preg_match_all( '!value=\"([0-9]+)\"!', $html, $matches );
					$response['positions'] = $matches[1];
					$response['html']      = '<a href="' . get_edit_post_link( $page_id ) . '" target="_blank">' . __( 'Edit Page', 'learnpress' ) . '</a>&nbsp;';
					$response['html']      .= '<a href="' . get_permalink( $page_id ) . '" target="_blank">' . __( 'View Page', 'learnpress' ) . '</a>';
				} else {
					$response['error'] = __( 'Error! Page creation failed. Please try again.', 'learnpress' );
				}
			} else {
				$response['error'] = __( 'Empty page name!', 'learnpress' );
			}
			learn_press_send_json( $response );
		}

Although less severe, this vulnerability would still allow an attacker to publish pages with spam links in the titles, which could be used as part of a malicious SEO campaign.

Disclosure Timeline

March 16, 2020 – Wordfence Threat Intelligence discovers unpatched vulnerabilities in the LearnPress plugin while analyzing recently patched vulnerabilities. Firewall rule released for Wordfence Premium users. Initial outreach to the plugin developer.
March 17, 2020 – Plugin developer confirms appropriate inbox for handling discussion. Full disclosure of vulnerabilities is sent.
April 15, 2020 – Firewall rule becomes available to Wordfence free users.
April 16, 2020 – Followup with plugin developer as issues not yet patched.
April 20, 2020 – We reach out to the WordPress plugins team about the issue and receive a response from the plugin developer shortly afterwards.
April 22, 2020 – Sufficiently patched version released.

Conclusion

In this post, we detailed two vulnerabilities in the LearnPress plugin, including a privilege escalation vulnerability and a post creation and modification vulnerability. These flaws have been fully patched in version 3.2.6.9, and we urge users to update to the latest available version as soon as possible. Sites running Wordfence Premium have been protected against these vulnerabilities since March 16, 2020, while sites still on the free version of Wordfence have been protected since April 15, 2020. If you are currently using a site running LearnPress as a a student, please forward this advisory to the administrator of the site.

The post High-Severity Vulnerabilities Patched in LearnPress appeared first on Wordfence.

High Severity Vulnerability Patched in Ninja Forms

$
0
0

On April 27, 2020, the Wordfence Threat Intelligence team discovered a Cross-Site Request Forgery(CSRF) vulnerability in Ninja Forms, a WordPress plugin with over 1 million installations. This vulnerability could allow an attacker to trick an administrator into importing a contact form containing malicious JavaScript and replace any existing contact form with the malicious version.

We reached out to Ninja Form’s security team according to their Responsible Disclosure Guidelines and they replied within a few hours. The plugin was patched less than 24 hours after our initial contact, on April 28, 2020.

All Wordfence users, including both Wordfence Premium and free Wordfence users, are protected from XSS attempts against this vulnerability by the Wordfence Firewall’s built-in XSS protection.


Description: Cross-Site Request Forgery to Stored Cross-Site Scripting
Affected Plugin: Ninja Forms
Plugin Slug: ninja-forms
Affected Versions: < 3.4.24.2
CVE ID: CVE-2020-12462
CVSS Score: 8.8 (High)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Fully Patched Version: 3.4.24.2

The Ninja Forms plugin features a “legacy” mode which allows users to revert its styling and features to those of the plugin’s final 2.9.x version. As part of this feature, it adds several AJAX functions which appear to be intended to import forms and fields between the “legacy” mode and the default mode. While all of these functions used capability checks, two of the functions failed to check nonces, which are used to verify that a request was intentionally sent by a legitimate user. One function in particular, ninja_forms_ajax_import_form, allowed importing forms containing custom HTML:

add_action( 'wp_ajax_ninja_forms_ajax_import_form', 'ninja_forms_ajax_import_form' );
function ninja_forms_ajax_import_form(){
   if( ! current_user_can( apply_filters( 'ninja_forms_admin_upgrade_import_form_capabilities', 'manage_options' ) ) ) return;

   $import = stripslashes( $_POST[ 'import' ] );

   $form_id = ( isset( $_POST[ 'formID' ] ) ) ? absint( $_POST[ 'formID' ] ) : '';

   WPN_Helper::delete_nf_cache( $form_id ); // Bust the cache.

   Ninja_Forms()->form()->import_form( $import, TRUE, $form_id, TRUE );

   if( isset( $_POST[ 'flagged' ] ) && $_POST[ 'flagged' ] ){
       $form = Ninja_Forms()->form( $form_id )->get();
       $form->update_setting( 'lock', TRUE );
       $form->save();
   }

   echo json_encode( array( 'export' => WPN_Helper::esc_html($_POST['import']), 'import' => $import ) );
   wp_die();
}

As such, if an attacker was able to trick an administrator into clicking a crafted link, they could spoof a request using that administrator’s session and import a form containing malicious JavaScript into the site. Worse yet, it was possible to replace any existing form on the site with one of these imported forms by setting the formID $_POST parameter to the ID of an existing form.

Depending on where the JavaScript was placed in the imported form, it could be executed in a victim’s browser whenever they visited a page containing the form, whenever an Administrator visited the plugin’s Import/Export page, or whenever an Administrator attempted to edit any of the form’s fields. As is typical with Cross-Site Scripting (XSS) attacks, a malicious script executed in an Administrator’s browser could be used to add new administrative accounts, leading to complete site takeover, while a malicious script executed in a visitor’s browser could be used to redirect that visitor to a malicious site.

Vulnerability Disclosure Policies are Important

One of the reasons this plugin was patched so quickly was because the plugin’s team maintains a Responsible Security Disclosure Policy, often referred to as a Vulnerability Disclosure Policy. This allowed us to contact them directly with our full disclosure rather than spending days trying to find or verify the appropriate contact channel. While we have occasionally seen plugins patched in less than 24 hours in the past, responses like this are exceptional and indicate a serious dedication to security.

If you are responsible for any kind of software product or service, having a Vulnerability Disclosure Policy (VDP) not only improves your chances of being alerted to serious security issues, but also allows you to set expectations for your response. Most importantly, it reduces the risk of vulnerabilities in your products being prematurely or irresponsibly disclosed and attacked by bad actors before you have a chance to fix them. For these reasons, we strongly recommend implementing a VDP to improve not only the efficiency of your response to specific flaws, but also the general security of your product.

Timeline

April 27, 2020 19:00 UTC – Our Threat Intelligence Team discovers and analyzes the vulnerability and verifies that our existing Firewall Rules provide sufficient protection against XSS.
April 27, 2020 19:24 UTC – We provide full disclosure to the plugin’s developer as per their Responsible Security Disclosure Policy.
April 27, 2020 20:27 UTC – We receive a response that a patch should be available the next day.
April 28, 2020 19:00 UTC – Patched version of the plugin released.

Conclusion

In today’s post, we detailed a Cross-Site Request Forgery vulnerability in the Ninja Forms WordPress plugin. This flaw has been fully patched in version 3.4.24.2, and we recommend that all users update to the latest available version immediately. Sites running Wordfence Premium, as well as sites still using the free version of Wordfence, are protected from Cross-Site Scripting attacks against this vulnerability by the Wordfence firewall’s built-in protection. If you know a friend or colleague who is using this plugin, we recommend forwarding this advisory to them as soon as possible to help them secure their site.

The post High Severity Vulnerability Patched in Ninja Forms appeared first on Wordfence.

Unpacking The 7 Vulnerabilities Fixed in Today’s WordPress 5.4.1 Security Update

$
0
0

WordPress Core version 5.4.1 has just been released. Since this release is marked as a combined security and bug fix update, we recommend updating as soon as possible. With that said, most of the security fixes themselves are for vulnerabilities that appear to require specific circumstances to exploit.

All in all this release contains 7 security fixes, 5 of which are XSS (Cross-Site Scripting) vulnerabilities. Both the free and Premium versions of Wordence have robust built-in XSS protection which will protect against potential exploitation of these vulnerabilities.

 

A Breakdown of each security issue

Password reset tokens failed to be properly invalidated

If a password reset was requested for a user, but they then logged in and manually updated their password on the profile page, the emailed password reset link could still be used. Previously, the password reset link would only be invalidated if the user changed their email address. There’s not many circumstances in which this type of issue could be problematic unless an attacker already had access to a victim’s email account, which would effectively be a worst-case scenario. The code change (diff) in question is:

https://core.trac.wordpress.org/changeset/47634/

This vulnerability was independently discovered and reported by both Muaz Bin Abdus Sattar and Jannes.

Certain private posts can be viewed by unauthenticated users

This changeset had the following comment: “Query: Ensure that only a single post can be returned on date/time based queries.”

This indicates that it was possible for an attacker to view private posts by using date and time-based queries, though only for protected posts that were created or updated at the exact same time, down to the second, as an unprotected post. The diff in question is:

https://core.trac.wordpress.org/changeset/47635/

This was discovered by ka1n4t and appears to be similar to CVE-2019-17671, where multiple posts are returned from a query, and only the first post is checked to ensure that it should be publicly visible.

Two XSS Issues in the Customizer

These vulnerabilities appear to allow for corruption of post content by various users, and could allow for the addition of malicious javascript by an authenticated attacker with contributor capabilities.  A user with the ability to write posts (such as a contributor or an author) without the unfiltered_html capability and an administrator or editor could corrupt the data from each other’s drafts, potentially adding malicious JavaScript to a preview or final version of a post. The diff in question is:

https://core.trac.wordpress.org/changeset/47633/

These vulnerabilities were discovered and reported by Evan Ricafort and Weston Ruter.

An XSS issue in the Search Block

This actually appears to refer to two separate vulnerabilities with the same mechanism in both the RSS block and the Search block. An attacker with the ability to customize the class of either of these blocks (such as a contributor) could potentially set the block class in such a way that malicious JavaScript would be executed when viewing or previewing the post. The diff in question is:

https://core.trac.wordpress.org/changeset/47636/

This vulnerability was discovered and reported by Ben Bidner from the WordPress Security Team.

An XSS issue in wp-object-cache

The Object Cache is used to save trips to the database by caching content from the database and making the cache contents available by using a key, which is used to name, and later retrieve the cache contents.

In a few edge cases, an attacker with the ability to change object cache keys might be able to set one of these cache keys to malicious JavaScript. By default WordPress does not display these stats, nor does it allow users to directly manipulate cache keys.

It is possible that an improperly programmed plugin or combination of plugins could allow an attacker to manipulate a cache key and result in the unescaped value being displayed to an administrator viewing these stats via a plugin or custom code designed to display them. The diff in question is:

https://core.trac.wordpress.org/changeset/47637/

This vulnerability was discovered by Nick Daugherty from WordPress VIP / WordPress Security Team.

An XSS issue in file uploads

This particular vulnerability could allow a user with the ‘upload_files’ capability (Authors and above in a default installation) to upload a file with the filename set to malicious JavaScript, which might be executed when viewing the file in the media gallery. The diff in question is:

https://core.trac.wordpress.org/changeset/47638/

This vulnerability was independently discovered and reported by both Ronnie Goodrich (Kahoots) and Jason Medeiros.

An authenticated XSS issue in the block editor

This vulnerability existed in a few of the release candidates, and does not appear to have ever been present in an official release. It was discovered by Nguyen the Duc in WordPress 5.4 RC1 and RC2, and It was fixed in 5.4 RC5.

 

What should I do?

Although most of these vulnerabilities appear to be exploitable only under limited circumstances or by trusted users, the researchers who discovered these vulnerabilities may publish Proof of Concept code for them. Given more time, attackers may find that exploitation of these vulnerabilities is much easier than is readily apparent now. As always,  we recommend updating as soon as possible.

This is a minor WordPress release, which means that most sites will automatically update. If your site sees a lot of traffic, you may wish to perform testing in a staging environment before updating the production version of your site.

 

Conclusion

We’d like to thank the WordPress core team and the researchers who discovered and reported these vulnerabilities for making WordPress safer for everyone.

You can find the official announcement of the WP 5.4.1 release on this page. If you have any questions or comments, please don’t hesitate to post them below and we’ll do our best to answer them in a timely manner. If you are one of the researchers whose work is included above and would like to provide additional detail or corrections, we welcome your comments.

The post Unpacking The 7 Vulnerabilities Fixed in Today’s WordPress 5.4.1 Security Update appeared first on Wordfence.

Nearly a Million WP Sites Targeted in Large-Scale Attacks

$
0
0

Our Threat Intelligence Team has been tracking a sudden uptick in attacks targeting Cross-Site Scripting(XSS) vulnerabilities that began on April 28, 2020 and increased over the next few days to approximately 30 times the normal volume we see in our attack data.

The majority of these attacks appear to be caused by a single threat actor, based on the payload they are attempting to inject – a malicious JavaScript that redirects visitors and takes advantage of an administrator’s session to insert a backdoor into the theme’s header.

After further investigation, we found that this threat actor was also attacking other vulnerabilities, primarily older vulnerabilities allowing them to change a site’s home URL to the same domain used in the XSS payload in order to redirect visitors to malvertising sites.

Due to the sheer volume and variety of attacks and sites that we’ve seen targeted, it is possible that your site may be exposed to these attacks, and the malicious actor will likely pivot to other vulnerabilities in the future. Indications of Compromise (IoCs) are listed below so you can monitor your sites.

While our records show that this threat actor may have sent out a smaller volume of attacks in the past, it’s only in the past few days that they’ve truly ramped up, to the point where more than 20 million attacks were attempted against more than half a million individual sites on May 3, 2020. Over the course of the past month in total, we’ve detected over 24,000 distinct IP addresses sending requests matching these attacks to over 900,000 sites.

All Wordfence users, including Wordfence Premium and free Wordfence users, are protected from XSS attacks via the Web Application Firewall’s built-in XSS protection. The Web Application Firewall also has a set of rules protecting against the attacks we’ve seen attempting to modify the home URL of a site. As these attacks appear to be targeted at vulnerabilities that have been patched for months or years, both Wordfence Premium and free Wordfence users should be protected.

Targets

Many of the targeted vulnerabilities have been attacked in previous campaigns. The most popular vulnerabilities targeted were:

  1. An XSS vulnerability in the Easy2Map plugin, which was removed from the WordPress plugin repository in August of 2019, and which we estimate is likely installed on less than 3,000 sites. This accounted for more than half of all of the attacks.
  2. An XSS vulnerability in Blog Designer which was patched in 2019. We estimate that no more than 1,000 vulnerable installations remain, though this vulnerability was the target of previous campaigns.
  3. An options update vulnerability in WP GDPR Compliance patched in late 2018 which would allow attackers to change the site’s home URL in addition to other options. Although this plugin has more than 100,000 installations, we estimate that no more than 5,000 vulnerable installations remain.
  4. An options update vulnerability in Total Donations which would allow attackers to change the site’s home URL. This plugin was removed permanently from the Envato Marketplace in early 2019, and we estimate that less than 1,000 total installations remain.
  5. An XSS vulnerability in the Newspaper theme which was patched in 2016. This vulnerability has also been targeted in the past.

Although it is not readily apparent why these vulnerabilities were targeted, this is a large scale campaign that could easily pivot to other targets.

Breaking Down the Attack Data

The majority of these attacks are attempting to insert a malicious JavaScript located at count[.]trackstatisticsss[.]com/stm (typically followed by what appears to be a version query string to prevent caching) into a site in the hopes that they’ll be executed by an administrator’s browser. In some cases these attempts include the plain URI of the malicious script, while in others they rely on String.fromCharCode to obfuscate the injected script location. Earlier iterations of these attacks appear to have used ws[.]stivenfernando[.]com/stm as the malicious payload.

Note: all screen shots contain deobfuscated/beautified versions of the scripts in question for readability.

The script checks to see if the victim has any WordPress login cookies set:

The malicious script's "check_adm" function.

If the victim is not logged in, and is not on the login page, it redirects them to a malvertising URL. If the victim is logged into the site, the script attempts to inject a malicious PHP backdoor into the current theme’s header file, in addition to another malicious JavaScript:

The malicious script's "make_theme" function.

Here’s a deobfuscated version of that PHP backdoor:

The PHP Backdoor added to the theme's header

The backdoor downloads yet another payload from https://stat[.]trackstatisticsss[.]com/n.txt, base64_decodes it, saves it to a temporary file htht, attempts to execute it by including it in the theme header, and then removes the temporary file. This method would allow the attacker to maintain control of the site, as they could simply change the contents of the file at https://stat[.]trackstatisticsss[.]com/n.txt to code of their choice which could be used to embed a webshell, create a malicious administrator, or even delete the entire contents of the site. While we have not included the current final payload for brevity, its functionality is to prepend a variant of the initial attack script to every JavaScript file and every .htm, .html, and .php file named “index” on the site, re-check every 6400 seconds to verify that the site is still infected, and reinfect the site if necessary.

Indicators of Compromise

The current final payload uses the following strings to determine whether or not the site’s files have already been infected, and as such they can be considered reliable Indicators of Compromise(IOCs):

hjt689ig9
trackstatisticsss

The current final payload also writes timestamps denoting when the site was last checked for reinfection to a file named debugs.log (note the misspelling).

Additionally, this campaign appears to be associated with another domain, stivenfernando[.]com and as such any occurrences of this domain on your site or in your logs should be considered a potential Indicator of Compromise.

Unfortunately it is impractical to list all of the IP addresses performing these attacks, but the top 10 attackers by request volume are listed below:

185.189.13.165
198.154.112.83
89.179.243.3
132.148.91.196
104.236.133.77
188.166.176.210
77.238.122.196
74.94.234.151
188.166.176.184
68.183.50.252

What should I do?

The most important thing you can do in a situation like this is to keep your plugins up to date, and to deactivate and delete any plugins that have been removed from the WordPress plugin repository. The vast majority of these attacks are targeted at vulnerabilities that were patched months or years ago, and in plugins that don’t have a large number of users. While we did not see any attacks that would be effective against the latest versions of any currently available plugins, running a Web Application Firewall can also help protect your site against any vulnerabilities that might have not yet been patched. Most Cross-Site Scripting(XSS) attacks follow patterns that can be blocked regardless of the specific vulnerability being targeted.

Conclusion

In today’s post we covered a large-scale attack against nearly a million individual sites, including the functionality of the attack payload. All Wordfence users, including sites running the free version of Wordfence as well as Wordfence Premium, are protected against these attacks. Nonetheless, we urge site owners to ensure that all of their plugins are up to date and to deactivate and delete any plugins that have been removed from the WordPress plugin repository.

Credit to Wordfence Security Analyst Nate Smith and QA Lead Matt Rusnak who initially investigated the vulnerabilities being attacked in the earlier stages of this campaign.

The post Nearly a Million WP Sites Targeted in Large-Scale Attacks appeared first on Wordfence.

28,000 GoDaddy Hosting Accounts Compromised

$
0
0

This is a public service announcement (PSA) from the Wordfence team regarding a security issue which may impact some of our customers. On May 4, 2020, GoDaddy, one of the world’s largest website hosting providers, disclosed that the SSH credentials of approximately 28,000 GoDaddy hosting accounts were compromised by an unauthorized attacker.

SSH, while extremely secure if configured correctly, can allow logins with either a username/password combination, or a username and a public/private key pair. In the case of this breach, it appears likely that an attacker placed their public key on the affected accounts so that they could maintain access even if the account password was changed.

It is unclear which of GoDaddy’s hosting packages were affected by this breach. According to GoDaddy’s public statement:

“On April 23, 2020, we identified SSH usernames and passwords had been compromised by an unauthorized individual in our hosting environment. This affected approximately 28,000 customers. We immediately reset these usernames and passwords, removed an authorized SSH file from our platform, and have no indication the individual used our customers’ credentials or modified any customer hosting accounts. The individual did not have access to customers’ main GoDaddy accounts.”

The breach itself appears to have occurred on October 19, 2019.

What should I do?

Immediate Action

If you have been impacted by this breach and have not already been notified by GoDaddy, you will likely be notified in the near future.

GoDaddy indicates that they have updated the account passwords and removed the attacker’s public key. While this should prevent the attacker from accessing impacted sites via SSH, we strongly recommend changing your site’s database password, as this could have easily been compromised by an attacker without modifying the account.

Compromised database credentials could be used to gain control of a WordPress site if remote database connections are enabled, which GoDaddy allows on many of its hosting accounts. You may also wish to check your site for unauthorized administrative users, as these could have been created without modifying any files on the site.

Remain Vigilant

Breaches like this can create a prime target for attackers who use phishing campaigns as a means to infect users.

Phishing, by general definition, is an attack whereby an attacker will create an email that appears to come from a legitimate source, but is intended to obtain sensitive information from an unsuspecting user. Although only 28,000 hosting accounts appear to have been affected, it is estimated that millions of sites are hosted by GoDaddy. This means that there are millions of users out there who might be worried that they will receive a notification that their hosting account has been breached.

Therefore the likelihood of a phishing campaign targeting GoDaddy users is high. We recommend that under these conditions, GoDaddy customers take care when clicking on links or executing any actions in an email to ensure that they don’t end up as the victim of a phishing attack.

There are a few key things you can check to see if you are the target of a phishing attack:

  • Check the email header. If the source of the email does not come from a registered GoDaddy domain, then it most likely did not come from GoDaddy and is an attempt at phishing.
  • Look for a large amount of typos or misspellings in the email content itself. This can indicate the presence of an attacker. Professional emails will contain minimal typos or misspellings, if any.
  • Modified verbiage used to scare you into providing personal information. GoDaddy’s security incident disclosure email should not appear to scare you, or ask you to provide any information. It should simply inform you that you may have been impacted by a breach. If you receive an email that appears to be scaring you into providing information, then it may be a phishing attempt.

If you can not verify the source of an email or its legitimacy, it is best to go directly to the GoDaddy site and contact them via their standard support channels. This will allow you to verify that your account is secure.

This is a public service announcement by the Wordfence Threat Intelligence team. We are providing this as a courtesy to our own customers, and to the larger WordPress community. Please contact GoDaddy directly if you have questions about the breach or about the security of your account. If you have friends or colleagues who use GoDaddy hosting, we suggest that you share this post with them to ensure they are aware of this issue.

Thank you to Wordfence Senior QA Engineer Ram Gall for his joint contributions and research to this post.

The post 28,000 GoDaddy Hosting Accounts Compromised appeared first on Wordfence.

Combined Attack on Elementor Pro and Ultimate Addons for Elementor Puts 1 Million Sites at Risk

$
0
0

On May 6, 2020, our Threat Intelligence team received reports of active exploitation of vulnerabilities in two related plugins, Elementor Pro and Ultimate Addons for Elementor. We have reviewed the log files of compromised sites to confirm this activity.

As this is an active attack, we wanted to alert you so that you can take steps to protect your site. We are intentionally limiting the amount of information this post provides, because this is an ongoing attack, and the most critical vulnerability has not yet been patched.

We have released a firewall rule which protects Wordfence Premium users against exploitation of this vulnerability. Free Wordfence users will be protected against this vulnerability after 30 days, on June 5, 2020.

Which plugins are affected by this attack

There are two plugins affected by this attack campaign. The first is Elementor Pro which is made by Elementor. This plugin has a zero day vulnerability which is exploitable if users have open registration.

UPDATE: As of 4:22 PM UTC today, May 7 2020, Elementor has released version 2.9.4 of Elementor Pro. Our threat intelligence team has verified that this patches this vulnerability. We recommend updating to this version immediately.

The second affected plugin is Ultimate Addons for Elementor, which is made by Brainstorm Force. A vulnerability in this plugin allows the Elementor Pro vulnerability to be exploited, even if the site does not have user registration enabled.

We estimate that Elementor Pro is installed on over 1 million sites and that Ultimate Addons has an install base of roughly 110,000.

Elementor Pro

Description:  Authenticated Arbitrary File Upload
Affected Plugin: Elementor Pro
Plugin Slug: elementor-pro
Affected Versions: <= 2.9.3
CVE ID: Will be updated once identifier is supplied.
CVSS Score: 9.9 (Critical)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Fully Patched Version: 2.9.4

To be clear, this does not impact the free Elementor plugin with over 4 million installations available from the WordPress plugin repository. The Elementor Pro plugin is a separate download available from the Elementor.com website. We estimate that Elementor Pro has over 1 million active installations.

The vulnerability in Elementor Pro, which is rated Critical in severity, allows registered users to upload arbitrary files leading to Remote Code Execution. This is a zero day vulnerability.

An attacker able to remotely execute code on your site can install a backdoor or webshell to maintain access, gain full administrative access to WordPress, or even delete your site entirely. Due to the vulnerability being unpatched at this time, we are excluding any further information.

We have data via another vendor that indicates the Elementor team are working on a patch. We have contacted Elementor and did not immediately receive confirmation of this before publication.

Ultimate Addons for Elementor

Description: Registration Bypass
Affected Plugin: Ultimate Addons for Elementor
Plugin Slug: ultimate-elementor
Affected Versions: <= 1.24.1
CVE ID: Will be updated once identifier is supplied.
CVSS Score: 7.2 (High)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Fully Patched Version: 1.24.2

The Ultimate Addons for Elementor plugin recently patched a vulnerability in version 1.24.2 that allows attackers to create subscriber-level users, even if registration is disabled on a WordPress site.

Two vulnerabilities being used in concert to attack sites

Attackers are able to directly target the zero day vulnerability in Elementor Pro on sites with open user registration.

In cases where a site does not have user registration enabled, attackers are using the Ultimate Addons for Elementor vulnerability on unpatched sites to register as a subscriber. Then they proceed to use the newly registered accounts to exploit the Elementor Pro zero day vulnerability and achieve remote code execution.

What you should do

If you are using Wordfence Premium, your site has received a firewall rule to protect you against this active attack.

There are a number of steps a site owner not using Wordfence Premium can take to protect their site from this active attack.

Upgrade Ultimate Addons for Elementor immediately. Make sure Ultimate Addons for Elementor is version 1.24.2 or greater.

Downgrade to Elementor free until a patch is released for Elementor Pro. You can do so by deactivating Elementor Pro and removing it from your site. This will remove the file upload vulnerability.

Once a patch is released, you can re-install the patched version of Elementor Pro on your site and regain any lost functionality. You may temporarily lose some design elements once downgraded, but in our tests these elements came back when reinstalling Elementor Pro. Nevertheless, a backup prior to downgrading is always prudent.

Tip: If you need a list of where you have Elementor Pro installed, you can login to your account on Elementor.com and go to “Purchases” then “View Websites” for a full list where Elementor Pro is installed with that license.

UPDATE: As of 4:22 PM UTC today, May 7 2020, Elementor has released version 2.9.4 of Elementor Pro. Our threat intelligence team has verified that this patches this vulnerability. You no longer need to downgrade to keep your site safe as of this time. Instead, we recommend updating to version 2.9.4 immediately.

Check for any unknown subscriber-level users on your site. This may indicate that your site has been compromised as a part of this active campaign. If so, remove those accounts.

Check for files named “wp-xmlrpc.php.” These can be considered an indication of compromise, so check your site for evidence of this file. Wordfence will alert you if a file containing malware is found.

Delete any unknown files or folders found in /wp-content/uploads/elementor/custom-icons/ directory. Files located here after a rogue subscriber-level account has been created are a clear indication of compromise.

If you are seeing widespread infection, use Wordfence to clean your site. The linked guide will assist you, or you can engage our Security Services Team for a professional site cleaning. As always, premium customers have access to our customer support engineers if there are any questions.

Thank you to Customer Service Engineer Gerroald Barron for bringing this issue to our attention, as well as Stephen Rees-Carter, Ramuel Gall, and Kathy Zant for their assistance in researching this attack and testing mitigations.

The post Combined Attack on Elementor Pro and Ultimate Addons for Elementor Puts 1 Million Sites at Risk appeared first on Wordfence.


Vulnerabilities Patched in Page Builder by SiteOrigin Affects Over 1 Million Sites

$
0
0

On Monday, May 4, 2020, the Wordfence Threat Intelligence team discovered two vulnerabilities present in Page Builder by SiteOrigin, a WordPress plugin actively installed on over 1,000,000 sites. Both of these flaws allow attackers to forge requests on behalf of a site administrator and execute malicious code in the administrator’s browser. The attacker needs to trick a site administrator into executing an action, like clicking a link or an attachment, for the attack to succeed.

We first contacted the plugin developer on May 4, 2020. After establishing an appropriate communication channel, we provided the full disclosure later that day. The developer quickly released a patch the next day, which was May 5, 2020.

These are considered high-risk security issues that could lead to full site takeover. We recommend an immediate update of Page Builder by SiteOrigin to the latest version available. At the time of writing, that is version 2.10.16.

Both the free and Premium version of the Wordfence firewall protect against these vulnerabilities via the built in cross site scripting (XSS) protection in the Wordfence firewall.

Description: Cross-Site Request Forgery to Reflected Cross-Site Scripting
Affected Plugin: Page Builder by SiteOrigin
Plugin Slug: siteorigin-panels
Affected Versions: <= 2.10.15
CVE ID: Will be updated once identifier is supplied.
CVSS Score: 8.8 (High)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Fully Patched Version: 2.10.16

Page Builder by SiteOrigin is a plugin that simplifies page and post editing in WordPress. Users can create “responsive column based content” using both widgets from WordPress and widgets from the SiteOrigin Widgets Bundle plugin.

The plugin has a built-in live editor so users can update content and drag/drop widgets while observing those changes made in real time. This makes the editing and designing for a page or post a much smoother process.

A view of the Page Builder by SiteOrigin live editor feature.

In order to show the modifications in real time through the live editor, the plugin registers the is_live_editor() function to check if a user is in the live editor.

static function is_live_editor(){
  return ! empty( $_GET['siteorigin_panels_live_editor'] );
}

If the user is in the live editor, the siteorigin_panels_live_editor parameter will be set to “true” and register that a user is accessing the live editor. The plugin will then attempt to include the live editor file which renders all of the content.

	// Include the live editor file if we're in live editor mode.
		if ( self::is_live_editor() ) {
			SiteOrigin_Panels_Live_Editor::single();
		}

Any content changes made are set and sent as a $_POST parameter:  live_editor_panels_data.  This parameter contains all of the content that has been edited by the user and is required to render a live preview of the changes.

Once a change has been made, the live-editor-preview.php file is used to render the content provided from the live_editor_panels_data parameter and update the page preview displaying any changes made changes in real-time.

 <?php if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } wp_enqueue_style( 'siteorigin-preview-style', siteorigin_panels_url( 'css/live-editor-preview' . SITEORIGIN_PANELS_CSS_SUFFIX . '.css' ), array(), SITEORIGIN_PANELS_VERSION ); ?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
	<meta charset="<?php bloginfo( 'charset' ); ?>">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="profile" href="http://gmpg.org/xfn/11">
	<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>">
	<?php wp_head(); ?>
</head>

<body <?php body_class(); ?>>
	
<div id="content" class="site-content">
		
<div class="entry-content">
			<?php if( !empty( $_POST['live_editor_panels_data'] ) ) { $data = json_decode( wp_unslash( $_POST['live_editor_panels_data'] ), true ); if( !empty( $data['widgets'] ) && ( !class_exists( 'SiteOrigin_Widget_Field_Class_Loader' ) || method_exists( 'SiteOrigin_Widget_Field_Class_Loader', 'extend' ) ) ) { $data['widgets'] = SiteOrigin_Panels_Admin::single()->process_raw_widgets( $data['widgets'], false, false );
				}
				echo siteorigin_panels_render( 'l' . md5( serialize( $data ) ), true, $data);
			}
			?>
		</div>

<!-- .entry-content -->
	</div>

	<?php wp_footer(); ?>
</body>
</html>

While capability checks were present in the post_metadata function to ensure a user accessing the live editor was allowed to edit posts, there was no nonce protection to verify that an attempt to render content in the live editor came from an legitimate source.

	function post_metadata( $value, $post_id, $meta_key ) {
		if (
			$meta_key == 'panels_data' &&
			current_user_can( 'edit_post', $post_id ) &&
			! empty( $_POST['live_editor_panels_data'] ) &&
			$_POST['live_editor_post_ID'] == $post_id
		) {
			$value = array( json_decode( wp_unslash( $_POST['live_editor_panels_data'] ), true ) );
		}
		return $value;
	}

As part of this exploit, some of the available widgets, such as the “Custom HTML” widget, could be used to inject malicious JavaScript into a rendered live page. If a site administrator was tricked into accessing a crafted live preview page, any malicious Javascript included as part of the “Custom HTML” widget could be executed in the browser. The data associated with a live preview was never stored in the database, resulting in a reflected XSS flaw rather than stored XSS flaw, in conjunction with the CSRF flaw.

This flaw could be used to redirect a site’s administrator, create a new administrative user account, or, as seen in the recent attack campaign targeting XSS vulnerabilities, be used to inject a backdoor on a site.

Description: Cross-Site Request Forgery to Reflected Cross-Site Scripting
Affected Plugin: Page Builder by SiteOrigin
Plugin Slug: siteorigin-panels
Affected Versions: <= 2.10.15
CVE ID: Will be updated once identifier is supplied.
CVSS Score: 8.8 (High)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Fully Patched Version: 2.10.16

We discovered an additional Cross-Site Request Forgery flaw in the action_builder_content function of the plugin. This was tied to the AJAX action wp_ajax_so_panels_builder_content.

add_action( 'wp_ajax_so_panels_builder_content', array( $this, 'action_builder_content' ) );

This function’s purpose was to transmit content submitted as panels_data from the live editor to the WordPress editor in order to update or publish the post using the content created from the live editor. This function did have a permissions check to verify that a user had the capability to edit posts for the given post_id. However, there was no nonce protection to verify the source of a request, causing the CSRF flaw.

	/**
	 * Get builder content based on the submitted panels_data.
	 */
	function action_builder_content() {
		header( 'content-type: text/html' );

		if ( ! current_user_can( 'edit_post', $_POST['post_id'] ) ) {
			wp_die();
		}

As part of the process, the content from the panels_data function was purposefully retrieved so that could be echoed to the page.

if ( empty( $_POST['post_id'] ) || empty( $_POST['panels_data'] ) ) {
			echo '';
			wp_die();
		}

		// echo the content
		$old_panels_data        = get_post_meta( $_POST['post_id'], 'panels_data', true );
		$panels_data            = json_decode( wp_unslash( $_POST['panels_data'] ), true );
		$panels_data['widgets'] = $this->process_raw_widgets(
			$panels_data['widgets'],
			! empty( $old_panels_data['widgets'] ) ? $old_panels_data['widgets'] : false,
			false
		);
		$panels_data            = SiteOrigin_Panels_Styles_Admin::single()->sanitize_all( $panels_data );

With this function, the “Custom HTML” widget did not create an XSS flaw in the same way as the previous vulnerability due to some sanitization features. However, we discovered that the “Text” widget could be used to inject malicious JavaScript due to the ability to edit content in a ‘text’ mode rather than a ‘visual’ mode. This allowed potentially malicious JavaScript to be sent unfiltered. Due to the widget data being echoed, any malicious code that was a part of the text widgets data could then be executed as part of a combined CSRF to XSS attack in a victim’s browser.

As with the previously mentioned CSRF to Reflected XSS vulnerability, this could ultimately be used to redirect a site’s administrator, create a new administrative user account, or, as seen in the recent attack campaign targeting XSS vulnerabilities, be used to inject a backdoor on a site.

Proof of Concept Walkthrough

Disclosure Timeline

May 4, 2020 – Initial discovery and analysis of vulnerabilities. We verify the Wordfence built-in XSS firewall rule offers sufficient protection. Initial outreach to the plugin’s team.
May 4, 2020 – Plugin’s developer confirms appropriate channel and we provide full disclosure.
May 5, 2020 – Developer acknowledges vulnerabilities and advises that they should have a patch released later in the day.
May 5, 2020 – A sufficient patch is released.

Conclusion

In today’s post, we detailed two flaws present in the Page Builder by SiteOrigin plugin that allowed attackers to forge requests on behalf of a site administrator and execute malicious code in that administrator’s browser. These flaws have been fully patched in version 2.10.16. We recommend that users immediately update to the latest version available.

Sites running Wordfence Premium, as well as sites using the free version of Wordfence, are protected from Cross-Site Scripting attacks against this vulnerability due to the Wordfence firewall’s built-in protection. If you know a friend or colleague who is using this plugin on their site, we highly recommend forwarding this advisory to them to help keep them protected.

Special thanks to Greg Priday, the plugin’s developer, for an extremely prompt response and for releasing a patch very quickly.

The post Vulnerabilities Patched in Page Builder by SiteOrigin Affects Over 1 Million Sites appeared first on Wordfence.

One Attacker Outpaces All Others

$
0
0

Starting April 28th, we saw a 30 times increase in cross site scripting attack volume, originating from a single attacker, and targeting over a million WordPress sites. We published research detailing the threat actor and attack volume increase on May 5th. By the time we published, the attack volume had dropped back down to baseline levels.

As of May 11, 2020, attacks by this same threat actor have once again ramped up, and are ongoing. This attacker has now attacked over 1.3 million sites in the past month. As of May 12, 2020, attacks by this threat actor have outpaced all other attacks targeting vulnerabilities across the WordPress ecosystem.

The chart below describes the attack volume we are seeing.

Attacks by this threat actor vs all other sources
These attacks are targeting the same vulnerabilities as the previous wave, with a heavy focus on older XSS vulnerabilities. Additionally, we have been able to link this threat actor to previously described attacks as far back as February 9, 2020.

A History of attacks

Our Threat Intelligence team has been able to link this threat actor to previous attacks with payloads hosted at domains: collectfasttracks[.]com and destinyfernandi[.]com.

Our logs show that this attacker has been ramping up attack volume, sustaining the attack over a two day period, and then reducing volume to a trickle. Each of these surges has progressively increased in volume as the attacker becomes more aggressive.

The earliest attacks containing the destinyfernandi[.]com payload occurred on February 9th and 10th, 2020 and targeted over 200,000 sites with 3.8 million requests.

On March 14 and 15, 2020, attacks containing the collectfasttracks[.]com payload ramped up and targeted over 500,000 sites with more than 7 million requests. That is an approximate doubling in attack volume and number of sites targeted from February to March.

What has changed?

Previous attacks appeared to be spaced roughly a month apart and had much lower volume. Comparatively, the last 30 days have seen 4 attacks of increasing size, cumulatively targeting over 1.3 million sites.

While this threat actor is not targeting different vulnerabilities, the new wave of attacks is hosting the initial malware payload on a different domain:

https://css[.]digestcolect[.]com/stm

The script hosted on the new domain is similar to the one previously hosted at count[.]trackstatisticsss[.]com.

There are a few changes that indicate the attacker is refining their technique. They fixed a bug in the previous version of their PHP backdoor that would have prevented it from being usable on most sites. They have also added two additional backdoor variants, one of which is similar to the backdoor used in a previous attack campaign.

The screenshot below has three chunks of PHP code, each starting with a <?php tag. These are three separate malware variants that the attacker embeds in infected sites. The first loads code from the attacker’s domain and the second and third malware variants allow the attacker to manually execute malicious code by sending a request containing a password and encoded data to execute.

Partially deobfuscated PHP backdoors
*The PHP backdoor variants in this screen shot have been partially deobfuscated for readability

When the older backdoor attempted to execute the payload located at https://stat[.]trackstatisticsss[.]com/n.txt, it tried to use the PHP include() function to include the payload source code. This was a bug because include() expects a file. The attackers should have been including the temporary file containing the payload. We spotted this bug during our previous research but neglected to mention it in our earlier post in order to avoid reporting bugs to malware authors.

The threat actor has now fixed this bug and the current backdoor correctly includes the payload located at http://css[.]digestcolect[.]com/m.txt.

The two additional backdoors, shown in the screenshot above, allow attackers to maintain access to the site, even if the payload URL is taken down due to an abuse complaint.

New Indicators of Compromise

While previous indicators of compromise still apply, the updated final payload also uses the following string to determine whether the site is already infected. It can do this because this is the name of the variable that it attempts to insert into every JavaScript file on the infected site:

mndfhghjf

The presence of the following domains in your database or filesystem should be considered an indicator of compromise:

digestcolect[.]com
trackstatisticsss[.]com
stivenfernando[.]com
collectfasttracks[.]com
destinyfernandi[.]com

As with most attack campaigns, the attacker frequently rotates IP addresses. At the moment, we are seeing attacks from these top 10 attacking IP addresses.

5.187.34.95
91.121.106.106
94.23.3.130
54.36.197.5
46.37.172.252
104.238.222.178
2001:41d0:2:482::
104.236.133.77
2001:41d0:c:c3d::
151.80.25.182

What should I do?

As with the previous attacks, the majority of vulnerabilities being targeted are Cross-Site Scripting (XSS) flaws. The Wordfence Firewall’s built-in XSS protection provides protection from these attacks. Nonetheless, we strongly recommend updating any outdated plugins or themes. We also recommend deactivating and deleting any plugins installed on your WordPress site that have been removed from the official WordPress repository.

If you are running the Wordfence plugin, our scanner will alert you if have any plugins or themes with known vulnerabilities, or that have been removed from the WordPress repository. If you are a Wordfence Premium customer, the real-time blacklist will detect and block access to your site from these malicious IP addresses.

Conclusion

In today’s post, we described another wave of large-scale attacks against WordPress sites, and linked these attacks to earlier attacks by the same threat actor going back to the beginning of the year. All Wordfence users, including sites running the free version of Wordfence, and Wordfence Premium, are protected against these attacks. Nonetheless, we recommend that all site owners keep their plugins and themes up to date. We will continue to track this threat actor’s movements going forward and share additional information as it becomes available. Please help create awareness of this ongoing threat by sharing this post with your fellow site administrators.

The post One Attacker Outpaces All Others appeared first on Wordfence.

Vulnerability in Google WordPress Plugin Grants Attacker Search Console Access

$
0
0

On April 21st, our Threat Intelligence team discovered a vulnerability in Site Kit by Google, a WordPress plugin installed on over 300,000 sites. This flaw allows any authenticated user, regardless of capability, to become a Google Search Console owner for any site running the Site Kit by Google plugin.

We filed a security issue report with Google on April 21, 2020. A patch was released a few weeks later on May 7, 2020.

This is considered a critical security issue that could lead to attackers obtaining owner access to your site in Google Search Console. Owner access allows an attacker to modify sitemaps, remove pages from Google search engine result pages (SERPs), or to facilitate black hat SEO campaigns. We strongly recommend an immediate update to the latest version of this plugin. At the time of writing, that is version 1.8.0 of Site Kit by Google.

Wordfence Premium customers received a new firewall rule on April 21, 2020 to protect against exploits targeting this vulnerability. Free Wordfence users will receive this rule after thirty days, on May 21, 2020.

Description: Google Search Console Privilege Escalation
Affected Plugin: Site Kit by Google
Plugin Slug: google-site-kit
Affected Versions: <= 1.7.1
CVE ID: Will be updated once identifier is supplied.
CVSS Score: 9.1 (Critical)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:L
Fully Patched Version: 1.8.0

Site Kit by Google is a plugin used to obtain and display insights on a site’s visitors and search performance as well as advertising performance, page speed insights and other metrics from Google services in the WordPress dashboard. It does this by initially connecting to a Google Search Console account, later providing additional capabilities to connect to Analytics, AdSense, PageSpeed Insights, Optimize, and Tag Manager.

Site Kit by Google Dashboard.

In order to establish the first connection with Site Kit and Google Search Console, the plugin generates a proxySetupURL that is used to redirect a site’s administrator to Google OAuth and run the site owner verification process through a proxy.

proxySetupURL Disclosure

Due to the lack of capability checks on the admin_enqueue_scripts action, the proxySetupURL was displayed as part of the HTML source code of admin pages to any authenticated user accessing the /wp-admin dashboard.

More specifically, the admin_enqueue_scripts action triggers the enqueue_minimal_admin_script function which enqueues the googlesitekit-base assest and ultimately includes the ‘googlesitekit-base-data‘ that returns the inline base data. This includes the proxySetupURL.

	new Script_Data(
				'googlesitekit-base-data',
				array(
					'global'        => '_googlesitekitBaseData',
					'data_callback' => function () {
						return $this->get_inline_base_data();
					},
				)
			),

Here is a look at the inline_js_base_data function that retrieves the data to display in the WordPress dashboard’s source code as part of the the admin_enqueue_scripts action. This includes the proxySetupURL.

	/**
	 * Modifies the base data to pass to JS.
	 *
	 * @since 1.2.0
	 *
	 * @param array $data Inline JS data.
	 * @return array Filtered $data.
	 */
	private function inline_js_base_data( $data ) {
		$first_admin_id  = (int) $this->first_admin->get();
		$current_user_id = get_current_user_id();

		// If no first admin is stored yet and the current user is one, consider them the first.
		if ( ! $first_admin_id && current_user_can( Permissions::MANAGE_OPTIONS ) ) {
			$first_admin_id = $current_user_id;
		}
		$data['isFirstAdmin'] = ( $current_user_id === $first_admin_id );
		$data['splashURL']    = esc_url_raw( $this->context->admin_url( 'splash' ) );

		$auth_client = $this->get_oauth_client();
		if ( $auth_client->using_proxy() ) {
			$access_code                 = (string) $this->user_options->get( Clients\OAuth_Client::OPTION_PROXY_ACCESS_CODE );
			$data['proxySetupURL']       = esc_url_raw( $auth_client->get_proxy_setup_url( $access_code ) );
			$data['proxyPermissionsURL'] = esc_url_raw( $auth_client->get_proxy_permissions_url() );
		}

		return $data;
	}

A closer look at the data discoverable in the source code of the admin dashboard:

proxySetupURL found in the source code.

This was fixed in the latest version of the plugin by the addition of a capability check on the admin_enqueue_scripts action. This prohibits the inline_js_base_data from being included in administrative pages for users who do not have the appropriate privileges, such as subscribers. This prevents the proxySetupURL from being displayed to unauthorized users.

	add_action( 'admin_enqueue_scripts', $register_callback );
		add_action( 'wp_enqueue_scripts', $register_callback );

		add_action(
			'admin_enqueue_scripts',
			function() {
				if ( ! current_user_can( Permissions::AUTHENTICATE ) ) {
					return;
				}
				$this->enqueue_minimal_admin_script();
			}
		);

Unprotected Verification

In addition to displaying the proxySetupURL to any authenticated user, we discovered that the verification request used to verify a site’s ownership was a registered admin action that, again, did not have any capability checks. This allowed verification requests to come from any authenticated WordPress user, including those with minimal permissions.

The admin_action_googlesitekit_proxy_setup action was registered here.

	add_action(
			'admin_action_' . Google_Proxy::ACTION_SETUP,
			function () {
				$this->verify_proxy_setup_nonce();
			},
			-1
		);

		add_action(
			'admin_action_' . Google_Proxy::ACTION_SETUP,
			function () {
				$code      = $this->context->input()->filter( INPUT_GET, 'googlesitekit_code', FILTER_SANITIZE_STRING );
				$site_code = $this->context->input()->filter( INPUT_GET, 'googlesitekit_site_code', FILTER_SANITIZE_STRING );

				$this->handle_site_code( $code, $site_code );
				$this->redirect_to_proxy( $code );
			}
		);

This is the function that handles the verification request:

	/**
	 * Handles receiving a verification token for a user by the authentication proxy.
	 *
	 * @since 1.1.0
	 * @since 1.1.2 Runs on `admin_action_googlesitekit_proxy_setup` and no longer redirects directly.
	 */
	private function handle_verification_token() {
		$verification_token = $this->context->input()->filter( INPUT_GET, 'googlesitekit_verification_token', FILTER_SANITIZE_STRING );
		$verification_type  = $this->context->input()->filter( INPUT_GET, 'googlesitekit_verification_token_type', FILTER_SANITIZE_STRING );
		$verification_type  = $verification_type ?: self::VERIFICATION_TYPE_META;

		if ( empty( $verification_token ) ) {
			return;
		}

		switch ( $verification_type ) {
			case self::VERIFICATION_TYPE_FILE:
				$this->authentication->verification_file()->set( $verification_token );
				break;
			case self::VERIFICATION_TYPE_META:
				$this->authentication->verification_meta()->set( $verification_token );
		}

		add_filter(
			'googlesitekit_proxy_setup_url_params',
			function ( $params ) use ( $verification_type ) {
				return array_merge(
					$params,
					array(
						'verify'              => 'true',
						'verification_method' => $verification_type,
					)
				);
			}
		);
	}

Here’s a look at the verification request sent during the process:
/wp-admin/index.php?action=googlesitekit_proxy_setup&googlesitekit_code=[SITEKIT-CODE]&googlesitekit_verification_token=[VERIFICATION TOKEN]&googlesitekit_verification_token_type=FILE&nonce=[NONCE]

This was fixed in the latest version with a capability check added on the handle_verification_token function to verify that a verification request occurred during a legitimate authenticated session with a user that had administrative permissions to SETUP the Site Kit by Google plugin.

		if ( ! current_user_can( Permissions::SETUP ) ) {
			wp_die( esc_html__( 'Sorry, you are not allowed to do that.', 'google-site-kit' ), 403 );
		}

These two flaws made it possible for subscriber-level users to become Google Search Console owners on any affected site.

The Impact

When a new owner for a property in Google Search Console is set up, a message is sent via email saying, “Property owners can change critical settings that affect how Google Search interacts with your site or app.”

There are several ways an attacker could make use of Google Search Console owner access for a site. For malicious attackers, the ability to manipulate search engine result pages through Blackhat SEO is particularly attractive. Additionally, an attacker could use search console access in conjunction with another exploit that involves malicious content being injected on a site for monetization.

An owner in Google Search Console can do things like request that URLs be removed from the Google Search engine, view competitive performance data, modify sitemaps, and more.

Unwarranted Google Search Console owner access on a site has the potential to hurt the visibility of a site in Google search results and impact revenue as an attacker removes URLs from search results. More specifically, it could be used to aid a competitor who wants to hurt the ranking and reputation of a site to better improve their own reputation and ranking.

Verifying the Integrity of Google Search Console Ownership

Fortunately, there are ways to verify and monitor if any new Google Search Console owners have been added and the Wordfence firewall provides your site with protection.

As our site cleaning team often sees malicious property owners in Google Search Console added to hacked sites, we’ve included some guidance from them.

Monitoring

Google will alert you via email whenever a new Search Console owner has been added. If you receive one of these emails and have not recently added a new Google Search Console owner, take immediate action and remove the unknown owner.

Verifying and Removing Unwanted Owners

Even if you haven’t received any emails from Google alerting you to the presence of a new Google Search Console owner, you can verify owners from the Google Search Console dashboard.

Checking for Google Search Console users:

  1. Log into your Google Search Console and go to “Settings.” This is where you will find “Users and Permissions.”

    Google Search Console settings location.

  2. Click on “Users and Permissions.” You will see a list of all the Google Search Console users with their name, email address, and role.
  3. Review the users listed. Verify that there are no unknown owners listed.

If you do discover a rogue Google Search Console owner, please take the following actions:

  1. Click the three dots next to the site owner you would like to remove.

    Removing owner.

  2. Click on “Manage property Owners.” Here you can see a log of verification requests and can determine when owners were added, along with the ability to unverify any site owners.

    Managing property owners.

  3. Click “Unverify” for any rogue owner you would like to remove. This will un-verify that account and revoke access to the search console account.

    Un-verifying site owner.

Extra Precaution

Site Kit by Google provides functionality to reset a site’s connection with Site Kit. If you discover that a rogue Google Search Console owner has been added, then we recommend taking the extra step to reset Site Kit by Google on your WordPress site.

Resetting Site Kit by Google:

  1. Log into your WordPress site, and navigate to the Site Kit by Google’s “Settings.”

    Site Kit by Google settings.

  2. Navigate to “Admin Settings” and click on “Reset Site Kit.” Confirm the reset by clicking on “Reset” when prompted. This will reset your Site Kit connection and require you to reconnect any Google services that were previously connected.

    Resetting Site Kit by Google.

Wordfence is Keeping you Protected.

We released a firewall rule on April 21, 2020 to Wordfence Premium users that will block any verification attempts that do not come from administrators, which ultimately provides protection against the creation of any unwarranted Google Search Console owners.

Due to some limitations, the firewall cannot prevent the ProxySetupURL from being displayed in the source code. However, the firewall rule blocking verification requests is enough to provide optimal protection on a site using a vulnerable version of Site Kit by Google.

Free Wordfence users will receive this rule on May 21, 2020.

Proof of Concept Walkthrough

Disclosure Timeline

April 21, 2020 – Initial discovery and analysis of vulnerability. Firewall rule was released for Wordfence Premium customers. We submitted the vulnerability disclosure through Google’s Vulnerability Reward Program, as this appears to be their primary vulnerability disclosure channel.
April 22, 2020 – The vulnerability report was triaged and assigned by the Google Security team.
April 30, 2020 – The Google Security team notifies us that the vulnerability was verified and a bug was filed.
May 4, 2020A commit appears in Site Kit by Google Github Repository that appears to provide a patch for the vulnerability.
May 7, 2020A patch was released.
May 21, 2020 – Free Wordfence users receive firewall rule.

Conclusion

In today’s post, we detailed a flaw that allowed low-level WordPress users the ability to become a Google Search Console owner by exploiting a vulnerability in the Site Kit by Google plugin. This flaw has been fully patched in version 1.8.0. We recommend that users immediately update to the latest version available.

Sites running Wordfence Premium have been protected from attacks against this vulnerability since April 21, 2020. Sites running the free version of Wordfence will receive this firewall rule update on May 21, 2020. If you know a friend or colleague using this plugin on their site, we strongly recommend forwarding this advisory to them so that they can update and protect their Google Search Console account and WordPress site.

The post Vulnerability in Google WordPress Plugin Grants Attacker Search Console Access appeared first on Wordfence.

The Elementor Attacks: How Creative Hackers Combined Vulnerabilities to Take Over WordPress Sites

$
0
0

On May 6, our Threat Intelligence team was alerted to a zero-day vulnerability present in Elementor Pro, a WordPress plugin installed on approximately 1 million sites. That vulnerability was being exploited in conjunction with another vulnerability found in Ultimate Addons for Elementor, a WordPress plugin installed on approximately 110,000 sites.

We immediately released a firewall rule to protect Wordfence Premium users and contacted Elementor about the vulnerability. As this vulnerability was being actively exploited, we also publicly notified the community of the vulnerability to help protect users from being compromised.

Elementor quickly released an update for Elementor Pro the same day we published a notice on the Wordfence blog. In today’s post, we provide the technical details of the two vulnerabilities along with a closer look at how these two vulnerabilities were used together to compromise WordPress websites using these plugins.

We urge any website owners who have not yet updated to the latest versions of these plugins to do so immediately. For Elementor Pro, that is version 2.9.4 and in Ultimate Addons for Elementor, that is version 1.24.2.

Ultimate Addons for Elementor

Description: Registration Bypass
Affected Plugin: Ultimate Addons for Elementor
Plugin Slug: ultimate-elementor
Affected Versions: <= 1.24.1
CVE ID: CVE-2020-13125
CVSS Score: 7.2 (High)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Fully Patched Version: 1.24.2

Ultimate Addons for Elementor is a plugin made by Brainstorm Force. It is an extension to Elementor, providing many additional widgets to use with Elementor.

One of the widgets adds a registration form, called the “User Registration Form” to any page. This is an easily customizable registration form that can be placed anywhere on the site. Unfortunately, there was a flaw in the functionality of this form that allowed for users to register even when registration was disabled, and even if the form widget was not actively in use on the site.

Is User Registration enabled?

The developers registered both nopriv and regular AJAX actions tied to the get_form_data function in order to provide functionality for the User Registration Form widget.

	public function __construct() {
		parent::__construct();

		add_action( 'wp_ajax_uael_register_user', array( $this, 'get_form_data' ) );
		add_action( 'wp_ajax_nopriv_uael_register_user', array( $this, 'get_form_data' ) );
		add_filter( 'wp_new_user_notification_email', array( $this, 'custom_wp_new_user_notification_email' ), 10, 3 );

Diving into the get_form_data function, we see that it was designed to retrieve the information submitted in the registration form. This data was then used to create a new user on the site using the WordPress wp_insert_user hook. Nowhere in the function did it verify that user registration was enabled on the site, nor did it do any alternative checks to verify that the registration form widget was active.

	/**
	 * Get Form Data via AJAX call.
	 *
	 * @since 1.18.0
	 * @access public
	 */
	public function get_form_data() {

		check_ajax_referer( 'uael-form-nonce', 'nonce' );

		$data     = array();
		$error    = array();
		$response = array();

		if ( isset( $_POST['data'] ) ) {

			$data = $_POST['data'];

*Note several lines are omitted for brevity.

			$user_args = apply_filters(
					'uael_register_insert_user_args',
					array(
						'user_login'      => isset( $user_login ) ? $user_login : '',
						'user_pass'       => isset( $user_pass ) ? $user_pass : '',
						'user_email'      => isset( $user_email ) ? $user_email : '',
						'first_name'      => isset( $first_name ) ? $first_name : '',
						'last_name'       => isset( $last_name ) ? $last_name : '',
						'user_registered' => gmdate( 'Y-m-d H:i:s' ),
						'role'            => isset( $user_role ) ? $user_role : '',
					)
				);

				$result = wp_insert_user( $user_args );

These missing checks were what made it possible for attackers to bypass the user registration settings on a WordPress site. Fortunately, Brainstorm Force added checks in the latest version to verify both that user registration is enabled and that the widget is active.

	/**
	 * Get Form Data via AJAX call.
	 *
	 * @since 1.18.0
	 * @access public
	 */
	public function get_form_data() {

		check_ajax_referer( 'uael-form-nonce', 'nonce' );

		$data             = array();
		$error            = array();
		$response         = array();
		$allow_register   = get_option( 'users_can_register' );
		$is_widget_active = UAEL_Helper::is_widget_active( 'RegistrationForm' );

		if ( isset( $_POST['data'] ) && '1' === $allow_register && true === $is_widget_active ) {

			$data = $_POST['data'];

Registration Nonce is always displayed

Though nonces are primarily used to mitigate CSRF attacks and verify the legitimacy of a request, they can also act as a fail-safe in instances like this where a function contains a small flaw, that is, if the nonce is undiscoverable by an attacker.

The get_form_data function did use nonce verification that could have potentially stopped rogue user registration. However, we discovered that the form_nonce was always visible in the source code of a page where a UA for Elementor widget was enabled, even when there was no form present on the page.

/**
	 * Setup Actions Filters.
	 *
	 * @since 0.0.1
	 */
	private function setup_actions_filters() {

		add_shortcode( 'uael-template', array( $this, 'uael_template_shortcode' ) );

		add_action( 'elementor/init', array( $this, 'elementor_init' ) );

		add_action( 'elementor/elements/categories_registered', array( $this, 'widget_category' ) );

		add_action( 'elementor/frontend/after_register_scripts', array( $this, 'register_widget_scripts' ) );

*Note several lines are omitted for brevity.


			wp_localize_script(
			'jquery',
			'uaelRegistration',
			array(
				'invalid_mail'       => __( 'Enter valid Email!', 'uael' ),
				'pass_unmatch'       => __( 'The specified password do not match!', 'uael' ),
				'required'           => __( 'This Field is required!', 'uael' ),
				'form_nonce'         => wp_create_nonce( 'uael-form-nonce' ),
				'incorrect_password' => __( 'Error: The Password you have entered is incorrect.', 'uael' ),
				'invalid_username'   => __( 'Unknown username. Check again or try your email address.', 'uael' ),
				'invalid_email'      => __( 'Unknown email address. Check again or try your username.', 'uael' ),
			)
		);
	}

This meant that attackers just needed to scrape the source code of pages on a site running this plugin for var uaelRegistration. If that site had at least one widget in use on any page, they would be granted a usable nonce to register on the site.

A look at the discoverable UAE nonce in the source code of a page with a UAE widget enabled.

The Exploit

Combined, these flaws made it possible for attackers to register as a subscriber on any vulnerable site and potentially use that access to pivot and exploit vulnerabilities that required subscriber level access. This is precisely what we saw being exploited in the case of the Elementor Pro vulnerability.

Special thanks to Ramuel Gall for his research contributions on this vulnerability.

Elementor Pro

Description: Authenticated Arbitrary File Upload
Affected Plugin: Elementor Pro
Plugin Slug: elementor-pro
Affected Versions: <= 2.9.3
CVE ID: CVE-2020-13126
CVSS Score: 9.9 (Critical)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Fully Patched Version: 2.9.4

Elementor is a popular WordPress page builder plugin, currently installed on over 5 million WordPress sites. The Pro version adds additional enhancements like the ability to upload custom icons and fonts. It also adds over 50 additional widgets to improve the page building process along with enhanced customizability.

When a plugin introduces the ability to upload files, regardless of the file type, the proper control measures should always be included in order to prevent unauthorized users from uploading files or bypassing any file filters or privileges established on the site.

Unfortunately, the ‘Custom Icon’ upload functionality in Elementor Pro did not have appropriate measures in place. Attackers discovered an effective way to bypass restrictions on which file types could be uploaded, and once authenticated they were able to upload PHP files like webshells and backdoors.

Lack of Permissions Check

Elementor Pro registers an AJAX endpoint used to trigger the icon upload function. Neither the AJAX action nor the upload function had any permission checks, allowing any authenticated user, including those with minimal permissions, the ability to trigger the function and upload a .zip file.

	public function register_ajax_actions( Ajax $ajax ) {
		$ajax->register_ajax_action( 'pro_assets_manager_custom_icon_upload', [ $this, 'custom_icons_upload_handler' ] );

Fortunately, the patched version of the plugin implemented a permissions check on the custom_icons_upload_handler function that blocks low-level users from being able to upload files.

public function custom_icons_upload_handler( $data ) {
		if ( ! current_user_can( Icons_Manager::CAPABILITY ) ) {
			return new \WP_Error( Exceptions::FORBIDDEN, 'Access denied.' );
		}

Unchecked Uploads

It appears that the custom icon upload functionality was intended to only allow .zip files that were created from the Fontello, IcoMoon, or Fontastic icon creation sites. It did this by checking the files included in the .zip file and verifying that those aligned with the files generated from the trusted icon sources. However, the plugin never checks to verify if any additional files have been included in those .zip files.

	$supported_icon_sets = self::get_supported_icon_sets();
		foreach ( $supported_icon_sets as $key => $handler ) {
			/**
			 * @var IconSets\Icon_Set_Base $icon_set_handler
			 */
			$icon_set_handler = new $handler( $results['directory'] );

			if ( ! $icon_set_handler ) {
				continue;
			}
			if ( ! $icon_set_handler->is_valid() ) {
				continue;

This made it possible for attackers to include malicious files in a trusted .zip file, bypassing the restrictions the plugin had in place. This included .php files.

Discoverable Nonce

There was a nonce check on the function, but just like we saw in the Ultimate Addons for Elementor plugin, the nonce was easily discoverable due to being included in var elementorCommonConfig as “ajax” in the page source of all administrative dashboard pages.

A closer look at the Elementor Pro nonce discovered in the page source of /wp-admin.

An attacker could find a usable nonce by scraping the page source of the /wp-admin dashboard while authenticated. This could then be used as a legitimate Elementor AJAX nonce to execute the vulnerable action and upload crafted .zip files.

The Exploit

These three flaws made it possible for attackers to upload arbitrary files by creating a Fontello, IcoMoon, or Fontastic icon .zip file, extracting that file, injecting arbitrary files of their choice to the folder, re-compressing the .zip file and uploading it to the site via the AJAX action.

Uploaded .zip files are extracted into the /wp-content/upload/elementor/custom-icon directory in a newly generated folder. If the site owner previously had not uploaded any custom icons, the malicious files would be located in the /-1 folder. If there were previously uploaded custom-icon files that directory may have been a different number such as /-5, and the attacker would need to use brute force in order to find the directory into which their malicious payload had been extracted.

An attacker would be able access any newly uploaded files, like a webshell, by going directly to the file:

https://example.com/wp-content/wp-content/upload/elementor/custom-icon/-1/backdoor.php

If the file uploaded was a .php file, the code would also be executed upon access. This allowed for remote code execution (RCE) and ultimately the total compromise of the WordPress site and hosting environment.

Disclosure Timeline for Elementor Pro

May 5, 2020 – Wordfence notified of recently patched vulnerability in Ultimate Addons for Elementor. In the same notice, it was mentioned that Elementor Pro may have a “bug” that caused rogue files present in the /custom-icons directory. We begin to investigate Elementor Pro to determine if there is a security flaw present. We conclude that there is an authenticated arbitrary file upload vulnerability present.
May 5, 2020 – We quickly provision Premium customers with a firewall rule to provide protection against the vulnerability found in Elementor Pro.
May 5, 2020 – We contact the team at Elementor to alert them of the vulnerability’s presence.
May 5, 2020 – Hosting company provides us with log files that confirm this is being actively exploited.
May 6, 2020 – We publish a public service announcement with limited details to inform users how to secure their site until a patch is available.
May 6, 2020 – Elementor releases a patch for Elementor Pro.
June 4, 2020 – Wordfence free users receive firewall rule.

Attack Scenario Walkthrough

Conclusion

In today’s post, we provided technical details of the vulnerability found in the Elementor Pro plugin and how this vulnerability was used in active exploits in conjunction with the vulnerability found in Ultimate Addons for Elementor. These flaws have both been patched and we recommend that users update to the latest versions available immediately.

Sites running Wordfence Premium have been protected from attacks against the vulnerability in Elementor Pro since May 5, 2020. Sites running the free version of Wordfence will receive the firewall rule update on June 4, 2020. If you know a friend or colleague who is running one, or both, of these plugins on their site, we highly recommend forwarding this to them immediately to help them secure their site.

Special thank you to the team at Elementor for working quickly to get a patch out to protect Elementor Pro users. Also, thank you again to Ramuel Gall, Kathy Zant, Gerroald Barron, and Stephen Rees-Carter from the Wordfence team for their assistance in researching this attack and testing mitigations.

The post The Elementor Attacks: How Creative Hackers Combined Vulnerabilities to Take Over WordPress Sites appeared first on Wordfence.

High Severity Vulnerabilities in PageLayer Plugin Affect Over 200,000 WordPress Sites

$
0
0

A few weeks ago, our Threat Intelligence team discovered several vulnerabilities present in Page Builder: PageLayer – Drag and Drop website builder, a WordPress plugin actively installed on over 200,000 sites. The plugin is from the same creators as wpCentral, a plugin within which we recently discovered a privilege escalation vulnerability.

One flaw allowed any authenticated user with subscriber-level and above permissions the ability to update and modify posts with malicious content, amongst many other things. A second flaw allowed attackers to forge a request on behalf of a site’s administrator to modify the settings of the plugin which could allow for malicious Javascript injection.

We initially reached out to the plugin’s developer on April 30, 2020 and after establishing an appropriate communication channel, we provided the full disclosure on May 1, 2020. They responded quickly on May 2, 2020 letting us know that they were beginning to work on fixes. An initial patch was released on May 2, 2020 and an optimal patch was released on May 6, 2020.

These are considered high-level security issues that could potentially lead to attackers wiping your site’s content or taking over your site. We highly recommend an immediate update to the latest version available at the time of this publication, which is version 1.1.4.

Wordfence Premium customers received a new firewall rule on April 30, 2020, to protect against exploits targeting this vulnerability. Free Wordfence users will receive this rule after thirty days, on May 30, 2020.

Description: Unprotected AJAX and Nonce Disclosure to Stored Cross-Site Scripting and Malicious Modification
Affected Plugin: Page Builder: PageLayer – Drag and Drop website builder
Plugin Slug: pagelayer
Affected Versions: <= 1.1.1
CVE ID: Will be updated once identifier is supplied.
CVSS Score: 7.4 (High)
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:L
Fully Patched Version: 1.1.2

PageLayer is a very easy to use WordPress page builder plugin that claims to work with nearly all themes on the market and in the WordPress repository. It provides extended customization of pages through the use of widgets that can add page elements like buttons, tables, excerpts, products and more.

We discovered that nearly all of the AJAX action endpoints in this plugin failed to include permission checks. This meant that these actions could be executed by anyone authenticated on the site, including subscriber-level users. As standard, these AJAX endpoints only checked to see if a request was coming from /wp-admin through an authenticated session and did not check the capabilities of the user sending the request.

There were nonce checks in use in all of these functions, but nonces can be easily compromised if incorrectly implemented – for example, if a usable nonce is displayed within the source code of the site’s output. Unfortunately for the PageLayer plugin, this is precisely what happened. A usable nonce was visible in the header section of the source code of any page that had previously been edited using the PageLayer plugin. Any site visitor could find this nonce, whether they were logged in or not, allowing any unauthenticated user the ability to obtain a legitimate nonce for the plugin’s AJAX actions.

PageLayer nonce obtainable from page source.

Using a single nonce as the mechanism for authorization control caused various security issues in the functionalities of the page builder due to this nonce being so easily obtainable.

WordPress nonces should never be used as a means of authorization as they can easily be compromised if implemented improperly or if a loophole is found. WordPress nonces are designed to be used for CSRF protection, not authorization control. Implementing capability checks in conjunction with CSRF protection on sensitive functions for full verification provides protection to ensure a request is coming from an authorized user.

The Impact

As previously mentioned, several AJAX functions were affected, causing a large variety of potential impacts. A few of the most impactful actions were wp_ajax_pagelayer_save_content, wp_ajax_pagelayer_update_site_title, and wp_ajax_pagelayer_save_template.

add_action('wp_ajax_pagelayer_save_content', 'pagelayer_save_content');
add_action('wp_ajax_pagelayer_update_site_title', 'pagelayer_update_site_title');
add_action('wp_ajax_pagelayer_save_template', 'pagelayer_save_template');

The pagelayer_save_content function is used to save a page’s data through the page builder. The lack of permission checks on this function allowed authenticated users, regardless of permissions, the ability to change any data on a page edited with PageLayer.

function pagelayer_save_content(){

	// Some AJAX security
	check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce');

	$content = $_POST['pagelayer_update_content'];

	$postID = (int) $_GET['postID'];

	if(empty($postID)){
		$msg['error'] =  __pl('invalid_post_id');
	}

An attacker could wipe the pages completely or inject any content they would like on the site’s pages and posts. In addition, a few widgets allowed Javascript to be injected, including the “Button” widget. There is no sanitization on the “Button” widget’s text, which allows for malicious Javascript to be used as a text. This Javascript would execute once any user browsed to a page containing that button.

PageLayer button with alert JS injected.

The pagelayer_update_site_title function is used to update a site’s title. The lack of permission checks on this function allowed authenticated users the ability to change a site title to any title of their choosing. Though less detrimental, this could still affect your sites search engine ranking if unnoticed for an extended period of time.

function pagelayer_update_site_title(){
	global $wpdb;

	// Some AJAX security
	check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce');

	$site_title = $_POST['site_title'];

	update_option('blogname', $site_title);

	$wpdb->query("UPDATE `sm_sitemeta` 
				SET meta_value = '".$site_title."'
				WHERE meta_key = 'site_name'");
	wp_die();
}

The pagelayer_save_template function is used to save PageLayer templates for the PageLayer Theme Builder. The lack of permission checks on this function allowed authenticated users the ability to create new PageLayer templates that were saved as new posts.

function pagelayer_save_template() {
	
	// Some AJAX security
	check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce');
	
	$done = [];
	
	$post_id = (int) $_GET['postID'];
	
	// We need to create the post
	if(empty($post_id)){
	
		// Get the template type
		if(empty($_POST['pagelayer_template_type'])){
			$done['error'] = __pl('temp_error_type');
			pagelayer_json_output($done);
		}
		
		$ret = wp_insert_post([
			'post_title' => $_POST['pagelayer_lib_title'],
			'post_type' => 'pagelayer-template',
			'post_status' => 'publish',
			'comment_status' => 'closed',
			'ping_status' => 'closed'
		]);

Though this function was intended to be used in the PRO version of the plugin, the function could still be executed in the free version, affecting all 200,000+ users of the PageLayer plugin. An attacker could create a new template, which created a new page on the site, and inject malicious Javascript in the same way they could with the pagelayer_save_content function.

Malicious Javascript can be used to inject new administrative users, redirect site visitors, and even exploit a site’s user’s browser to compromise their computer.

The Patch

In the latest version of the plugin, the developers implemented permissions checks on all of the sensitive functions that could make changes to a site, and reconfigured the plugin to create separate nonces for the public and administrative areas of a WordPress site.

	// Are you allowed to edit ?
	if(!pagelayer_user_can_edit($postID)){
		$msg['error'][] =  __pl('no_permission');
		pagelayer_json_output($msg);
	}
Description: Cross-Site Request Forgery to Stored Cross-Site Scripting
Affected Plugin: Page Builder: PageLayer – Drag and Drop website builder
Plugin Slug: pagelayer
Affected Versions: <= 1.1.1
CVE ID: Will be updated once identifier is supplied.
CVSS Score: 8.8 (High)
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Fully Patched Version: 1.1.2

The PageLayer plugin registers a settings area where configuration changes can be made. This includes functionality such as where the editor is enabled, basic content settings, basic information configurations, and more.

PageLayer settings area.

The settings update function used a capability check to verify that a user attempting to make any changes had the appropriate permissions. However, there was no CSRF protection to verify the legitimacy of any request attempting to update a site’s settings. This made it possible for attackers to trick an administrator into sending a request to update any of the PageLayer settings.

function pagelayer_settings_page(){

	$option_name = 'pl_gen_setting' ;
	$new_value = '';

	if(isset($_REQUEST['pl_gen_setting'])){
		$new_value = $_REQUEST['pl_gen_setting'];
		
		if ( get_option( $option_name ) !== false ) {
	
			// The option already exists, so we just update it.
			update_option( $option_name, $new_value );

The “Information” tab in the settings area provides site owners with a way to set a default address, telephone number, and contact email address that are displayed whenever the corresponding widgets were used on a page. There was no sanitization on the address or telephone number settings, and due to the administrator’s capability to use unfiltered_html, Javascript could be injected into these settings.

PageLayer Address updated with alert JS.

The Impact

This allowed attackers the ability to inject malicious scripts while exploiting the CSRF vulnerability in the settings. If the widget was already enabled, any injected malicious scripts would execute whenever someone browsed to a page containing that widget. If the widget was not yet enabled, the malicious scripts could be executed once an administrator started editing and inserting the widget into a page. As always, these scripts can do things like create a new administrative account and redirect users to malicious sites.

The Patch

In the patched version of the plugin, the developers implemented CSRF protection consisting of a WordPress nonce and verification of that nonce when updating settings.

	if(isset($_REQUEST['submit'])){
		check_admin_referer('pagelayer-options');
	}

PoC Walkthrough: pagelayer_save_content

Disclosure Timeline

April 24, 2020 to April 30, 2020 – Initial discovery of minor security flaw and deeper security analysis of plugin.
April 30, 2020 – Firewall rule was released for Wordfence Premium customers. We made our initial contact attempt with the plugin’s development team.
May 1, 2020 – The plugin’s development team confirms appropriate inbox for handling discussion. We provide full disclosure.
May 2, 2020 – Developer acknowledges receipt and confirms that they are beginning to work on fixes. An update is released the same day.
May 4, 2020 – We analyze the fixes and discover a few security issues left unpatched and responsibly disclose these issues to the developer.
May 6, 2020 – Developer releases the final sufficient patch.
May 30, 2020 – Free Wordfence users receive firewall rule.

Conclusion

In today’s post, we detailed several flaws related to unprotected AJAX actions and nonce disclosure that allowed for attackers to make several malicious modifications to a site’s pages and posts in addition to providing attackers with the ability to inject malicious Javascript. These flaws have been fully patched in version 1.1.2. We recommend that users immediately update to the latest version available, which is version 1.1.4 at the time of this publication.

Sites running Wordfence Premium have been protected from attacks against this vulnerability since April 30, 2020. Sites running the free version of Wordfence will recieve this firewall rule update on May 30, 2020. If you know a friend or colleague who is using this plugin on their site, we highly recommend forwarding this advisory to them to help keep their sites protected.

The post High Severity Vulnerabilities in PageLayer Plugin Affect Over 200,000 WordPress Sites appeared first on Wordfence.

Large Scale Attack Campaign Targets Database Credentials

$
0
0

Between May 29 and May 31, 2020, the Wordfence Firewall blocked over 130 million attacks intended to harvest database credentials from 1.3 million sites by downloading their configuration files.

The peak of this attack campaign occurred on May 30, 2020. At this point, attacks from this campaign accounted for 75% of all attempted exploits of plugin and theme vulnerabilities across the WordPress ecosystem.

A graph showing the spike in attacks
We were able to link these attacks to the same threat actor previously targeting XSS vulnerabilities at a similar scale. All Wordfence users, including Wordfence Premium and those still using the free version of Wordfence, are protected by our firewall’s built-in directory traversal protection.

Different vulnerabilities, same IPs

The previously reported XSS campaigns sent attacks from over 20,000 different IP addresses. The new campaign is using the same IP addresses, which accounted for the majority of the attacks and sites targeted. This campaign is also attacking nearly a million new sites that weren’t included in the previous XSS campaigns.

As with the XSS campaigns, almost all of the attacks are targeted at older vulnerabilities in outdated plugins or themes that allow files to be downloaded or exported. In this case the attackers are attempting to download wp-config.php, a file critical to all WordPress installations which contains database credentials and connection information, in addition to authentication unique keys and salts. An attacker with access to this file could gain access to the site’s database, where site content and users are stored.

Indicators of Compromise

Attacks by this campaign should be visible in your server logs. Look for any log entries containing wp-config.php in the query string that returned a 200 response code.

The top 10 attacking IP addresses in this campaign are listed below.

200.25.60.53
51.255.79.47
194.60.254.42
31.131.251.113
194.58.123.231
107.170.19.251
188.165.195.184
151.80.22.75
192.254.68.134
93.190.140.8

What should I do?

Sites running Wordfence are protected against this campaign. If your site is not running Wordfence, and you believe you have been compromised, change your database password and authentication unique keys and salts immediately.

If your server is configured to allow remote database access, an attacker with your database credentials could easily add an administrative user, exfiltrate sensitive data, or delete your site altogether. Even if your site does not allow remote database access, an attacker who knows your site’s authentication keys and salts may be able to use them to more easily bypass other security mechanisms.

If you’re not comfortable making the changes above, please contact your host, since changing your database password without updating the wp-config.php file can temporarily take down your site.

Conclusion

In today’s post, we covered another large-scale attack campaign against WordPress sites by a threat actor we have been tracking since February. All Wordfence users, including sites running the free version of Wordfence, and Wordfence Premium, are protected against these attacks. Nonetheless, we urge you to make sure that all plugins and themes are kept up to date, and to share this information with any other site owners or administrators you know. Attacks by this threat actor are evolving and we will continue to share additional information as it becomes available.

The post Large Scale Attack Campaign Targets Database Credentials appeared first on Wordfence.

WordPress 5.4.2 Patches Multiple XSS Vulnerabilities

$
0
0

WordPress Core version 5.4.2 has just been released. Since this release is marked as a combined security and bug fix update, we recommend updating as soon as possible. With that said, most of the security fixes themselves are for vulnerabilities that would require specific circumstances to exploit. All in all this release contains 6 security fixes, 3 of which are for XSS (Cross-Site Scripting) vulnerabilities. Both the free and Premium versions of Wordence have robust built-in XSS protection which will protect against potential exploitation of these vulnerabilities.

A Breakdown of each security issue

An XSS issue where authenticated users with low privileges are able to add JavaScript to posts in the block editor

This flaw would have made it possible for an attacker to inject JavaScript into a post by manipulating the attributes of Embedded iFrames. This would be exploitable by users with the edit_posts capability, meaning users with the Contributor role or higher in most configurations.

The changeset in question is:
https://core.trac.wordpress.org/changeset/47947/

This issue was discovered and reported by Sam Thomas (jazzy2fives)

An XSS issue where authenticated users with upload permissions are able to add JavaScript to media files

This flaw would have made it possible for an attacker to inject JavaScript into the “Description” field of an uploaded media file. This would be exploitable by users with the upload_files capability, meaning users with the Author role or higher in most configurations.

The changeset in question is:
https://core.trac.wordpress.org/changeset/47948/

This issue was discovered and reported by Luigi – (gubello.me)

An open redirect issue in wp_validate_redirect()

For this flaw, the wp_validate_redirect function failed to sufficiently sanitize URLs supplied to it. As such it would have been possible under certain circumstances for an attacker to craft a link to an impacted site that would redirect visitors to a malicious external site. This would not require specific capabilities, but it would typically require either social engineering or a separate vulnerability in a plugin or theme to exploit.

The changeset in question is:
https://core.trac.wordpress.org/changeset/47949/

This issue was discovered and reported by Ben Bidner of the WordPress Security Team.

An authenticated XSS issue via theme uploads

This flaw would have made it possible for an attacker to inject JavaScript into the stylesheet name of a broken theme, which would then be executed if another user visited the Appearance->Themes page on the site. This would be exploitable by users with the install_themes or edit_themes capabilities, which are only available to administrators in most configurations.

The changeset in question is:
https://core.trac.wordpress.org/changeset/47950/

This issue was discovered and reported by Nrimo Ing Pandum

An issue where set-screen-option can be misused by plugins leading to privilege escalation

For this flaw, a plugin incorrectly using the set-screen-option filter to save arbitrary or sensitive options could potentially be used by an attacker to gain administrative access. We are not currently aware of any plugins that are vulnerable to this issue.

The changeset in question is:
https://core.trac.wordpress.org/changeset/47951/

This issue was discovered and reported by Simon Scannell of RIPS Technologies

An issue where comments from password-protected posts and pages could be displayed under certain conditions

For this flaw, comment excerpts on password-protected posts could have been visible on sites displaying the “Recent Comments” widget or using a plugin or theme with similar functionality.

The changeset in question is:
https://core.trac.wordpress.org/changeset/47984/

This issue was discovered and reported by Carolina Nymark

Note: This is unrelated to an issue where unmoderated spam comments were briefly visible and indexable by search engines.

What should I do?

Most of these vulnerabilities appear to be exploitable only under limited circumstances or by trusted users, but we recommend updating as soon as possible. Attackers may find ways to exploit them more easily, or the researchers who discovered these vulnerabilities may publish Proof of Concept code that allows simpler exploitation. This is a minor WordPress release, so most sites will automatically update to the new version.

Conclusion

We’d like to thank the WordPress core team and the researchers who discovered and responsibly reported these vulnerabilities for making WordPress safer for everyone.

You can find the official announcement of the WP 5.4.2 release on this page. If you have any questions or comments, please don’t hesitate to post them below and we’ll do our best to answer them in a timely manner. If you are one of the researchers whose work is included above and would like to provide additional detail or corrections, we welcome your comments.

Special thanks to QA Lead Matt Rusnak for helping to identify the changesets associated with these fixes.

The post WordPress 5.4.2 Patches Multiple XSS Vulnerabilities appeared first on Wordfence.


Malware Detection: Measuring Recall to Catch Them All

$
0
0

At Wordfence, we take performance seriously on all levels. While speed is one way to measure performance, there are other metrics that are equally important. Over the past year, our Threat Intelligence team has improved our malware scan by leaps and bounds. We wanted to share some of the metrics we use and what they mean for our customers. We’ll also take a brief look at the new Jetpack Scan and see how it compares.

Measuring Recall to catch them all

Wordfence currently has more than 1.5 million malware samples on file, ranging from backdoors and shells to SEO spam. At any given time we use several thousand “signatures” to detect these malicious files. A signature is a pattern that is used to algorithmically match malware. Our signatures use regular expressions that are optimized to be highly performant and compatible with a range of platforms, from PHP regex to server-based pattern engines.

One of the most important metrics we use is Recall. Simply put, Recall is the percentage of known malicious files that are detected by our signatures.

Over the past year we have continuously improved this recall rate, and currently our signatures detect over 98% of known malicious content. Our Threat Intelligence team is constantly adding to and improving on these signatures, in order to detect emerging threats.

Keeping False Positives low

It’s just as important to make sure that our scanner doesn’t mistake legitimate software for malware. This is a situation known as a False Positive. We have a number of ways to prevent our customers from experiencing False Positives, and very few customers will ever see one.

Preventing False Positives starts with the malware detection signatures themselves, and we test them against millions of examples of legitimate web application code, ranging from popular plugins to home-brewed contact forms.

Over the past year we have improved the False Positive rate of our malware signatures from 1.1% to less than 0.03%. That is, our signatures mistakenly detect less than 3 in 10,000 known good files.

Speed is still critical

We measure each malware detection signature to ensure it doesn’t slow down the Wordfence scanner, replacing slow signatures with faster ones that detect even more malware. Over the past year, the combined speed of our malware detection signatures has increased by over 70%, which means Wordfence can scan your site faster than ever before.

How the competition measures up

We recently had an opportunity to test the performance of the new Jetpack Scan. Similar to the Vaultpress scan that was previously available as a Jetpack upgrade, Jetpack Scan uploads a helper file to your site and downloads any files it finds to their servers in order to scan them for malware.

For each of our malware detection signatures, we placed a malicious file that was detected by that particular signature on a test server in the wp-content/uploads folder. After running the Jetpack Scan, we found that it had a recall rate of 11.5%. We used a total of 2982 malware samples in the test from our collection of over 1.5 million samples. That means that for a total of 2982 malware samples, 342 were detected by Jetpack in our testing.

It’s worth noting that our scan had a 100% recall rate on these samples, but that is because these are samples that we know of. So there is a case of selection bias here in that we are choosing samples that we already detect. While our collection of 1.5 million malware samples is substantial, we do not know the size of Jetpack’s own malware collection, and how their recall rate compares against their own collection. It is possible their collection contains malware that we don’t know about, and that their scanner has an enormously high detection rate for malware that is simply not on our radar.

Much of our own malware database comes from our site cleaning business, where we analyze sites that have been hacked, and where we collect indicators of compromise, including malware samples, malicious IP addresses, and malicious domains. Having a constant flow of customers that have encountered a real-world intrusion provides us with a continuous portrait of emerging threats.

We were unable to test Jetpack Scan’s False Positive rate since this would have required a much larger number of files to be scanned.

Conclusion

In this article, we have covered some of the ways we measure malware scan performance, how our performance has changed over time, and how Jetpack Scan compares. Knowing how to measure performance is important, but it is only the first step. The large and rapid improvements we have made in malware detection have been the result of a concerted and ongoing effort by the Wordfence team. We improved because we made it a priority, and it is a priority because we have a team that is dedicated to making WordPress safer.

The post Malware Detection: Measuring Recall to Catch Them All appeared first on Wordfence.

Critical Vulnerabilities Patched in Adning Advertising Plugin

$
0
0

On June 24, 2020, our Threat Intelligence team was made aware of a possible vulnerability in the Adning Advertising plugin, a premium plugin with over 8,000 customers. We eventually discovered 2 vulnerabilities, one of which was a critical vulnerability that allowed an unauthenticated attacker to upload arbitrary files, leading to Remote Code Execution(RCE), which could allow complete site takeover.

The next day, on June 25, 2020, we privately disclosed these vulnerabilities to the plugin’s author, Tunafish. A patched version was made available in less than 24 hours, on June 26, 2020. We strongly recommend updating to the latest version of this plugin, 1.5.6, immediately.

Wordfence Premium users received a firewall rule protecting against these vulnerabilities on June 25, 2020. Users still running the free version of Wordfence will receive this rule on July 25, 2020.

After monitoring attacks against this firewall rule, we determined that, although these vulnerabilities were being attacked in the wild, the attacks were extremely limited in scope and scale. As such we withheld details from public disclosure for a short period of time to allow users time to update and prevent more widespread exploitation.


Description: Unauthenticated Arbitrary File Upload leading to Remote Code Execution
Affected Plugin: Adning Advertising
Plugin Slug: angwp
Affected Versions: < 1.5.6
CVE ID: N/A
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
CVSS score: 10.0(critical)
Patched Version: 1.5.6

One functionality of the Adning plugin is to allow users to upload banner images. In order to provide this functionality, it used an AJAX action, _ning_upload_image. Unfortunately this AJAX action was available with a nopriv_ hook, meaning that any visitor to the site could make use of it, even if they were not logged in. Additionally, the function called by this AJAX action also failed to make use of a capability check or a nonce check.

	public static function _ning_upload_image()
	{
		$_action = isset($_POST['action']) ? $_POST['action'] : '';
		$user_id = isset($_POST['uid']) ? $_POST['uid'] : 0;
		$banner_id = isset($_POST['bid']) ? $_POST['bid'] : 0;
		$max_upload_size = isset($_POST['max_upload_size']) ? $_POST['max_upload_size'] : 100;
		$upload = isset($_POST['upload']) ?  json_decode(stripslashes($_POST['upload']), true) : array();
		$valid_formats = isset($_POST['allowed_file_types']) ? explode(',', $_POST['allowed_file_types']) : array('jpg');
		if( in_array('jpg', $valid_formats) )
		{
			$valid_formats[] = 'jpeg';
		}
		
		//$max_file_size = 1024*100; //100 kb
		//$max_file_size = 1024000*15; // 15 MB (1 mb = 1000 kb)
		$max_file_size = 1024000*$max_upload_size;
		
		//$upload_path = $upload_dir.'/'.$upload_folder;
		//$upload_path = $upload_path.$upload_folder;
		$upload_path = $upload['dir'].$upload['folder'];
		$count = 0;

		// Create upload folder if not exists
		if(!is_dir($upload_path)) {
		    mkdir($upload_path, 0777, true);
		}

		if(!empty($_FILES['files'])) 
		{
			$upload_success = false;
			$upload_error = '';
			$uploaded_files = array();
			$unzip_error = array();

			// Loop $_FILES to execute all files
			foreach ($_FILES['files']['name'] as $f => $name) 
			{     
			    if ($_FILES['files']['error'][$f] == 4) 
			    {
			        continue; // Skip file if any error found
			    }	       
			    if ($_FILES['files']['error'][$f] == 0) 
			    {	           
			        if ($_FILES['files']['size'][$f] > $max_file_size) 
			        {
			            $upload_error = $name. " is too large!";
			            continue; // Skip large files
			        }
					elseif( !in_array(pathinfo($name, PATHINFO_EXTENSION), $valid_formats) )
					{
						$upload_error = $name." is not a valid format";
						continue; // Skip invalid file formats
					}
			        else
			        { 
			        	// No error found! Move uploaded files 
			            if(move_uploaded_file($_FILES["files"]["tmp_name"][$f], $upload_path.$name)){
			            	$count++; // Number of successfully uploaded file
							$src = $upload['src'].$upload['folder'].$name;

			            	// Copy image to banner folder
			            	/*if(!empty($banner_id))
			        		{
			        			if(!is_dir($upload_dir.'/'.$banner_folder)) {
								    mkdir($upload_dir.'/'.$banner_folder, 0777, true);
								}
			        			copy($path.$name, $upload_dir.'/'.$banner_folder.$name);
			        		}*/

			        		$uploaded_files[] = array(
			        			'name' => $name, 
								'size' => $_FILES['files']['size'][$f],
								'upload' => $upload,
								'path' => $upload_path.$name,
			        			'src' => $src,
			        			'grid_item' => '<div class="grid-item" data-src="'.$src.'" data-use="path"><img src="'.$src.'" /><div class="info_btn" data-info="'.basename($src).'"><svg viewBox="0 0 448 512" style="height:18px;border-radius:2px;"><path fill="currentColor" d="M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zm-176 86c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z" class=""></path></svg></div></div>',
			        			'uid'  => $user_id,
			        			'action'  => $_action
							);
							
							
							if( pathinfo($name, PATHINFO_EXTENSION) == 'zip')
							{
								$zipfile = array(
									'name' => $_FILES['files']['name'][$f],
									'type' => $_FILES['files']['type'][$f],
									'tmp_name' => $_FILES['files']['tmp_name'][$f],
									'error' => $_FILES['files']['error'][$f],
									'size' => $_FILES['files']['size'][$f],
								);
								
								$unzip_error = self::upload_and_unzip($zipfile, array('folder' => $upload['folder'], 'path' => $upload_path, 'src' => $upload['src']));
							}
						}
						else
						{
							$upload_error = is_writable($upload_path) ? 'Could not move files.' : 'Folder is not writable.';
						}
			        }
			    }
			}

			if(count($uploaded_files) > 0){
				$upload_success = true;
			}

			echo json_encode(array("chk" => $_FILES['files'], "unzip" => $unzip_error, "upload" => $upload, "success" => $upload_success, "files" => json_encode($uploaded_files), "error" => $upload_error));
		}else{
			echo 'no files found.';
		}
		exit;
	}

This function also allowed the user to supply the “allowed” file types. As such it was possible for an unauthenticated attacker to upload malicious code by sending a POST request to wp-admin/admin-ajax.php with the action parameter set to _ning_upload_image the allowed_file_types set to php, and a files parameter containing a malicious PHP file. Alternatively, an attacker could set the allowed_file_types to zip and upload a compressed archive containing a malicious PHP file, which would be unzipped after upload. It was also possible for an attacker to change the upload directory by manipulating the contents of the upload parameter – if the desired directory did not exist, the plugin would create it.


Description: Unauthenticated Arbitrary File Deletion via path traversal
Affected Plugin: Adning Advertising
Plugin Slug: angwp
Affected Versions: < 1.5.6
CVE ID: N/A
CVSS Vector: CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:H/A:H
CVSS score: 8.7(high)
Patched Version: 1.5.6

In order to delete any uploaded images, the plugin also registered another ajax action, _ning_remove_image, which also used a nopriv_ hook. As with the upload vulnerability, this function did not perform a capability check or a nonce check. As such it was possible for an unauthenticated attacker to delete arbitrary files using path traversal.

If an attacker were able to delete wp-config.php, the site would be reset, and an attacker could then set it up again and point it to a remote database under their control, effectively replacing the site’s content with their own content.

	public static function _ning_remove_image()
	{
		$upload = wp_upload_dir();
		$upload_dir = $upload['basedir'];
		$upload_url = $upload['baseurl'];
		$upload_folder = self::$upload_folder.$_POST['uid'].'/';	

		$path = $upload_dir.'/'.$upload_folder.basename($_POST['src']);
		$removed = 0;

		if(unlink($path)){
			$remove = 1;
		}
		echo $remove;

		exit;
	}

This attack might require an extra step of preparation, which is that the wp-content/uploads/path folder would need to exist. However, since the previously mentioned arbitrary file upload vulnerability allowed for directory creation, this was not a major obstacle. Once the directory was created, an attacker could send a POST request to wp-admin/admin-ajax.php with the action parameter set to _ning_remove_image, the uid parameter set to /../../.. and the src parameter set to wp-config.php.

Timeline

June 24, 2020 – Wordfence Threat Intelligence receives a report of a compromised website running the Adning plugin. During our investigation, we discovered two vulnerabilities.
June 25, 2020 – Firewall rule released for Premium Wordfence users. We make initial contact with plugin’s author and send full disclosure after receiving a response.
June 26, 2020 – Plugin’s author releases a patch.
July 25, 2020 – Firewall rule becomes available to Wordfence free users.

Conclusion

In today’s post, we discussed two vulnerabilities in the Adning Advertising plugin which could allow an attacker to completely take over a website. These flaws have been fully patched in version 1.5.6. If you are running this plugin, it is critical that you updated to this version as soon as possible. Sites running Wordfence Premium have been protected against these vulnerabilities since June 25, 2020, while sites still using the free version of Wordfence will receive the firewall rule on July 25, 2020.

Special Thanks to Tunafish, the author of the Adning Advertising plugin, for their excellent and timely response in releasing a patch.

The post Critical Vulnerabilities Patched in Adning Advertising Plugin appeared first on Wordfence.

XSS Flaw Impacting 100,000 Sites Patched in KingComposer

$
0
0

On June 15, 2020, our Threat Intelligence team was made aware of a number of access control vulnerabilities that had recently been disclosed in KingComposer, a WordPress plugin installed on over 100,000 sites. During our investigation of these vulnerabilities, we discovered an unpatched reflected Cross-Site Scripting(XSS) vulnerability.

Wordfence Premium customers received a new firewall rule the same day, protecting against the newly patched access control vulnerabilities as well as the unpatched Cross-Site Scripting vulnerability. Wordfence users still using the free version will receive this rule after 30 days, on July 15, 2020.

We attempted to contact the plugin’s developers the next day, on June 16, 2020. Since we did not receive a response after 9 days, we contacted the WordPress Plugins team on June 25, 2020. The WordPress Plugins team replied the next day and let us know that they were in touch with the developers of the KingComposer plugin, and a patch was released on June 29, 2020.

What is Reflected Cross-Site Scripting(XSS)?

We’ve written a number of articles about Stored Cross-Site Scripting(XSS) vulnerabilities in the past, and how they can be used to take over a website if an administrator accesses a page on their site containing a malicious JavaScript. We’ve also written about Cross-Site Request Forgery(CSRF) attacks, where an attacker can trick a victim into clicking a specially crafted link in order to make changes to a site.

Reflected XSS vulnerabilities have characteristics of both of these vulnerabilities. Much like a CSRF attack, exploiting a Reflected XSS vulnerability usually relies on an attacker tricking their victim into clicking a malicious link which sends the victim to the vulnerable site along with a malicious payload. This can be done in a number of ways, but it is common to first link to an intermediate site controlled by the attacker, which then sends a request containing a malicious payload to the vulnerable site on behalf of the victim.

A notable distinction between the stored XSS vulnerabilities more commonly found and reflected XSS vulnerabilities such as this, is that the malicious scripts that are used as part of the exploit are not actually stored anywhere in the database with reflected XSS vulnerabilities. Rather, the malicious scripts are reflected and executed once during the exploit.

As with Stored XSS attacks, the malicious payload will be executed in the victim’s browser. However, with reflected XSS, the vulnerable site would immediately output (reflect) the malicious JavaScript payload, which would be executed a single time in the victim’s browser instead of being stored in the database for later execution.

This could be used in a variety of attacks. For instance, if the victim was a logged-in administrator on the vulnerable site, the reflected JavaScript could be used to create a new, malicious administrator account controlled by the attacker.

In order for reflected XSS attacks to successfully exploit a user, an attacker needs to trick the user into performing an action. For that reason, we highly recommend remaining vigilant when clicking on links or attachments in comments, emails, and other communication sources unless you are sure of their integrity and legitimacy.


Description: Reflected Cross-Site Scripting(XSS)
Affected Plugin: Page Builder: KingComposer – Free Drag and Drop page builder by King-Theme
Plugin Slug: kingcomposer
Affected Versions: < 2.9.5
CVE ID: CVE-2020-15299
CVSS Score: 6.1(medium)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
Fully Patched Version: 2.9.5

KingComposer is a WordPress plugin that allows Drag and Drop page building, and it registers a number of AJAX actions to accomplish this. One of these AJAX actions was no longer actively used by the plugin, but could still be used by sending a POST request to wp-admin/admin-ajax.php with the action parameter set to kc_install_online_preset.

The vulnerable function:

	public function install_online_preset(){

		$data = isset($_POST['kc-online-preset-data']) ? esc_attr($_POST['kc-online-preset-data']) : '';
		$link = isset($_POST['kc-online-preset-link']) ? esc_url($_POST['kc-online-preset-link']) : '';
		$link = str_replace( 'http://features.kingcomposer.com/', 'https://kingcomposer.com/presets/', $link);
		$callback = '
		<script type="text/javascript">
			top.kc.cfg.preset_link = "'.$link.'";
			top.kc.backbone.push(\''.str_replace( "\n", '\'+"\n"+\'', base64_decode($data)).'\');
			top.kc.tools.popup.close_all();
		</script>';

		echo $callback;

		exit;

	}

This function renders a JavaScript based on the contents of the kc-online-preset-link and kc-online-preset-data parameters. Since it uses the esc_attr and esc_url functions, it appears safe at first glance. Unfortunately, however, the contents of the kc-online-preset-data parameter are base64-decoded after this step.

As such, if an attacker used base64-encoding on a malicious payload, and tricked a victim into sending a request containing this payload in the kc-online-preset-data parameter, the malicious payload would be decoded and executed in the victim’s browser. The patched version of this plugin resolved the issue by removing the vulnerable function entirely.

Disclosure Timeline

June 15, 2020 – The Wordfence Threat Intelligence team discovers an unpatched vulnerability while investigating newly patched vulnerabilities in the KingComposer plugin. We release a firewall rule covering both the patched and unpatched vulnerabilities to our Premium users.
June 16, 2020 – We attempt to contact the developers of the KingComposer plugin.
June 25, 2020 – We contact the WordPress Plugins team about the vulnerability.
June 26, 2020 – The WordPress Plugins team responds and indicates that they are in touch with the developers of the KingComposer plugin.
June 29, 2020 – Patched version of KingComposer is released.
July 15, 2020 – Firewall rule becomes available to Wordfence Free users.

Conclusion

In today’s blog post, we discussed a Reflected Cross-Site Scripting(XSS) vulnerability in the KingComposer WordPress plugin, and provided some background information on how Reflected XSS attacks work. This vulnerability has been fully patched in version 2.9.5 and we strongly recommend updating to this version immediately. Sites running Wordfence Premium have been protected against this vulnerability, as well as older vulnerabilities in the KingComposer plugin, since June 15, 2020. Sites still using the free version of Wordfence will receive the firewall rule update on July 15, 2020.

The post XSS Flaw Impacting 100,000 Sites Patched in KingComposer appeared first on Wordfence.

2 Million Users Affected by Vulnerability in All in One SEO Pack

$
0
0

On July 10, 2020, our Threat Intelligence team discovered a vulnerability in All In One SEO Pack, a WordPress plugin installed on over 2 million sites. This flaw allowed authenticated users with contributor level access or above the ability to inject malicious scripts that would be executed if a victim accessed the wp-admin panel’s ‘all posts’ page.

We reached out to the plugin’s team the same day of discovery on July 10, 2020 and a patch was released just a few days later on July 15, 2020.

This is considered a medium severity security issue that, as with all XSS vulnerabilities, can result in complete site takeover and other severe consequences. We strongly recommend immediately updating to the latest version of this plugin. At the time of writing, that is version 3.6.2 of All in One SEO Pack.

Wordfence Premium customers received a new firewall rule on July 10, 2020 to protect against exploits targeting this vulnerability. Free Wordfence users will receive this rule after thirty days, on August 9, 2020.


Description: Authenticated Stored Cross-Site Scripting
Affected Plugin: All in One SEO Pack
Plugin Slug: all-in-one-seo-pack
Affected Versions: <= 3.6.1
CVE ID: Pending.
CVSS Score: 5.4 (Medium)
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
Fully Patched Version: 3.6.2

All In One SEO Pack is a plugin that provides several SEO enhancing features to help rank a WordPress site’s content higher on search engines. As part of its functionality, it allows users that have the ability to create or edit posts to set an SEO title and SEO description directly from a post as it is being edited. This makes it easier for post creators to improve the SEO of posts as they are writing them. This feature is available to all users that can create posts, such as contributors, authors, and editors.

Unfortunately, the SEO meta data for posts, including the SEO title and SEO description fields, had no input sanitization allowing lower-level users like contributors and authors the ability to inject HTML and malicious JavaScript into those fields.

	/**
	 * Saves the data of our metabox settings for a post.
	 *
	 * @since   ?
	 * @since   3.4.0   Added support for priority/frequency + minor refactoring.
	 *
	 * @param   int     $id     The ID of the post.
	 * @return  bool            Returns false if there is no POST data.
	 */
	function save_post_data( $id ) {
		$awmp_edit = null;
		$nonce     = null;

		if ( empty( $_POST ) ) {
			return false;
		}

		if ( isset( $_POST['aiosp_edit'] ) ) {
			$awmp_edit = $_POST['aiosp_edit'];
		}

		if ( isset( $_POST['nonce-aioseop-edit'] ) ) {
			$nonce = $_POST['nonce-aioseop-edit'];
		}

		if ( isset( $awmp_edit ) && ! empty( $awmp_edit ) && wp_verify_nonce( $nonce, 'edit-aioseop-nonce' ) ) {

			$optlist = array(
				'keywords',
				'description',
				'title',
				'custom_link',
				'sitemap_exclude',
				'disable',
				'disable_analytics',
				'noindex',
				'nofollow',
				'sitemap_priority',
				'sitemap_frequency',
			);

			if ( empty( $this->options['aiosp_can'] ) ) {
				unset( $optlist['custom_link'] );
			}

			if ( ! AIOSEOPPRO ) {
				$optlist = array_diff( $optlist, array( 'sitemap_priority', 'sitemap_frequency' ) );
			}

			foreach ( $optlist as $optionName ) {
				$value = isset( $_POST[ "aiosp_$optionName" ] ) ? $_POST[ "aiosp_$optionName" ] : '';
				update_post_meta( $id, "_aioseop_$optionName", $value );
			}
		}
	}

Here is a look at where these fields can be edited in the post editor:

SEO area in post from All in One SEO Pack.

The SEO title and SEO description for each post are always displayed on the ‘all posts’ page as they appear in the far right column for easier quick editing access. Therefore, any values added to the SEO title and SEO description fields would be displayed here in an unsanitized format, causing saved JavaScript in these fields to be executed when any user accessed the ‘all posts’ page.

The SEO Title and SEO Description areas that appear on the ‘all posts’ admin area.

Any JavaScript injected in the SEO description field would also be executed when visiting the page directly if a closing tag was inserted by an attacker before adding their own script. For example, it could look like </script><script>alert(0)</script>. This was due to the fact that the tag would close out the SEO description’s original script tag and inject an additional script directly after.

Using a closing script tag to start a new script.

Due to the JavaScript being executed whenever a user accessed the ‘all posts’ page, this vulnerability would be a prime target for attackers that are able to gain access to an account that allows them to post content. Since Contributors must submit all posts for review by an Administrator or Editor, a malicious Contributor could be confident that a higher privileged user would access the ‘all posts’ area to review any pending posts. If the malicious JavaScript was executed in an Administrator’s browser, it could be used to inject backdoors or add new administrative users and take over a site.

Fortunately, in the patched version, the plugin developer has added sanitization to all of the SEO post meta values so any HTML characters supplied will be escaped and unable to become executable scripts.

Proof of Concept Walkthrough

How Concerning Is a Contributor+ vulnerability?

The great news about this vulnerability is that it requires a high level of permissions to exploit, making it more difficult for attackers to actually utilize in an attack. Therefore, it is less likely to be targeted as part of a mass automated campaign. It could, however, be one additional method of escalating a more sophisticated attack. As such, there are a few security precautions you should always remember to take to help protect your site against vulnerabilities targeting higher-level user exploits.

Always use the principle of least privilege.
Least privilege is a security concept that suggests that users be provided with the minimal amount of privileges required to do their job. This means that when you are supplying users with access to your site, you should make sure you are providing them with the least amount of privileges needed to perform any needed actions. If your users don’t need to write posts but need an account, make sure you are only providing them with subscriber-level access or equivalent. You can read more about WordPress Roles and Capabilities here.

We understand that in some cases you may need to provide users with slightly more privileges to do certain tasks than their normal day-to-day routine. In these cases, we recommend providing users with temporarily elevated privileges and then revoking those privileges once the task has been completed.

For example, if you want to have someone write a guest post on your WordPress blog, we recommend providing them with contributor-level access to write the post and then, once they are finished, downgrade their privileges to subscriber-level. Once they are done writing the guest post they no longer need contributor-level privileges, therefore, maintaining the principle of least privilege by downgrading those privileges is optimal for your site’s security.

Along with this, we recommend auditing your site’s user accounts to make sure there are no rogue or left-over accounts that should be deleted. Leaving unused accounts on a site provides attackers with more possible intrusion vectors for exploiting vulnerabilities that require higher-level permissions.

Trust and verification are important when providing users with access to your site.
When providing users with higher-level roles like contributor, author, and editor, we highly recommend verifying that the user can be trusted. This can be done by checking personal references or establishing security protocols limiting access to people who work for reputable companies.

If someone calls you, sends you an email, or contacts you in any way saying they need access to your site for any reason, and it’s not coming from someone you know and trust, then it might be a social engineering attempt. Never provide credentials or user account access unless you can trust and verify who you are providing that information to.

Always remember to never share accounts or passwords. Instead, establish separate accounts and choose the option to notify the user about the account via email. In this way, the user can set up their own password, and you can enforce strong passwords using Wordfence, so that passwords are never transmitted via email which should be considered an insecure channel of communication. As you are not sharing accounts, you can always revoke access immediately for a new user if malicious actions start to appear.

Use and enforce strong passwords for end users, especially those with higher privileges.
We highly recommend enforcing strong passwords for all users, however, accounts with higher privileges have an elevated risk as they have more capabilities associated with their account. For that reason, strong passwords are extremely important to enforce, in order to mitigate the risk associated with attackers gaining unauthorized access to these accounts through password compromising attack techniques like brute force.

We also recommend enforcing two-factor authentication for all users, especially those with higher level capabilities, to help provide an extra layer of login security and protection against brute force attacks and compromised passwords. Wordfence makes this easy with built in functionality that can be found in the “Login Security” area of the Wordfence plugin or with the use of the stand alone Wordfence Login Security Plugin. You can learn more on how to enable and configure these settings here.

Disclosure Timeline

July 10, 2020 – Initial discovery and analysis of vulnerability. Firewall rule was released for Wordfence Premium customers. Initial outreach to the Semper plugin team.
July 13, 2020 – The lead developer at Semper confirms an appropriate discussion channel. We provide full disclosure.
July 15, 2020 – A patch was released (version 3.6.2).
August 9, 2020 – Free Wordfence users receive firewall rule.

Conclusion

In today’s post, we detailed a flaw that allowed higher-level WordPress users the ability to inject malicious scripts into posts in the All in One SEO plugin. This flaw has been fully patched in version 3.6.2. We recommend that users immediately update to the latest version available at the time of reading this.

Sites running Wordfence Premium have been protected from attacks against this vulnerability since July 10, 2020. Sites running the free version of Wordfence will receive this firewall rule update on August 9, 2020. If you know a friend or colleague using this plugin on their site, we strongly recommend forwarding this advisory to them so that they can update and protect their WordPress site.

Special thank you to the Lead Developer for All in One SEO Pack, Benjamin Rojas, for working quickly to get a patch out to protect users. 

The post 2 Million Users Affected by Vulnerability in All in One SEO Pack appeared first on Wordfence.

High Severity Vulnerability Patched in TC Custom JavaScript

$
0
0

On June 12, 2020, Wordfence Threat Intelligence discovered an unauthenticated stored Cross-Site Scripting(XSS) vulnerability in TC Custom JavaScript, a WordPress plugin with over 10,000 installations.

Wordfence Premium customers received a new firewall rule to provide protection against attacks targeting this vulnerability the same day. Wordfence users still using the free version received this rule after 30 days, on July 12, 2020.

We attempted to contact the plugin’s developer the same day, on June 12, 2020, but we did not receive a response. After 10 days without an initial response, we contacted the WordPress Plugins team on June 22, 2020. An initial patch was released the next day, on June 23, 2020, and a full patch was released on June 29, 2020.

Description: Unauthenticated Stored Cross-Site Scripting(XSS)
Affected Plugin: TC Custom JavaScript
Plugin Slug: tc-custom-javascript
Affected Versions: < 1.2.2
CVE ID: CVE-2020-14063
CVSS Score: 8.3(high)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:L
Fully Patched Version: 1.2.2

TC Custom JavaScript is a WordPress plugin that allows site owners to add custom JavaScript to every page on a site and emphasizes a minimalist approach. While this kind of functionality can be incredibly useful, it can also be incredibly dangerous without proper access controls.

This plugin ran the TCCJ_Core_Content::update function immediately upon startup. This was unusual, as most WordPress plugins register functions to be run at predictable points in the WordPress load process.

As a result, the update function ran before WordPress access control functions, such as capability checks and nonce verification, could be used. This, combined with the lack of capability checks and nonce verification on the function, made it possible for unauthorized visitors to use the update function.

The update function used a companion function, has_update_request, to check if the tccj-update POST parameter was supplied and set to Update. If this check passed, then the update function would accept the contents of the tccj-content POST parameter and add it to the database.

class TCCJ_Core_Content {
	public static function update() {
		if ( self::has_update_request() ) {
			if ( get_magic_quotes_gpc() )
				$tccj_content = stripslashes( $_POST['tccj-content'] );
			else
				$tccj_content = $_POST['tccj-content'];

			// Sanitizing data before insert to database
			$tccj_content = wp_check_invalid_utf8( $tccj_content, true );
			$tccj_content = htmlentities( $tccj_content );

			if ( ! get_magic_quotes_runtime() )
				$tccj_content = addslashes( $tccj_content );

			update_option( 'tccj_content', $tccj_content );
		}
	}

	private static function has_update_request() {
		if ( isset( $_POST['tccj-update'] ) && ( $_POST['tccj-update'] == 'Update' ) )
			return true;
		else
			return false;
	}
}

While the update function did run htmlentities on the content provided by tccj-content before storing it, this didn’t provide any additional safety, as the TCCJ_Core_Frontend::print_script_in_footer function used to display the added script not only used html_entity_decode on the stored content but also added <script> tags around it.

class TCCJ_Core_Frontend {
	public static function print_script_in_footer() {
		//$tccj_content = sanitize_text_field( get_option( 'tccj_content', '' ) );
		$tccj_content = get_option( 'tccj_content', '' );
		$tccj_content = stripslashes( $tccj_content );
		$tccj_content = html_entity_decode( $tccj_content );

		if ( $tccj_content != '' ) {
			echo '<script type="text/javascript">' . $tccj_content . '</script>';
		}
	}
}

As such, an attacker could send a POST request to any location on a vulnerable site with the tccj-update parameter set to Update and the tccj-content parameter set to malicious JavaScript, and this JavaScript would display in the footer of every page on the site.

Malicious JavaScript of this type can be used to redirect visitors to malvertising sites or steal payment information. Even worse, it can detect when an administrator visits the site and send a request on their behalf to infect files with a backdoor or possibly create a new, malicious administrator user account leading to takeover of the entire site.

Timeline

June 12, 2020 – Wordfence Threat Intelligence discovers a vulnerability in TC Custom JavaScript. We release a firewall rule available to Wordfence Premium users and attempt to make contact with the plugin’s developer.
June 22, 2020 – After failing to make contact with the plugin’s developer, we contact the WordPress Plugins team to notify them of the vulnerability.
June 23, 2020 – The plugin developer releases an initial patch which is still vulnerable to CSRF attacks.
June 29, 2020 – A fully patched version of the plugin is released.
July 12, 2020 – Firewall rule becomes available to free Wordfence users.

Conclusion

In today’s article, we reviewed an unauthenticated stored Cross-Site Scripting(XSS) vulnerability in the TC Custom JavaScript plugin. This flaw has been fully patched in version 1.2.2 and we strongly recommend updating to this version as soon as possible. Sites running Wordfence Premium have been protected against these vulnerabilities since June 12, 2020, while sites still using the free version of Wordfence received the firewall rule on July 12, 2020.

Special thanks to Wordfence QA Lead Matt Rusnak, who initially discovered the vulnerability.

The post High Severity Vulnerability Patched in TC Custom JavaScript appeared first on Wordfence.

Viewing all 426 articles
Browse latest View live