File Manager is a popular WordPress plugin that manages 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 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 actively exploited in the wild. A vulnerability management tool can detect and remediate this vulnerability.
The WordPress vulnerability in the WordPress File Manager plugin has not 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 executes directly. The file had no access restrictions and be accessed by anyone in order to execute commands via a function in elFinderConnector.class.php script. A patch management software fixes this.
Code:
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 process 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 WordPress vulnerability to upload phpcode is:
Invoking PHP code to execute ‘ipconfig’ command:
Publicly available PoC:
A proof of concept (PoC) code has published and is publicly available for download.
Impact of WordPress vulnerability:
The vulnerability can allow unauthenticated users to upload malicious files and execute arbitrary commands on the target system.
Affected Versions in WordPress vulnerability:
The vulnerability affects WordPress File Manager plugin versions 6.0 through 6.8
Solution:
The developers fixed this vulnerability. Update WordPress File Manager plugin to version 6.9 or later.