泛微 ecology 8.x && 9.x 前台SQL注入
- 泛微 ecology 9.x 补丁版本号 <= v10.56
- 泛微 ecology 8.x 补丁版本号 <= v10.56
由上面补丁版本,我们需要到官网下载两个补丁包:
1. https://www.weaver.com.cn/cs/package/Ecology_security_20230418_v9.0_v10.57_deta.zip?v=20230420
2. https://www.weaver.com.cn/cs/package/Ecology_security_20221014_v10.55.zip?v=20230420
以确保我们能够根据两个版本的补丁包去精确定位漏洞位置
将这两个补丁包解压后,先用idea打开其中一个目录,然后使用idea自带的比较对象功能去比较这两个补丁包:
刚开始,我对比的时候自己也很费劲,不知道如何定位漏洞位置,后面静下心来根据时间看漏洞通告在4.18号,我就想着根据文件日期去看,看哪个文件离18号近,就有可能是被改动的。
而且通告里也说了,这个SQL注入是未授权。通告地址:微信公众平台 (qq.com)
然后注意到这个10.57补丁里的这个文件:ecology/WEB-INF/securityRule/E9/4d162ce4-d74e-4371-944f-814d850ff895_forbidden_20230406.xml
这里设置了几个需要检查的URL,我看着时间挺近,我就fofa找了几个站尝试访问了一下哪个未授权,然后就发现了
http://xxxxxx/mobile/plugin/CheckServer.jsp是未授权
然后又看到了这个文件ecology/WEB-INF/securityRule/E8/4d162ce4-d74e-4371-944f-814d850ff7f9_mobile_setting.xml
意思可能是针对这个url对mobilesettings做了某些限制,然后我就去找这个weaver.security.validators.MobileSettingsValidator
ecology/WEB-INF/myclasses/weaver/security/validators/MobileSettingsValidator.class
暂时还不知道这个类是干啥的,就先留着,然后我还看到10.57里的CheckServer.jsp这个文件,有改动:
这么多新改动指向它,我感觉很有可能就是CheckServer.jsp这个文件有大问题,注入点很有可能就在这。然后就找了个Ecology9的安装包本地把环境搭建起来,具体分析代码了。
测试环境版本:9.00.2003.18
找到源码中的CheckServer.jsp文件:mobile/plugin/CheckServer.jsp
,发现里面是有内容的:
而且传参里面带个mobileSetting
,那很有可能就是这个地方有问题了;根据type传值判断属于哪个分支,然后进入对应的方法中,这次主要研究的是mobileSetting这个判断分支,因此传值的时候直接
传type=mobileSetting,即可进入对应分支,然后进入result = ps.syncMobileSetting(settings, timestamp)
这个方法内部看看。
这不就妥妥的SQL拼接吗。。。但是我就是在这里卡了一天。按流程来看我们只要传入?type=mobileSetting&settings=x×tamp=x,就能顺利走到注入处,那我们断点调试一下看看情况
看到这我就懵了,为啥传值到这里变成了-999999999N
,我尝试了很多值:字母、数字,特殊字符,发现只有数字是没有改变,初步判断可能是强转或者做了限制,我为了方便,直接把值输出
到response上了。
String timestamp = fu.getParameter("timestamp");
out.println(timestamp);
至于为什么timestamp参数值会进行过滤,我只知道断点后走到这里:
通过classbean/weaver/file/FileUpload.class#getParameter()
这个方法
走到classbean/weaver/security/webcontainer/XssRequestWeblogic.class#getParameter()
,但是里面的代码太冗余了,看的头疼,以后再分析吧
然后到这里的时候其实已经快要放弃这个猜测的漏洞点了,继续翻看classbean/weaver/mobile/plugin/ecology/service/PluginServiceImpl.class#syncMobileSetting()
这个方法的时候,突然想起来syncMobileSetting()
这个方法应该在哪见过ecology/WEB-INF/myclasses/weaver/security/validators/MobileSettingsValidator.class
,这不就是补丁包里新增的类嘛,那看来漏洞位置肯定在这个方法里,我就继续翻看这个方法:
因为这里使用到了settings这个参数,因此我首先尝试打印这个参数值,看它有没有过滤:
可以看到,它完整的输出了我想要的结果,然后我接下来去找看看这个方法的代码里有没有SQL拼接的地方,最后找到了在这个内部方法里
classbean/weaver/mobile/plugin/ecology/service/PluginServiceImpl.classs#yncMobileSetting()-->this.saveMobileDocSetting(var10, var12, var13);
可以看到,这里有很多地方可以做拼接的,但是要根据分支去具体分析:
我们先来设置几个基础变量
saveMobileDocSetting(int var1, String var2, String var3)
var1 = (int)scope
var2 = (String)setting
var3 = (string)modulename
这里有两种情况,第一种是var2为空,第二种是var2不为空的情况,我们先来分析第一种:
1: var2为空
由这个判断,我们可以知道,当var1(scope) > 0 并且var3(modulename) 不是空值的时候,会进入判断,因此我们目前的payload可以写成:
settings=[{"scope":"1","modulename":"a"}]
继续进入内部的if分支后,可以看到,这里需要确保StringUtils.isBlank(var2)
为true,才会进入判断,而var2=setting,因此我们的poc可以继续写成:
settings=[{"scope":"1","modulename":"a","setting":""}]
现在的问题是,我们该如何进入到内部方法saveMobileDocSetting()
中,回过头来看classbean/weaver/mobile/plugin/ecology/service/PluginServiceImpl.class#syncMobileSetting()
方法
因此我们继续设置我们的poc: settings=[{"scope":"1","module":"2","modulename":"a","setting":""}]
成功进入分支后,就直接执行sql语句了,通过第三个sql语句我们可以知道,payload可以直接插入modulename中,通过断点调试并结合mysql,去分析:
成功走到了saveMobileDocSetting()
内部方法中:
在执行三条sql语句之前,我们先看看数据库中该表的状态:
执行第二条语句后:
执行第三条语句后:
我们尝试插入恶意poc:
settings=[{"scope":"1","module":"2","modulename":"1'+and+benchmark(100000000,sha(1))+and+'","setting":""}]×tamp=11111
2. var2 不为空:
当var2(setting)不为空的情况下,就走近了else分支中了
我们可以直接看这条sql语句中的var12,var1。看看该else分支中是如何处理这两个变量的
单击var1参数,我们是可以看到这个else分支中是没有var1的动作的:
所以其实我们整个poc只需要修改setting,保证不为空,即可进行select注入:
综上:
insert sqli: [{"scope":"1","module":"2","modulename":"1'+and+benchmark(100000000,sha(1))+and+'","setting":""}]
select sqli: [{"scope":"1","module":"2","modulename":"1'+and+benchmark(100000000,sha(1))+and+'","setting":"1"}]