RuoYi-Flowable-Plus 0day表达式注入
字数 1676 2025-08-03 16:44:16

RuoYi-Flowable-Plus 表达式注入漏洞分析与利用指南

漏洞概述

RuoYi-Flowable-Plus是基于若依系统二次开发的工作流系统,集成了Flowable流程引擎。该系统v0.8.3版本存在表达式注入漏洞,攻击者可通过精心构造的表达式实现远程代码执行。

受影响版本

  • RuoYi-Flowable-Plus v0.8.3
  • 下载地址:https://gitee.com/KonBAI-Q/ruoyi-flowable-plus

漏洞利用方法

方法一:使用Java类实现RCE

条件要求:

  1. 目标类需要具有公共无参构造函数(系统使用newInstance实例化)
  2. 需要实现JavaDelegate接口,存在execute函数

可利用类:

  1. org.flowable.engine.impl.test.NoOpServiceTask

    • 添加name表达式:
      ${''.getClass().forName('java.lang.Runtime').getMethod('getRuntime').invoke(null).exec('calc.exe')}
      
  2. org.flowable.engine.impl.bpmn.listener.ScriptExecutionListener

    • 添加以下两个变量(选择表达式类型):
      • script: var System = java.lang.Runtime.getRuntime().exec("calc");
      • language: js

方法二:直接使用表达式

直接使用表达式注入:

${''.getClass().forName('java.lang.Runtime').getMethod('getRuntime').invoke(null).exec('calc.exe')}

详细利用步骤

利用NoOpServiceTask类

  1. 新建表单并保存
  2. 新增流程分类
  3. 新增流程模型
  4. 点击"设计"按钮
  5. 点击创建开始事件,并添加监听器
  6. 设置监听器内容为NoOpServiceTask类,并添加恶意表达式
  7. 选择之前新建的表单
  8. 保存流程
  9. 点击"部署"按钮
  10. 新建流程并点击"发起"
  11. 随意输入值点击"提交",命令执行成功

利用ScriptExecutionListener类

  1. 将流程模型中的监听器改为ScriptExecutionListener
  2. 设置script和language参数为恶意值
  3. 点击"部署"(必须步骤,否则流程模型不会被更改)
  4. 在新建流程中发起流程,点击提交触发漏洞

直接使用表达式

  1. 在适当位置插入恶意表达式
  2. 点击部署
  3. 发起流程,命令执行成功

漏洞原理分析

Java类利用流程

  1. org.flowable.engine.impl.bpmn.listener.ListenerNotificationHelper#executeExecutionListeners开始处理
  2. 进入createClassDelegateExecutionListener函数,调用create函数
  3. 创建ClassDelegate类并将监听器赋值到此类中
  4. 执行ClassDelegate类的notify函数
  5. 最终执行到defaultInstantiateDelegate函数实例化监听器
  6. 返回到DelegateExecutionListener的构造函数
  7. 调用DelegateExecutionListener类的notify函数
  8. 经过一系列函数调用后解析表达式,实现命令执行

表达式直接利用流程

  1. org.flowable.engine.impl.bpmn.listener.ListenerNotificationHelper#executeExecutionListeners处理
  2. 直接创建ExpressionExecutionListener
  3. 调用ExpressionExecutionListener类的notify函数
  4. 最终解析表达式,实现命令执行

防御建议

  1. 升级到最新版本,检查是否有官方补丁
  2. 对用户输入的表达式进行严格过滤和验证
  3. 限制Flowable引擎的表达式解析能力
  4. 实施最小权限原则,限制系统命令执行能力
  5. 使用安全沙箱技术限制表达式执行环境

总结

该漏洞利用Flowable流程引擎的表达式解析功能,通过精心构造的恶意表达式实现远程代码执行。攻击者需要具备一定的后台操作权限,但一旦利用成功危害极大。建议用户及时采取防护措施,避免系统被攻击者控制。

RuoYi-Flowable-Plus 表达式注入漏洞分析与利用指南 漏洞概述 RuoYi-Flowable-Plus是基于若依系统二次开发的工作流系统,集成了Flowable流程引擎。该系统v0.8.3版本存在表达式注入漏洞,攻击者可通过精心构造的表达式实现远程代码执行。 受影响版本 RuoYi-Flowable-Plus v0.8.3 下载地址:https://gitee.com/KonBAI-Q/ruoyi-flowable-plus 漏洞利用方法 方法一:使用Java类实现RCE 条件要求: 目标类需要具有公共无参构造函数(系统使用newInstance实例化) 需要实现JavaDelegate接口,存在execute函数 可利用类: org.flowable.engine.impl.test.NoOpServiceTask 添加name表达式: org.flowable.engine.impl.bpmn.listener.ScriptExecutionListener 添加以下两个变量(选择表达式类型): script: var System = java.lang.Runtime.getRuntime().exec("calc"); language: js 方法二:直接使用表达式 直接使用表达式注入: 详细利用步骤 利用NoOpServiceTask类 新建表单并保存 新增流程分类 新增流程模型 点击"设计"按钮 点击创建开始事件,并添加监听器 设置监听器内容为NoOpServiceTask类,并添加恶意表达式 选择之前新建的表单 保存流程 点击"部署"按钮 新建流程并点击"发起" 随意输入值点击"提交",命令执行成功 利用ScriptExecutionListener类 将流程模型中的监听器改为ScriptExecutionListener 设置script和language参数为恶意值 点击"部署"(必须步骤,否则流程模型不会被更改) 在新建流程中发起流程,点击提交触发漏洞 直接使用表达式 在适当位置插入恶意表达式 点击部署 发起流程,命令执行成功 漏洞原理分析 Java类利用流程 org.flowable.engine.impl.bpmn.listener.ListenerNotificationHelper#executeExecutionListeners 开始处理 进入 createClassDelegateExecutionListener 函数,调用create函数 创建 ClassDelegate 类并将监听器赋值到此类中 执行 ClassDelegate 类的 notify 函数 最终执行到 defaultInstantiateDelegate 函数实例化监听器 返回到 DelegateExecutionListener 的构造函数 调用 DelegateExecutionListener 类的 notify 函数 经过一系列函数调用后解析表达式,实现命令执行 表达式直接利用流程 org.flowable.engine.impl.bpmn.listener.ListenerNotificationHelper#executeExecutionListeners 处理 直接创建 ExpressionExecutionListener 类 调用 ExpressionExecutionListener 类的 notify 函数 最终解析表达式,实现命令执行 防御建议 升级到最新版本,检查是否有官方补丁 对用户输入的表达式进行严格过滤和验证 限制Flowable引擎的表达式解析能力 实施最小权限原则,限制系统命令执行能力 使用安全沙箱技术限制表达式执行环境 总结 该漏洞利用Flowable流程引擎的表达式解析功能,通过精心构造的恶意表达式实现远程代码执行。攻击者需要具备一定的后台操作权限,但一旦利用成功危害极大。建议用户及时采取防护措施,避免系统被攻击者控制。