Use After Free in unserialize()

Sec Bug #73147 Use After Free in unserialize()
Submitted: 2016-09-23 13:22 UTC Modified: 2016-11-02 09:25 UTC
From: taoguangchen at icloud dot com Assigned: stas (profile)
Status: Closed Package: *General Issues
PHP Version: 5.6.26 OS:
Private report: No CVE-ID: 2016-9137

 [2016-09-23 13:22 UTC] taoguangchen at icloud dot com

Description:
------------
PoC:
```
<?php

$poc = 'a:1:{i:0;O:8:"CURLFile":1:{s:4:"name";R:1;}}';
unserialize($poc);

?>
```


Patches

1 (last revision 2019-09-06 03:41 UTC by 825307076 at qq dot com)
demo17 (last revision 2019-06-06 06:46 UTC by 417177366 at qq dot com)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports

 [2016-09-26 02:55 UTC] stas@php.net

-PHP Version: 7.0.11 +PHP Version: 5.6.26 -Assigned To: +Assigned To: stas -CVE-ID: +CVE-ID: needed

 [2016-09-26 11:10 UTC] taoguangchen at icloud dot com

The similar bug can be also triggered via Exception::__toString with DateInterval::__wakeup

```
ZEND_METHOD(exception, __toString)
{
...
	zend_update_property_str(base_ce, exception, "string", sizeof("string")-1, str);
```

PoC:
```
<?php

$poc = 'O:9:"Exception":2:{S:17:"\00Exception\00string";R:1;i:0;O:12:"DateInterval":1:{s:4:"days";R:1;}}';
unserialize($poc);

?>
```

 [2016-09-26 19:42 UTC] stas@php.net

Hmmm... I suspect there might be also other places, I'm not sure how to handle this problem in general, as reference allows to overwrite anything, by definition, that's how reference is supposed to work.

 [2016-09-26 22:30 UTC] taoguangchen at icloud dot com

the follow patch can fix this bug:

```
+	zval tmp;
+	ZVAL_STRINGL(&tmp, "string", sizeof("string") - 1);
+	Z_OBJ_HANDLER_P(exception, unset_property)(exception, &tmp, NULL);
+	zval_ptr_dtor(&tmp);
	zend_update_property_str(base_ce, exception, "string", sizeof("string")-1, str);
```

 [2016-09-26 22:35 UTC] stas@php.net

Yes, I know this particular one can be easily fixed. The problem is that every __wakeup that modifies any property would produce the same problem.

 [2016-09-26 22:41 UTC] taoguangchen at icloud dot com

You can handle the DateInterval::__wakeup() like PHP5.

 [2016-10-11 23:45 UTC] stas@php.net

-Status: Assigned +Status: Closed

 [2016-10-14 06:00 UTC] tyrael@php.net

-Summary: Use After Free in PHP7 unserialize() +Summary: Use After Free in unserialize()

 [2016-11-02 09:25 UTC] kaplan@php.net

-CVE-ID: needed +CVE-ID: 2016-9137

 [2016-11-02 09:25 UTC] kaplan@php.net

From CVE-assign:
"Use CVE-2016-9137 for the ext/curl/curl_file.c vulnerability that was
fixed in 5.6.27 and 7.0.12.

Use CVE-2016-9138 for the remaining security problem associated with
__wakeup that is still present in 5.6.27 and 7.0.12."