PHP网站的安全测试—反序列化漏洞

 
 
        前段时间SINE安全对某一大客户的网站进行安全测试服务,客户网站的架构是PHP+MYsql
 
数据库,在对其详细的网站安全检测以及渗透测试后发现网站存在反序列化漏洞,具体的网站漏

洞发现,以及如何利用,下面记录一下,出于对客户的隐私保密,这里不在做介绍。
 
 
网站安全测试了7天,也想告诉大家的是,只有彻彻底底的理解了网站整体的架构与设计逻辑
 
,才能挖掘出最底层的漏洞。也需要对PHP反序列化机制的理解很深,不然就像我的第一反应
 
一样,根本无从下手,也不知道这个机制是怎样去运行的。下面看下出现漏洞的PHP代码:Sine

安全公司是一家专注于:服务器安全、网站安全、网站安全检测、网站漏洞修复,渗透测试,安全

服务于一体的网络安全服务提供商。
 
<?php
//A webshell is wait for you
ini_set('session.serialize_handler', 'php');
session_start();
class OowoO
{
    public $mdzz;
    function __construct()
    {
        $this->mdzz = 'phpinfo();';
    }
    
    function __destruct()
    {
        eval($this->mdzz);
    }
}
if(isset($_GET['phpinfo']))
{
    $m = new OowoO();
}
else
{
    highlight_string(file_get_contents('index.php'));
}
?>
 
这个网站漏洞的关键点在于:
 
ini_set('session.serialize_handler', 'php');
 
PHP内置了多种处理器,用于存取$_SESSION的时候对数据进行序列化和反序列化,这个的意
 
思是在于设置序列化解释格式,我的理解是和字符集相似,按照某种格式构造和解析序列化
 
的字段。漏洞产生在php_serialize和php解析方式上,如果我们通过php_serialize的方式构
 
造序列化语句,然后通过php的方式解析序列化语句,就会出现安全问题。原因是在使用
 
php_serialize构造过程中,可以在字符串变量中储存 | 符号,但是如果按照php的方式解析
 
的话,会把 | 之前的语句当做数组的键,之后的语句当做值,这时我们就可以按照这个特性
 
来构造执行对象的命令。
 
 
通过php_serialize语句来构造的:
 
a:1:{s:4:"ryat";s:20:"|O:8:"stdClass":0:{}";}
 
以php代码的方式解析也会变为:
 
array(1) {  ["a:1:{s:4:"ryat";s:20:""]=>  object(stdClass)#1 (0) {  }} 成功执行了变量。
 
这时就有一个问题,在题目代码中,没有某个值是用来接受我们传入的数据,并储存到
 
$_SESSION中的。其实我们是有办法传入$_SESSION数据的。Sine安全公司是一家专

注于:服务器安全、网站安全、网站安全检测、网站漏洞修复,渗透测试,安全服务于一

体的网络安全服务提供商。

 


 
我们查看phpinfo页面,可以发现,session.upload_progress.enabled是被打开了的,而当
 
这个选项被打开时,php会自动记录上传文件的进度,在上传时会将其信息保存在$_SESSION
 
中。这时,我们可以在本地构造一个指向目标页面的表单。上传之后,用burp修改filename
 
,就可以将我们想要传入的序列化字段储存进去。传入什么呢?因为在php大于5.5.4的版本
 
中默认使用php_serialize规则,所以我们可以在本地构造语句来执行。
分享: