泛微Ecology(CheckServer-SQL注入)漏洞原理分析
2023-05-24 17:26:00

0x00、前言

泛微Ecology(CheckServer-SQL注入)漏洞复现与分析,针对CheckServer.jsp的漏洞点的复现和分析,本来是复现分析任意用户登录的漏洞,安装下载折腾了半天然后发现安装的版本不存在该漏洞,借此转向前端时间的SQL注入漏洞,brower-sql注入的后面再补。

0x01、漏洞描述

泛微 Ecology OA 系统对用户传入的数据过滤处理不当,导致存在 SQL 注入漏洞,未经过身份认证的远程攻击者可利用此漏洞执行任意SQL指令,从而窃取数据库敏感信息。

0x02、漏洞范围

泛微 Ecology <= v10.56

0x03、环境搭建

这里下载的网上的泛微Ecology9版本,安装步骤可参考
http://www.taodudu.cc/news/show-5203830.html?action=onClick
https://blog.csdn.net/qq_35086986/article/details/129853901

步骤不再赘述,记下安装坑点,浪费了不少时间

由于安装环境的数据库是mysql,导致初始化数据库的时候报错了很多次

防止安装初始化数据库失败,需要修改mysql配置(本地数据库版本为Mysql5.7.24),步骤如下:

  • 新建数据库名ecology,与初始化数据库名相同即可,然后需要设置utf-8编码

  • 修改mysql.ini配置,在[mysqld]中新增内容

      character-set-server=utf8
      log_bin_trust_function_creators=1
      lower_case_table_names = 1
      sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
      transaction_isolation = READ-COMMITTED
      group_concat_max_len = 102400
      //修改默认存储引擎为InnoDB
      default-storage-engine=InnoDB
    

修改后重启mysql服务,然后再点击步骤中的初始化数据库,出现success即初始化成功,安装完成,即可访问

调试部署:
配置文件/Resin/conf/resin.properties,添加idea的调试代码即可

将Ecology文件夹中的classbean文件(泛微Ecology编译好的class文件)导入idea,运行配置添加远程jvm即可


发包即可抓包获取调试

0x04、漏洞复现

由于POC暂未直接公开,复现分析均以分析思路为主,执行payload进行打码处理。

0x05、原理分析

直接定位到有问题的CheckServer.jsp文件

通过FileUpload类生成了一个request请求的对象,可以调用request用户请求的参数

再根据不同的type值进行不同的处理方式

type等于checkPluginFile时,获取fileHash参数,并调用PluginServiceImpl.checkPluginFile方法,跟进checkPluginFile发现并没有相关的SQL执行操作

接着当type等于mobileSetting时,获取settings参数和timestamp参数,一起传入并调用PluginServiceImpl.syncMobileSetting方法

接着跟进PluginServiceImpl.syncMobileSetting方法,该方法先是从paramString1参数(也就是传入的settings参数)中读取json数据并转化为列表list,表明了settings参数值必须满足Arrayjson格式,即[{"xx":"xx","xxx":"xxx"}]格式,接着执行两个sql语句,不存在注入,然后判断list是否不存在或者为空

因此settings参数必须赋值,赋值内容往下跟进看

接着创建list列表的迭代器循环读取list表中的元素,通过获取的元素可以知道settings参数的json数据内容包括(scope、module、setting、modulename、include、orasc)六个元素,

i变量(也就是scope参数)等于1|7|8|9|10时,操作内容都是向arrayList数组列表添加数据

相关的添加完成过后,最后执行sql语句,也不存在sql注入

其中当i变量(也就是scope参数)等于2|3时,会调用saveMobileDocSetting方法,其中传递的参数分别是(scope、setting、modulename)


接着跟进saveMobileDocSetting方法,第一步进行判断,如果paramInt参数(传入的scope)<= 0,或者paramString2参数(传入的modulename)等于空的话,直接就返回了,因此条件必须满足scope>0,modulename不为空

接着判断paramString1(setting)不为空的话,执行3处sql语句,该语句参数可控,但不存在SQL注入

接着就是重点的逻辑取值部分,先看前部分,也就是说当setting值等于@xxx1#xxx2时,bool判断为true,并且去掉@号进行重新赋值此时setting值为xxx1#xxx2,随后将#作为分割符号,分割后xxx1xxx2分别放入数组arrayOfString

再看后半段的逻辑取值,这里将前半段逻辑取值处理过后的arrayOfString数据通过|符号进行分割后重新放入新的数组arrayOfString1,也就是当前面分割前如果setting值为@xx|x1#xxx2,通过前半段分割后变成xx|x1xxx2,后半段再将|进行分割,将xx|x1分割成xxx1放入数组arrayOfString1

随后通过判断bool变量值

如果为bool值为true也就是setting值以@为开头,则对arrayOfString1[0](也就是后半段逻辑取值中获取的xx|x1中的xx数据)进行url解码后赋值给str2变量,最后执行SQL,此时SQL语句str2可控,存在SQL注入。

若bool为fasle,也就是setting值不以@为开头,例如xxx1#xxx2,则直接将paramString2值(传入的modulename参数)赋值给str2,然后执行SQL语句,此时str2可控,理论上同前一种相同都存在SQL注入,将传入的paramString2值构造成恶意的sql语句,也能实现注入,但实际测试发现传入的paramString2值的字节被编码了导致语法错误,因此该参数不存在SQL注入


主体判断其他的type判断分支思路同上,就不赘述了。

总结下条件:

  • settings参数必须满足Arrayjson格式且存在
  • scope>0,modulename不为空
  • setting参数必须以@开头,并且存在#号进行分割,分割的前半段数据中需要存在|符号进行分割,|符号分割后的前半段需要经过URL编码一遍
  • 最后将整体的请求setting参数再URL编码一遍,因为提交给服务器时会进行URL解码,如果只存在一次编码此时payload里面的字符会被解码出来导致执行失败。

0x06、漏洞修复

目前官方已发布安全补丁,建议受影响用户尽快升级至10.57及以上版本。
https://www.weaver.com.cn/cs/securityDownload.asp#

该漏洞官方补丁修复:

  • 直接删除该文件代码(从源头解决问题)

0x07、参考链接

https://nox.qianxin.com/article/575
https://www.weaver.com.cn/cs/securityDownload.asp#