前言
该漏洞的实质触发原因是由于可以通过反序列化来执行任意sql
语句,导致可以在数据库中更改上传文件的限制类型,最后达到可以上传任意PHP
文件的效果
代码分析
漏洞利用点文件位置在./system/aws_model.inc.php
,该文件中存在一个AWS_MODEL
类,重点关注一下该类的__destruct
方法
![](/2020/02/29/WeCenter-V3-3-4%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/1.png)
该方法遍历了$_shutdown_query
,然后执行了query方法,跟进去看一下
![](/2020/02/29/WeCenter-V3-3-4%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/2.png)
该方法的功能是执行传入的SQL
语句,那么也就是说我们只要控制了$_shutdown_query
就可以执行任意的语句了,可以注意到该变量是该类中的私有成员变量
![](/2020/02/29/WeCenter-V3-3-4%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/3.png)
如果存在反序列化的点,我们就可以控制$_shutdown_query
的值来执行任意SQL
语句,于是接着来寻找反序列化的触发方法
在本例中反序列化是利用phar
进行触发的,触发点文件在./models/account.php
,在该文件的account_class
类中,存在着这样一个函数
![](/2020/02/29/WeCenter-V3-3-4%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/4.png)
如果该函数中的$headimgurl
是可控的,就可以通过file_get_contents
函数来触发phar
反序列化,通过搜索发现在./app/account/ajax.php
中的synch_img_action
函数调用了associate_remote_avatar
函数
![](/2020/02/29/WeCenter-V3-3-4%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/5.png)
在这里我们需要控制的是$wxuser['headimgurl']
,而synch_img_action
对于$wxuser['headimgurl']
的获取是来源于数据库中的users_weixin
表的,所以我们想控制其值必须找到对users_weixin
表中headimgurl
字段操作的代码,通过搜索发现./models/openid/weixin/weixin.php
文件中bind_account
函数存在着对该表的插入操作
![](/2020/02/29/WeCenter-V3-3-4%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/6.png)
接下来需要找到bind_account
函数的调用位置,并且需要使其参数可控,通过搜索关注到binding_action
函数,该函数在/app/m/weixin.php
文件中
![](/2020/02/29/WeCenter-V3-3-4%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/7.png)
可以看到该函数中在调用bind_account
函数传入参数时,参数的值都是从cookie
中获取的,这样我们就可以通过cookie来控制传入的参数值,而binding_action
这个方法可以通过路由访问直接调用,所以我们基本上就可以来执行任意SQL语句了
接着来梳理一下流程,首先我们控制cookie
然后调用binding_action
函数,使其调用bind_account
函数并带入我们控制的参数,该函数将会把我们构造的headimgurl
插入到数据库中,在我们调用synch_img_action
方法时,该方法会将headimgurl
取出来并调用associate_remote_avatar
函数,该函数会调用file_get_contents($headimgurl)
来触发phar
反序列化,进而执行任意sql
语句
实际测试
下面首先编写反序列化的生成代码
1 |
|
在提问的编辑器处进行文件上传,会返回文件路径
![](/2020/02/29/WeCenter-V3-3-4%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/8.png)
然后编写生成cookie
的代码
1 |
|
首先带着cookie
调用binding_action
方法,注意一下cookie
的前缀需要抓包获取
![](/2020/02/29/WeCenter-V3-3-4%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/9.png)
然后去直接触发synch_img_action
方法,就可以通过报错函数来得到sql执行结果
深入分析
登陆后台可以发现允许上传的文件类型是保存在数据库中的,执行更新后缀名的语句如下
![](/2020/02/29/WeCenter-V3-3-4%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/11.png)
我们可以仿照该语句来将php
后缀名加入其中
1 |
|
按照上面的执行语句的流程,成功执行后即可将php
后缀添加到白名单中,之后在编辑器中可直接上传php文件