Apache OFBiz目录遍历导致RCE(CVE-2024-38856)
环境搭建
下载地址: https://ofbiz.apache.org/download.html
下载的是17.02版本(下载的是17.02版本(代码有点区别但是能复现漏洞,建议还是18版本)
然后在build.gradle 中设置jvm 调式参数
List jvmArguments = ['-Xms128M', '-Xmx1024M','-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005'] |
构建项目:
./gradlew cleanAll loadAll |
这时候会编译出jar
直接运行
./gradlew ofbiz |
不需要等待到100%
访问:https://localhost:8443/accounting/control/main
poc:
POST /webtools/control/forgotPassword;/ProgramExport HTTP/1.1 |
groovy代码注入,早在2023年就出现过CVE: CVE-2023-51467
https://blog.csdn.net/qq_53003652/article/details/135311261
编码绕过
在CVE-2023-51467 的基础上 进行unicode编码绕过
断点:groovyScripts/entity/ProgramExport.groovy
跟进isValidText
黑名单检测:
搬了exec 所以 直接 execute 也是不行的
进行unicode编码,能进行绕过
路径遍历
在一个ControlFilter的处理逻辑
在这里主要关注的点是为什么请求的是/webtools/control/forgotPassword/ProgramExport接口时,但是实际调用的是ProgramExport接口,而且能利用forgotPassword来绕过身份验证
具体的处理逻辑从webapp.control.ControlServlet#doGet()开始,该方法主要是做请求预处理,包括获取用户session信息、设置响应头,接着就会进入到RequestHandler.doRequest()
从代码上看,安全策略是由xml来配置的,找到相关配置文件:
webcommon/WEB-INF/common-controller.xml
在xml中获取request-map标签的相关信息,在security标签中保存了接口是否需要鉴权的信息,当该接口无需身份验证就能访问时auth的值就为false,从下图中我们可以看到forgotPassword是无需鉴权的
requestMap对象属性为securityAuth,该属性的值是从commom-controller.xml中获取的,保存的是security标签里auth的值,如果为true 就会检查是否登录了
再看看requestMap 怎么来的:
也就是 取决于前面的defaultRequestUri
继续查看defaultRequestUri
然而最后的view视图是取决于overrideViewUri
总结: 检查鉴权的是defaultRequestUri ( forgotPassword ) 而渲染视图的是 overrideViewUri(ProgramExport)
这样就绕过了登录检查,平常审计的时候也应该密切关注安全检查的策略
修复
来看看修复方式:
filter里面就搬了;和./
此外还对接口脚本处,多增一处权限校验
进一步的修复:https://github.com/apache/ofbiz-framework/commit/6c3b0068a99bb3b93321fdb983a0046b0679c86d
就不跟了
Reference: