2020, the year of the pandemic, has also been known for rapid digitalization. Be it, organizations who had to allow their employees to Work From Home (WFH) or users who started operating digitally because of the fear of getting themselves infected, there was a significant digital transformation taking place at our homes and now people find it hard to come out of their cocoon. 

While security professionals and IT administrators are working round the clock to make the new digital world a safe haven for everyone, they have fallen short of addressing all the vulnerabilities in their systems, making them susceptible to attacks.

WordPress is one among the most popular Content Management Systems(CMS) available in the market. It has been estimated that around 40% of the websites on the internet are created using WordPress. WordPress has reduced the hassle that was involved in creating websites making it accessible to even a non-technical person. WordPress has a ton of plugins and themes that are used for customization of the site and for providing necessary functionalities to its users. As more popularity means more attention (in the negative sense), a lot of WordPress sites have been defaced or are being exploited to be used as Command and Control (C&C) servers for other malicious activities, recent among them being for the Gootloader campaign.

Figure 1: WordPress site being used as C&C servers (source:threatpost.com)
Figure 2: Gootloader campaign (source:esentire.com)

In this blog, we will discuss the internals of three WordPress vulnerabilities that were patched in the year 2020 and also look at the Techniques, Tactics and Procedures (TTPs) used by threat actors for exploiting these in the wild.

CVE-2020-25213 in WP-File Manager

With more than 700K downloads, this plugin is the go to solution for a File Manager for WordPress (WP) sites. It serves as an alternative to File Transfer Protocol (FTP) servers with features that enable users to edit, delete, upload, download, zip, copy and paste files and folders directly on the servers hosting WP websites.

This vulnerability identified in WP-File Manager versions < 6.9 had a Common Vulnerability Scoring System(CVSS) of 10, marking it as critical. Exploiting this can lead to remote code execution (RCE) attacks on the victim’s machine. This is due to improper implementation of an open source library called elFinder, which is an open source file manager for web written in Javascript. This elFinder library has a connector file named ‘connector.minimal.php-dist’  that has minimal security built into it, by default, to make it easier for developers to understand the core features of the connector. The connector file can execute from a list of predefined commands (as shown in Figure 4) on the server which it receives in a POST request from a user. In the WP-File Manager plugin this file is present at ‘/wp-content/plugins/wp-file-manager/lib/php/’ as ‘connector.minimal.php’. Since there is no proper security mechanism built into this file, an unauthenticated user can access this file with its URL. With tools like Postman or Burp it is possible to craft a POST request as depicted in Figure 3 to access the file and execute the commands.

Figure 3: POST request to run a command on connector.minimal.php
Figure 4: List of predefined commands supported by the connector file

In Figure 3 the parameters in POST request are cmd and target. The cmd parameter must be a command from the list that is supported by elFinder and the target parameter defines the location from where the command is executed. l1_Lw denotes the default directory /wp-content/plugins/wp-file-manager/lib/files/. This POST request on the server side calls run(). This function gets the POST parameters and checks if the cmd is present in its list of commands. It then assigns the values to $cmd and $args[] variables if the condition succeeds. These two variables are then passed on to exec() as shown in Figure 5. exec() in php is used to run shell commands and the command’s output is sent back to the user as  a response as shown in Figure 3. The list of supported commands includes a command called upload which requires target and upload as parameters (as shown in Figure 6). The target parameter specifies the location at which the uploaded file is put and the upload  parameter is an array consisting of the filename and its contents. The file upload functionality does not have any filetype check hence it is possible to upload files with .php extension. By uploading a php shell code file and accessing the file it is possible to gain a complete shell in the context of the upload directory’s owner as shown in Figure 7.

Figure 5: Call stack leading to code execution on the connector file and the exec code
Figure 6: File upload command and required arguments
Figure 7: Remote code execution on the web server

CVE-2020-11738 in Duplicator 

According to the Duplicator’s description, it is used “to migrate, copy, move or clone a site from one location to another and also serves as a simple backup utility”. With 1M downloads, this plugin is one among the most popular plugins for website migration. A critical vulnerability with CVSS as 7.5 was identified in Duplicator versions <= 1.3.26.  Exploiting this can lead to Local File Inclusion (LFI) on the victim’s machine. 

The Duplicator plugin allows the site’s administrator to clone a site and create archives of the clone. The site administrator can then download these clones. This cloning and downloading process involves multiple AJAX requests to be sent to the server with an action parameter in its GET request (as shown in Figure 9). This action is used to identify the function that is to be executed on the server. One such action parameter is duplicator_download which has an additional parameter called file which is the path for the file to be downloaded (shown in Figure 9).The duplicator_download AJAX request is hooked to wp_ajax_nopriv_(as shown in Figure 8) in the plugin’s init() function making it accessible to any unauthorized or unauthenticated user. Vulnerability in the code is improper input sanitization of the filename which does not remove dot (.) and forward slash (/). By exploiting these, it is possible for an unauthenticated user to perform a Local File Inclusion(LFI) on the vulnerable site. Using multiple “../” the user can traverse back till the root directory. This can be utilized by the attacker as a work around by going to the root directory and then traversing to other file locations from there as shown in Figure 9 (e.g. “../../../../../../../../etc/passwd” which is a critical file on a Linux machine that gives information about all the users present on that server). On successful exploitation an attacker can obtain sensitive information from the server (as shown in Figure 10).

