CNVD证书—–代码审计PHP反序列化漏洞
作者:Shmliy
前言:首先我们在审计php反序列化,要了解它的魔术方法,因为有些魔术方法是自动调用的,下列是列举的常见的几种魔术方法。
__wakeup() //使用unserialize时触发
__sleep() //使用serialize时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当脚本尝试将对象调用为函数时触发
这里我们审计是某cms的一套源码。话不多说直接干哇!!!
一.查找关键字
我们在寻找反序列化这类漏洞的时候,不可能去争对功能点一个一个去找,而且反序列不一定只会出现功能点的地方,所以会有点不现实,我们直接全局搜索unserialize或serialize
等或者魔术方法。

这里我们可以很容易就观察到,就跟进上面传参,因为它的参数值没有指定,而下面那个传参是指定了的,所以我要找就找那种可以构造参数值的,这样才能达到我们想要的效果

这个时候我们,就想到使用unserialize这个函数的时候,会触发_wakeup()这个魔术方法,因为在这里我们的出发点是unserialize所以首先想到的就是这个魔术方法,你也可以去找那些常见的魔术方法呀,这里我就不给大家啰嗦了,直接讲有问题的地方,
于是我们继续全局搜索_wakeup()关键字去看那个文件调用了这个函数

二.跟进函数方法,查找特征
这里,我们每个都可以去看看,因为代码审计毕竟还是要花时间和精力的,我就直接给来到有问题的这个地方了

我们看到这里触发了两个方法load(),checkSystem(),然后在调用laod()方法的时候又调用了getSouce()方法,我们跟过去看看

跟过来后,就发现了不正常的东西!!!嘿嘿,这个eval()和file_get_contents()函数是真的亮眼呀,
那么也就是说我们可以执行读取任意文件的内容,我们继续跟进file_get_contents()函数中调用的getSource()函数

也就是说我们只要能构造source这个参数的值,那么我们就可以读取任意文件的内容了,利用反序列化,

刚好在这个文件里搜索到了这个变量名,初始值是空值,这个时候就是构造POC链的时候了,到目前为止我们来整理一下我们走过的思路
首先我们通过unserialize()---->_wakeup()---->load()---->eval()--->file_get_contents()--->getSourc()---->参数source-----对象PMA_Config
接下来我们就开始构造POC链
三.构造POC链
我们现在要做的就是触发unserialize(),

这里可以看到,我们只要把参数configguration参数post传参我们构造的poc链,并且action参数的值不等于clear即可
我们直接来到在线的php来写生成POC链,当然自己写也是可以的
O:4:”info“:2:{s:5:“namea”;i:1:“9”;}
O:object 代表数组,i代表数组
4:对象长度
info:对象名称
2:该对象中变量的个数
s:变量数据类型,s代表string,i代表int
4:变量名长度
namea:变量名

<?php
class PMA_Config{
var $source = 'd://shmily.txt';
}
$x = new PMA_Config();
echo serialize($x);
?>
O:10:"PMA_Config":1:{s:6:"source";s:14:"d://shmily.txt";}


我们这里是在本地搭建的,好像是本地环境问题,有些报错,所以源码审计大概就是如此
直接来到目录,传参后,可以看到直接读取了任意文件目录的文件内容

总结:
这里通过代码审计通过反序列化漏洞造成了命令执行,在代码审计的时候,不可能将所有的代码都审计完,我们只能通过搜索关键字,然后再进一步去审计有用的代码,当然你要看完也可以,那只能说你很强,你很棒。