|
某大型CMS后台注入从分析到利用 (qq.com)
某大型CMS后台注入从分析到利用joker [url=]HACK之道[/url] 昨天
本文首发于奇安信攻防社区
搭建环境Github找一下若依4.6.1版本下载到本地,丢到IDEA里面,数据库文件导入,druid连接池配置文件中修改username和password
在application.yml文件中可更改服务默认端口,80端口被占用修改成其他空闲端口
完成数据库导入和配置文件一些必要信息的修改之后就可以运行整个项目了
漏洞分析若依cms这个后台SQL注入貌似还没有公开漏洞细节,相关的分析内容很难找,Google到了其中一篇文章,获取到了关键的污点传播路径,整理如下:
- RuoYi/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java:56,`role`为污点源
- ->RuoYi/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java:37,污点源从`role`传递至`dataScope`
- ->RuoYi/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java:19,污点传入selectRoleList方法
- ->RuoYi/ruoyi-system/src/main/resources/mapper/system/SysRoleMappper.xml:36,'SQLI'类型触发注入
初看比较疑惑,顺着污点传播路径跟进不太明白poc是怎么整出来的,看到最后的xml文件也就是漏洞触发点也就清楚是怎么一回事了,先从污点源开始看
RuoYi/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
查看代码可以确定利用的漏洞路径为/system/role/list,以POST的方式进行传参,可以看到初始的污点源为传递给TableDataInfo的参数role,跟进方法中调用的startPage()方法
Ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java
函数体打断点处,调用了TableSupport类的buildPAgeRequest(),如果pageNum和PageSize两个参数值不为空的话就会进行分页处理,调用的是pagehelper这个第三方插件,跟进buildPAgeRequest()方法分析是如何进行赋值处理的
Ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/core/page/TableSupport.java
实例化一个PageDomain类,并通过ServletUtils类从post传递的数据中获取对应的参数值,所以这几个参数值对漏洞利用并没有太大的影响,让其获取到的都为空就可以,第一部分poc
- pageSize=&pageNum=&orderByColumn=&isAsc=
顺着污点传播链,跟进RuoYi/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java文件
对dataScope参数的一个拼接,并且进行了类型的转换,继续跟传播链,RuoYi/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java
注释已经写明此处根据分页查询角色数据,暂时不知道污点为何会传入selectRoleList()方法,继续跟传播链
RuoYi/ruoyi-system/src/main/resources/mapper/system/SysRoleMappper.xml
可以看到这里是SQL查询语句,具体为什么这么写可以去自行百度一下,可以看到这里直接将${params.dataScope}拼接入了SQL语句中,因此构造SQL注入语句就能够查询我们想要获取的数据,到这里也就不难理解为什么污点源会变成dataScope,现在根据公开的poc来捋一捋整个链
role为初始污点源->调用RuoYi/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java#selectRoleList方法->selectRoleList方法调用RuoYi/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java中的SysRole类,该类会对dataScope参数进行处理->dataScope传入了RuoYi/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java#selectRoleList方法->调用SQL查询时拼接dataScope参数值进行了注入
可能并不是很准确,但是自己是这么理解的,有师傅理解更到位的话请多多指教
第二部分poc
- roleName=&roleKey=&status=&params[beginTime]=&params[endTime]=&params[dataScope]=and extractvalue(1,concat(0x7e,substring((select database()),1,32),0x7e))
将两部分poc结合也就得到了公开的poc,其实从poc入手,再直接看到最后的漏洞注入点能够更好理解poc为什么是这么构造的,其他参数的值皆为空默认就会为null,只传入dataScope这个参数值也是可以的
- url/system/role/list
- POST:pageSize=&pageNum=&orderByColumn=&isAsc=&roleName=&roleKey=&status=&params[beginTime]=&params[endTime]=&params[dataScope]=and extractvalue(1,concat(0x7e,(select database()),0x7e))
本地复现
可以看到通过报错注入获取到了数据库的名字,后面更改SQL语句就能够获取到详细的数据库信息了
项目测试打开给定的地址,看到这个界面就觉得很熟悉,之前审报告的就是就看到很多回,若依没跑了,站点应该只是更改了一些静态资源。
登录还是常规手段尝试弱口令,admin/admin123,直接进去了后台
burp抓个包,poc打过去,获取到了数据库名
得到如下部分数据库中的信息,详细的就不公开了
- exam_banner,exam_collect,exam_p 表名
- id,title,banner_img,is_put,cont #exam_banner表中的列名,不完整,长度限制,可以分长度读出
总结整个到这里就差不多结束了,漏洞分析的可能不是特别到位,师傅们轻喷,只是想知道poc的参数是怎么构造的才去扒拉源码分析的,跟着poc去分析会更好理解,也就有了这篇文章。
END
|
|