| Newsgroups |
php.pear.bugs |
| Message-ID |
<[email protected]> |
Edit report at https://pear.php.net/bugs/bug.php?id=21165&edit=1
ID: 21165
Comment by: [email protected]
Reported By: research at karmainsecurity dot com
Summary: PHP Object Injection Vulnerability through PHP
Serializer
Status: Critical
Type: Bug
Package: HTML_AJAX
Package Version: 0.5.7
PHP Version: 5.6.29
Roadmap Versions:
New Comment:
FYI: the Common Vulnerabilities and Exposures project (cve.mitre.org)
has assigned the name CVE-2017-5677 to this vulnerability.
Previous Comments:
------------------------------------------------------------------------
[2017-01-25 19:03:40] egix
-Status: Open
+Status: Critical
I'm going to change the status to "Critical" because I think this poses
a serious security risk for every
application which uses the
HTML_AJAX PEAR package.
Last week the details of a type-confusion vulnerability in the GMP
deserialization has been published
on the Full Disclosure mailing
list [1], and this can be exploited through the vulnerability I reported
here, allowing a potential attacker
to manipulate properties of
already created objects within an application which uses HTML_AJAX to
implement an AJAX server
(which may result in catastrophic
consequences).
In addition to this recent PHP bug, a talk published on December 2014
[2] shows how it's possible to
exploit unserialize()
vulnerabilities in PEAR applications leveraging a magic method from the
DB_common class, which
allows to call arbitrary callbacks
(in other words, Remote Code Execution).
References:
[1] http://seclists.org/fulldisclosure/2017/Jan/55
[2] https://hack4.org/2014/talks/exploit-alchemy/Exploit%20Alchemy.pdf
------------------------------------------------------------------------
[2017-01-18 21:39:35] egix
Description:
------------
When handling AJAX requests a "serializer" will be selected
automatically
relying on the Content-Type HTTP header
(AJAX.php, lines 427-436):
// auto-detect serializer to use from content-type
$type = $this->unserializer;
$key = array_search($this->_getClientPayloadContentType(),
$this->contentTypeMap);
if ($key) {
$type = $key;
}
$unserializer = $this->_getSerializer($type);
$args = $unserializer->unserialize($this->_getClientPayload(),
$this-
>_allowedClasses);
When the header is set to "application/php-serialized", the
HTML_AJAX_Serializer_PHP class will be used to deserialize user
input coming from the AJAX request. Such a class will use the
unserialize()
PHP function with user-controlled input unless a
class is found within the serialized string which is not in the provided
array of
allowed class names:
function unserialize($input, $allowedClasses)
{
[...]
$classes = $this->_getSerializedClassNames($input);
if ($classes === false) {
trigger_error('Invalidly serialized string');
return false;
}
$diff = array_diff($classes, $allowedClasses);
if (!empty($diff)) {
trigger_error('Class(es) not allowed to be serialized');
return false;
}
return unserialize($input);
}
By default the $allowedClasses array is empty, meaning that no classes
are
allowed to be unserialized. However, due to a faulty
security check in the "_getSerializedClassNames()" method it might be
possible to bypass such a restriction by replacing "O:X"
with "O:+X" from within the serialized string, where X is the length of
the
class-name:
function _getSerializedClassNames($string) {
[...]
// Pull out the class names
preg_match_all('/O:[0-9]+:"(.*)"/U', $string, $matches); <===
faulty regex
leading to a security bypass
// Make sure names are unique (same object serialized twice)
return array_unique($matches[1]);
}
This can be exploited to inject arbitrary PHP objects into the
application
scope, allowing an attacker to perform some attacks by
using a "POP chain" or exploit memory corruption vulnerabilities within
the
internal implementation of the unserialize() function,
which has a long history of security bugs (see e.g. CVE-2016-5771).
More info: https://www.owasp.org/index.php/PHP_Object_Injection
NOTE: I discovered this vulnerability in a PHP application which uses
the
HTML_AJAX Pear package for its AJAX server. They
asked to get a CVE created for this issue, so that other developers
using the
package will be notified about the potential security
risk. I'm not sure if MITRE will assign a CVE identifier for
vulnerabilities in
Pear packages, since they product list mention PHP
but not Pear
(https://cve.mitre.org/cve/data_sources_product_coverage.html). Could
you
please try to request a CVE for this
vulnerability?
Test script:
---------------
HTTP request to reproduce the issue:
POST /HTML_AJAX-0.5.7/examples/server.php?c=test&m=echo_string HTTP/1.1
Host: localhost
X-Content-Type: application/php-serialized
Content-Length: 20
Connection: close
O:+8:"stdClass":0:{}
Expected result:
----------------
{"errNo":1024,"errStr":"Class(es) not allowed to be
serialized","errFile":"\/HTML_AJAX-
0.5.7\/HTML\/AJAX\/Serializer\/PHP.php","errLine":51}
Actual result:
--------------
{"errNo":4096,"errStr":"Object of class stdClass could not be converted
to
string","errFile":"\/HTML_AJAX-
0.5.7\/examples\/support\/test.class.php","errLine":20}
------------------------------------------------------------------------
--
Edit this bug report at https://pear.php.net/bugs/bug.php?id=21165&edit=1