Apache OFBiz是一款基于 Web 的开源企业资源规划和客户关系管理套件。该软件具有会计、目录和供应链管理、存储付款信息等功能。Apache OFBiz 被许多大型组织使用,之前披露的漏洞已被广泛利用。
2024 年,Apache OFBiz 发布了少量未经认证的代码执行 CVE。8 月,网络安全和基础设施安全局将其中一个 CVE-2024-32113 添加到其已知被利用漏洞目录中,其实这三个漏洞(CVE-2024-32113 、CVE-2024-36104 、CVE-2024-38856)本质上是具有相同根源的相同漏洞。
环境部署
执行以下命令数据导入:
gradlew.bat loadAll
如果使用MySQL作为存储需要修改配置文件(参考):
https://blog.csdn.net/weixin_38989540/article/details/106106001
进入\framework\entity\config\entityengine.xml
选中的修改为localmysql

修改数据库连接密码

创建ofbiz库
执行gradlew.bat loadAll命令导入数据库

现在表里都有字段了

idea打开项目
终端执行以下命令:
./gradlew ofbiz –debug-jvm

添加一个运行配置

点击Dbug

访问https://127.0.0.1:8443/webtools/control/main

调试的时候host要设置127.0.0.1,不然会报错。

漏洞分析
请求url为:https://127.0.0.1:8443/webtools/control/forgotPassword/./ProgramExport
ControlFilter#doFilter会对URL进行标准化处理,这里去掉了./

然后会走到RequestHandler#doRequest方法。
从XML文件中读取控制器配置

跟进看下,解析WEB-INF/controller.xml这个文件。

最后控制器配置数据保存在ccfg

再往后就是初始化变量path、requestUri和overrideViewURI的值。

getRequestUri方法获取requestUri,通过/分割,返回第0个元素。

getOverrideViewUri方法获取,通过/分割,干掉了第0个元素,然后返回。


requestUri和overrideViewUri的最终计算值为requestUri=forgotPassword和overrideViewUri=ProgramExport

跟进下面的Collection
大概是从控制器读取requestUri传递的配置信息。

对应的配置信息如下,其中关键的是auth为false,

返回后继续往下跟
requestMap.securityAuth的结果为false,代表不会进入安全检查。

type为view,进入if分支。
viewName的值为ProgramExport,这是路径的第二部分,而刚才进行检查的是第一部分。

跟进renderView()方法
获取http请求传递的参数,

往下看,获取ProgramExport视图相关的配置信息

跟进发现获取\framework\webtools\webapp\webtools\WEB-INF\controller.xml

视图信息为component://webtools/widget/EntityScreens.xml#ProgramExport

获取视图信息保存在nextPage

渲染视图

后面的调用栈如下:
executeScript:342, ScriptUtil (org.apache.ofbiz.base.util)
executeScript:324, ScriptUtil (org.apache.ofbiz.base.util)
runAction:634, AbstractModelAction$Script (org.apache.ofbiz.widget.model)
runSubActions:143, AbstractModelAction (org.apache.ofbiz.widget.model)
renderWidgetString:278, ModelScreenWidget$Section (org.apache.ofbiz.widget.model)
renderScreenString:164, ModelScreen (org.apache.ofbiz.widget.model)
render:140, ScreenRenderer (org.apache.ofbiz.widget.renderer)
render:102, ScreenRenderer (org.apache.ofbiz.widget.renderer)
render:113, MacroScreenViewHandler (org.apache.ofbiz.widget.renderer.macro)
最后跟到ScriptUtil#executeScript(java.lang.String, java.lang.String, java.util.Map<java.lang.String,java.lang.Object>, java.lang.Object[])
当前后缀为.groovy,进入if调用GroovyUtil.runScriptAtLocation(filePath, functionName, context);

跟进GroovyUtil.runScriptAtLocation方法
创建一个脚本对象并获取脚本,如果methodName为空,调用script.run(),这样会运行整个脚本文件。

跟进script.run()进入到ProgramExport.groovy
获取参数

shell.evaluate(groovyProgram)执行后成功弹出计算器

漏洞复现
这个POC适用于CVE-2024-32113 、CVE-2024-36104 、CVE-2024-38856
POST /webtools/control/forgotPassword/ProgramExport HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: 127.0.0.1:8443
Content-Length: 61
groovyProgram=throw+new+Exception(‘calc.exe’.execute().text);

参考
补丁分析
18.12.13
补丁:比较原始URL和标准化后的URL是否一致,如果不一致则拒绝该请求。
绕过:通过使用;代替./绕过限制。

18.12.14
补丁:从URI中删除;和URL编码的;
绕过:不需要遍历或分号序列,对类似路径的请求/webtools/control/forgotPassword/ProgramExport会导致控制器设置为“forgotPassword”,视图映射设置为“ProgramExport”

18.12.15
为ProgramExport和EntitySQLProcessor 添加权限检查,因此,这两种漏洞利用技术都不再可行。

