You are currently viewing WordPress File Manager Plugin Under Active Exploitation

WordPress File Manager Plugin Under Active Exploitation

File Manager is a popular WordPress plugin that is used to manage files on WordPress sites. It allows a WordPress administrator to edit, delete, upload, download, archive, copy and paste files and folders directly from the WordPress backend. A critical remote code execution vulnerability has been identified in the WordPress File Manager plugin which allows an attacker to run arbitrary code on the target. The plugin is currently installed on more than 700,000 active WordPress websites and is being actively exploited in the wild.

The vulnerability in the WordPress File Manager plugin has not been assigned any CVE as of now but carries a maximum CVSS score of 10.0. The flaw exists due to the inclusion of the open-source file manager library called elFinder. The plugin uses the file connector.minimal.php-dist in an executable format by just renaming it to connector.minimal.php so it could be executed directly. The file had no access restrictions and could be accessed by anyone in order to execute commands via a function in elFinderConnector.class.php script.

Here is the code from the connector.minimal.php file allowing an attacker to initiate an elFinder command:


// run elFinder
$connector = new elFinderConnector(new elFinder($opts));
$connector->run();

An attacker can pass any parameters to connector.minimal.php that would be processed by the run function present in elFinderConnector.class.php.

public function run()
{
$isPost = $this->reqMethod === 'POST';
$src = $isPost ? array_merge($_GET, $_POST) : $_GET;
$maxInputVars = (!$src || isset($src['targets'])) ? ini_get('max_input_vars') : null;
if ((!$src || $maxInputVars) && $rawPostData = file_get_contents('php://input')) {
// for max_input_vars and supports IE XDomainRequest()
$parts = explode('&', $rawPostData);
if (!$src || $maxInputVars input_filter($src);
$_REQUEST = $this->input_filter(array_merge_recursive($src, $_REQUEST));
}
}
if (isset($src['targets']) && $this->elFinder->maxTargets && count($src['targets']) > $this->elFinder->maxTargets) {
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_MAX_TARGTES)));
}
$cmd = isset($src['cmd']) ? $src['cmd'] : '';
$args = array();
...
...

elFinder allows only a pre-defined list of commands, defined in the elFinder.class.php

/**
* Commands and required arguments list
*
* @var array
**/
protected $commands = array(
'abort' => array('id' => true),
'archive' => array('targets' => true, 'type' => true, 'mimes' => false, 'name' => false),
'callback' => array('node' => true, 'json' => false, 'bind' => false, 'done' => false),
'chmod' => array('targets' => true, 'mode' => true),
'dim' => array('target' => true, 'substitute' => false),
'duplicate' => array('targets' => true, 'suffix' => false),
'editor' => array('name' => true, 'method' => true, 'args' => false),
'extract' => array('target' => true, 'mimes' => false, 'makedir' => false),
'file' => array('target' => true, 'download' => false, 'cpath' => false, 'onetime' => false),
'get' => array('target' => true, 'conv' => false),
'info' => array('targets' => true, 'compare' => false),
'ls' => array('target' => true, 'mimes' => false, 'intersect' => false),
'mkdir' => array('target' => true, 'name' => false, 'dirs' => false),
'mkfile' => array('target' => true, 'name' => true, 'mimes' => false),
'netmount' => array('protocol' => true, 'host' => true, 'path' => false, 'port' => false, 'user' => false, 'pass' => false, 'alias' => false, 'options' => false),
'open' => array('target' => false, 'tree' => false, 'init' => false, 'mimes' => false, 'compare' => false),
'parents' => array('target' => true, 'until' => false),
'paste' => array('dst' => true, 'targets' => true, 'cut' => false, 'mimes' => false, 'renames' => false, 'hashes' => false, 'suffix' => false),
'put' => array('target' => true, 'content' => '', 'mimes' => false, 'encoding' => false),
'rename' => array('target' => true, 'name' => true, 'mimes' => false, 'targets' => false, 'q' => false),
'resize' => array('target' => true, 'width' => false, 'height' => false, 'mode' => false, 'x' => false, 'y' => false, 'degree' => false, 'quality' => false, 'bg' => false),
'rm' => array('targets' => true),
'search' => array('q' => true, 'mimes' => false, 'target' => false, 'type' => false),
'size' => array('targets' => true),
'subdirs' => array('targets' => true),
'tmb' => array('targets' => true),
'tree' => array('target' => true),
'upload' => array('target' => true, 'FILES' => true, 'mimes' => false, 'html' => false, 'upload' => false, 'name' => false, 'upload_path' => false, 'chunk' => false, 'cid' => false, 'node' => false, 'renames' => false, 'hashes' => false, 'suffix' => false, 'mtime' => false, 'overwrite' => false, 'contentSaveId' => false),
'url' => array('target' => true, 'options' => false),
'zipdl' => array('targets' => true, 'download' => false)
);

A typical crafted HTTP request exploiting this vulnerability to upload phpcode is given below:

 

Invoking PHP code to execute ‘ipconfig’ command:

Publicly available PoC:

A proof of concept (PoC) code has been published and is publicly available for download.

Impact:

The vulnerability can allow unauthenticated users to upload malicious files and execute arbitrary commands on the target system.

Affected Versions:

The vulnerability affects WordPress File Manager plugin versions 6.0 through 6.8

Solution:

A fix for this vulnerability has been released. Update WordPress File Manager plugin to version 6.9 or later.