In Pimcore versions prior to 5.7.1, a deserialization vulnerability exists in the handler function for the bulk-commit
POST request.
Recent assessments:
space-r7 at September 12, 2019 6:07pm UTC reported:
There exists a PHP deserialization vulnerability in Pimcore versions prior to 5.7.1 that allows the ability to gain remote code execution post authentication.
The Metasploit module documentation for exploit/multi/http/pimcore_unserialize_rce
mentions that the PHP deserialization vulnerability exists in the ClassController.php
file in the function that takes care of the bulk-commit
method. The bulkCommitAction()
function has a comment mentioning that it handles the bulk-commit
route, so it’s safe to say that analysis should start there.
In bulkCommitAction()
, the serialized PHP object gets assigned to the data
variable, and its layout type is checked in an if
statement.
The block of code is quite large, but the important detail happens in the first few lines of the elseif
block:
elseif ($type == 'customlayout') {
$layoutData = unserialize($data['name']);
$className = $layoutData['className'];
$layoutName = $layoutData['name'];
...
}
The serialized payload is passed to the unserialize()
function unsanitized, which will call the object’s magic method, __destruct()
in this case. The object used in Metasploit’s module is an object of the ApcuAdapter
class, which inherits its magic method from AbstractAdapter
.
__destruct()
method:
public function __destruct()
{
if ($this->deferred) {
$this->commit();
}
}
The deferred
variable contains the PHP code, so the commit()
function is called.
In commit()
, there are two lines of interest:
$byLifetime = $this->mergeByLifetime;
$byLifetime = $byLifetime($this->deferred, $this->namespace, $expiredIds);
The object’s mergeByLifetime
variable, which is set to proc_open
in the serialized object, gets assigned to $byLifetime
. In the next line, $byLifetime
is executed with the object’s instance variables passed as the arguments. As noted previously, the deferred
variable contains the PHP code to execute. Viewing the serialized object in the pimcore_unserialize_rce
Metasploit module shows us that the namespace
variable is an empty array, and $expiredIds
is a variable that will hold an array of file pointers. So summing this up, proc_open()
will execute code embedded in a PHP serialized object, potentially giving unauthorized individuals shell access.
Assessed Attacker Value: 3
Assessed Attacker Value: 3Assessed Attacker Value: 3
packetstormsecurity.com/files/152667/Pimcore-Unserialize-Remote-Code-Execution.html
www.rapid7.com/db/modules/exploit/multi/http/pimcore_unserialize_rce
cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10867
github.com/pimcore/pimcore/commit/38a29e2f4f5f060a73974626952501cee05fda73
snyk.io/vuln/SNYK-PHP-PIMCOREPIMCORE-173998
www.exploit-db.com/exploits/46783