Apache OFBiz是一个电子商务平台,用于构建大中型企业级、跨平台、跨数据库、跨应用服务器的多层、分布式电子商务类应用系统。2024年5月,官方发布新版本修复了CVE-2024-32113 Apache OFBiz 目录遍历致代码执行漏洞,攻击者可构造恶意请求控制服务器。建议尽快修复漏洞。
0X02 Groovy执行分析
/framework/webtools/webapp/webtools/WEB-INF/controller.xml
412-416行
<request-map uri="ProgramExport"> <security https="true" auth="true"/> <response name="success" type="view" value="ProgramExport"/> <response name="error" type="view" value="ProgramExport"/> </request-map>
可以看到是view类型
652行写着对应配置位置
apache-ofbiz-18.12.11/framework/webtools/widget/EntityScreens.xml
74-96行
<screen name="ProgramExport"> <section> <actions> <set field="titleProperty" value="PageTitleEntityExportAll"/> <set field="tabButtonItem" value="programExport"/> <script location="component://webtools/groovyScripts/entity/ProgramExport.groovy"/> </actions> <widgets> <decorator-screen name="CommonImportExportDecorator" location="${parameters.mainDecoratorLocation}"> <decorator-section name="body"> <screenlet> <include-form name="ProgramExport" location="component://webtools/widget/MiscForms.xml"/> </screenlet> <screenlet> <platform-specific> <html><html-template location="component://webtools/template/entity/ProgramExport.ftl"/></html> </platform-specific> </screenlet> </decorator-section> </decorator-screen> </widgets> </section> </screen>
可以看见调用了
/webtools/groovyScripts/entity/ProgramExport.groovy
56-82行
parameters.groovyProgram = groovyProgram } else { groovyProgram = parameters.groovyProgram } // Add imports for script. def importCustomizer = new ImportCustomizer() importCustomizer.addImport("org.apache.ofbiz.entity.GenericValue") importCustomizer.addImport("org.apache.ofbiz.entity.model.ModelEntity") def configuration = new CompilerConfiguration() configuration.addCompilationCustomizers(importCustomizer) Binding binding = new Binding() binding.setVariable("delegator", delegator) binding.setVariable("recordValues", recordValues) ClassLoader loader = Thread.currentThread().getContextClassLoader() def shell = new GroovyShell(loader, binding, configuration) if (UtilValidate.isNotEmpty(groovyProgram)) { try { // Check if a webshell is not uploaded but allow "import" if (!SecuredUpload.isValidText(groovyProgram, ["import"])) { logError("================== Not executed for security reason ==================") request.setAttribute("_ERROR_MESSAGE_", "Not executed for security reason") return }
从groovyProgram获取参数,SecuredUpload.isValidText进行黑名单检查。
其中调用getDeniedWebShellTokens();得到黑名单。
可以看到没有对**execute()**过滤。
直接可以使用. "".execute()执行命令,或者直接unicode编码。
0x03 目录遍历分析
/ControlFilter.java
18.12
18.10
可以看到使用httpRequest.getRequestURI() 获取url,这么一看就有两种绕过的。**"../"和";"**进行截断绕过filter处理。
来看看修复方式,
18.13
equals进行判断,不一致直接抛出。
18.14
url包含 ".." 或者**";"** 替换为空,然后比较。
整个漏洞点很简单,绕过filter。
0x04 复现
这里直接使用18.10的环境,懒得下了。
直接替换为18.13的framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
可以看到,使用**";"** 截断就可以绕过检测。
最后也是成功执行。
0x05 修复建议
升级到官网最新版本。