Figure 8: init function present in duplicator plugin
Figure 9: Exploit payload being sent as GET request to the web server
Figure 10: Contents of the /etc/passwd file that is present in the server

CVE-2020-35942 in NextGEN

NextGEN is a simple image gallery plugin with more than 700k downloads. Multiple vulnerabilities were identified in this plugin in versions less than 3.5.0. The most critical among these vulnerabilities is CVE-2020-35942 with CVSS score of 9.6. This vulnerability is a Cross-Site Request Forgery (CSRF) vulnerability in file upload functionality which also has Local File Inclusion (LFI) vulnerability. These vulnerabilities when exploited can result in  Cross-Site Scripting (XSS) and RCE attacks on the victim’s machine. 

The plugin has a function called is_authorized_request, which is used to authorize any request that is being made from the plugin. Whenever a request is made with the plugin this function checks for the user authorization first before executing the functions related to the actual request. It then checks if the nonce is valid and the response to the user is shown as Not Authorized if it’s invalid. Though this looks enough to prevent unauthenticated users from making unauthorized requests, there exists a logical flaw in the nonce check. The nonce check is done inside an if() statement. The flaw in this statement is that if the request has no 

value in it, the if() statement can be skipped as when there’s no nonce the isset($_REQUEST[‘nonce’]) statement returns false. This flaw results in a CSRF vulnerability which can lead to more severe vulnerabilities. Figure 11 shows the is_authorized_request function’s code.

Figure 11: is_authorized_request function present in NextGEN Plugin

The plugin has a feature to change the styling of all the galleries using Cascading Style Sheets (CSS). In the plugin’s dashboard there’s an option called ‘Other Options’ which has a ‘Styles’ sub-option, on clicking this it gives a feature to enable custom CSS. It is possible to edit the current CSS file’s contents directly using the style editor which is accessible through the plugin’s dashboard. On saving the changes the content is directly written into the CSS file present on the server. The problem with this feature is that the save request contains a parameter called style_settings[file] which contains the CSS file’s name. When this name is changed a new file is created in that location with the given name. Though this parameter only accepts files with .css extension there isn’t any check to prevent double extension, therefore it is possible to exploit this to create a file named exploit.php.css inside wp-content/ngg_styles directory (as in Figure 12). This file cannot be executed directly and this problem can be solved by using another vulnerability present in the NextGEN plugin.

Figure 12: Payload uploaded to the styles directory
Figure 13: POST request to upload the payload

A feature called ‘Legacy Templates’ is provided by the NextGEN gallery plugin for backward compatibility in viewing the gallery on old browsers. As with all other requests in this plugin, any requests on modifying the features related to ‘Legacy Templates’ is first authorized by the is_authorized_request function. This makes it vulnerable to the same CSRF attack as discussed above. 

In the plugin’s dashboard there’s an option called ‘Gallery Settings’ which has multiple options all related to how the gallery can be viewed. Each of these options has a sub-option called ‘Legacy Templates’. The first option called ‘Basic Thumbnails’ controls how the initial thumbnails are viewed when the site is open (as shown in Figure 14). On saving the changes, a request made by the plugin which has a parameter called photocrati-nextgen_basic_thumbnails[template] contains the path to the template file. They are template files with .php extensions that are provided by the NextGEN Gallery. The parameter photocrati-nextgen_basic_thumbnails[template] has a Local File Inclusion(LFI) vulnerability which enables users to assign any files from the local machine as the template file and these files are executed at the time of viewing the affected gallery from the WordPress site (shown in Figure 15 and Figure 16).

Figure 14: Legacy feature in NextGEN plugin
Figure 15: Legacy template file on the web server
Figure 16: POST request to modify the legacy template file

Using these two vulnerabilities that were discussed earlier, it is possible to send a CSRF request to the site’s admin to upload a php shell to the wp-content/ngg_styles directory and to include the uploaded file as a template file. When any user now views the gallery it is possible to launch RCE attacks on the victim’s machines (as shown in Figure 17). The only caveat for this attack is that at least one gallery has to be posted on the WordPress site.

Figure 17: Code execution on the vulnerable server


  • Update WordPress site, plugins and themes
  • Implement end point firewalls such as Wordfence
  • Regularly scan the site with WordPress scanners such as WPScan which are available for free to make sure the site is secure
  • Make sure WordPress is not executed on the server with root privileges

Further Readings

Like what you're reading? Subscribe to our top stories.

If you want to subscribe to our monthly newsletter, please submit the form below.

    0 replies on “Unpatched WordPress: E-Pass to Web Servers”