问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
Apache OFBiz 最新Grovvy代码执行分析(CVE-2024-36104)
漏洞分析
这个月爆出了CVE-2024-36104这个漏洞,实际上CVE-2024-32113和新爆出的CVE-2024-36104应该都是基于webtools/control/ProgramExport这个接口所产生的漏洞,该接口用于后台执行groovy代码,攻击者可以通过恶意的groovy代码实现任意命令执行
前言 == Apache OFBiz是一个开源的开发框架,它提供了一些预制的逻辑用于开发企业级的业务流程。 在今年5、6月份分别爆出了两个目录遍历导致命令执行的漏洞**CVE-2024-32113**和**CVE-2024-36104** ![image1.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-b67b57456111e79fe2677158438a970fce003504.png) ![image2.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-804e9c1895e329212b5c429095191af800650be8.png) 当我在寻找漏洞相关poc的时候,发现很多公众号都放出了关于CVE-2024-32113这个漏洞的相关poc,但是接口都是webtools/control/xmlrpc,实际上这个接口是CVE-2020-9496反序列化漏洞的接口,而且在18.12.10版本之后,OFBiz官方对于这个接口的漏洞修复方法是直接移除了XML-RPC相关的逻辑了,所以部分公众号发布的关于CVE-20240-32113这个漏洞的poc都是不对的 ![image3.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-2a2536d695ae0589f5cb09ff1d729b2180f92a7d.png) 紧着在这个月爆出了CVE-2024-36104这个漏洞,实际上CVE-2024-32113和新爆出的CVE-2024-36104都是基于webtools/control/ProgramExport这个接口所产生的漏洞,该接口用于后台执行groovy代码,攻击者可以通过恶意的groovy代码实现任意命令执行 环境搭建 ==== 这里下载的ofbiz版本为**18.12.14** 安装gradle后,将项目导入到IDEA,执行build后会在build/libs下生成一个ofbiz.jar 然后添加JAR Application,设置JAR的路径后启动就可以开始调试项目了 ![image4.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-743717f0744a9b6be39ab27bfd11df297ce06330.png) 访问https://127.0.0.1:8443/accounting 能看到登录界面说明搭建成功 CVE-2023-51467分析 ================ 我们先看看CVE-2023-51467这个漏洞,这个漏洞是一个鉴权绕过漏洞,可以实现绕过身份验证机制从而直接调用后台的一些接口,实际上应该也是webtools/control/ProgramExport这个接口漏洞最早的利用方式,这里可以使用**vulhub/ofbiz/CVE-2023-51467**的环境 启动环境后直接发送poc执行id命令,可以看到成功执行命令 ![image5.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-2bb7928ed61c0025819f40f0bd32706679b24d25.png) 现在通过代码来分析一下,Apache OFBiz中,对于登录的验证在org.apache.ofbiz.webapp.control.LoginWorker#checkLogin()下,根据poc详情,只要在登录时提交参数**USERNAME=&PASSWORD=&requirePasswordChange=Y**就能绕过登录 在未登录的情况下,userLogin==null,程序会进入到if语句下,这里的验证逻辑是当返回内容不是error时则为认证成功 ![image6.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-0ecd6dc299b1bd9e242ef379658bf72fde9d170a.png) 这里会判断username和password是否为null,还判断login(request, response)的返回值是否为error ![image7.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-fa6bff906554921bf8c5fa7cd68fa2735f667618.png) 在login()方法下首先会判断username和password是否为空,如果为空的话就给unpwErrMsgList添加一个值,接着会判断requirePasswordChange是否等于Y,当requirePasswordChange=Y成立时,就会将requirePasswordChange的值赋为true 程序执行到return语句时,由于requirePasswordChange为true,所以login()返回的内容为requirePasswordChange ```java return requirePasswordChange ? "requirePasswordChange" : "error"; ``` ![image8.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-a68c3dadc1dec0fc86f2cb7201c3266ff02bfd28.png) 返回到checkLogin()中,由于if条件不成立,继续向下执行到最后直接返回success,所以就能绕过checkLogin()的身份认证 ![image9.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-828587c8209d37e6d03f5c8e988f4b620b82d5bc.png) 官方为了修复这个漏洞,发布了18.12.11版本,现在来看看官方是如何修复的,修复版本改用UtilValidate.isEmpty()来判断参数的值是否为空 ![image10.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-310b7ffae4a313231ebcd3a4120c3440444018c3.png) 新漏洞分析 ===== 没有找到有关CVE-2024-32113这个漏洞的相关文章,但是找到了CVE-2024-36104的相关poc,关于漏洞的描述是由于在controlfilter类中对路径限制不当导致攻击者能够绕过后台功能点的身份验证 **下面是找到的在网上公开的poc:** [https://mp.weixin.qq.com/s/tsG1wbKqGs\_yyzQhJr6ZLw](https://mp.weixin.qq.com/s/tsG1wbKqGs_yyzQhJr6ZLw) groovyProgram的内容是unicode加密后的 ```java POST /webtools/control/forgotPassword/%2e/%2e/ProgramExport HTTP/1.1 Host: x.x.x.x User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35 Connection: close Content-Length: 262 Content-Type: application/x-www-form-urlencoded user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10\_14\_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15 Accept-Encoding: gzip groovyProgram=\\u0074\\u0068\\u0072\\u006f\\u0077\\u0020\\u006e\\u0065\\u0077\\u0020\\u0045\\u0078\\u0063\\u0065\\u0070\\u0074\\u0069\\u006f\\u006e\\u0028\\u0027\\u0069\\u0064\\u0027\\u002e\\u0065\\u0078\\u0065\\u0063\\u0075\\u0074\\u0065\\u0028\\u0029\\u002e\\u0074\\u0065\\u0078\\u0074\\u0029\\u003b ``` 在最新发布的18.12.14版本中官方也是在controlfilter中添加了对;和%2e的过滤 <https://github.com/apache/ofbiz-framework/commit/d33ce31012> ![image11.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-50a7c7b8e7ec5853a4b50c0f66e157d69d82ee8f.png) **但是发现其中也存在一些问题,接下来使用最新版本18.12.14来进行调试** 当利用上面的poc发送请求的时候,发现是能够成功执行命令的 尝试在不使用%2e特殊字符,直接请求/webtools/control/forgotPassword/ProgramExport接口的情况下发现也可以绕过身份验证调用后台接口 ![image12.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-7058eb5e05d00c0958dd1c256c0b5eb425d998d4.png) 将断点下在ProgramExport.gvooy下 然后向webtools/control/forgotPassword/ProgramExport接口发送请求,可以获取到调用栈 ![image13.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-733a877234956dcada01a4f3536a173cd6728b1b.png) 从调用栈中可以看到请求首先经过一系列的filter,先跟进到ControlFilter#dofilter()下 红框里的代码是官方在18.14.13版本之后新增加的,在这里对我们的请求没有限制,程序继续向下执行 ![image14.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-4639e19c147cb35cc6522d75213ae87be43ae29e.png) 在这里主要关注的点是为什么请求的是/webtools/control/forgotPassword/ProgramExport接口时,但是实际调用的是ProgramExport接口,而且能利用forgotPassword来绕过身份验证 具体的处理逻辑从webapp.control.ControlServlet#doGet()开始,该方法主要是做请求预处理,包括获取用户session信息、设置响应头,接着就会进入到RequestHandler.doRequest() 程序首先会解析WEB-INF/common-controller.xml配置文件,获取request-map标签的相关信息,在security标签中保存了接口是否需要鉴权的信息,当该接口无需身份验证就能访问时auth的值就为false,从下图中我们可以看到forgotPassword是无需鉴权的 ![image15.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-a509b1dcbd8aabf566d0e2a567856ba14ff9cb09.png) 首先跟进到RequestHandler.doRequest()第286行下面,系统会通过所请求接口requestUri去生成一个requestMap对象,该对象有一个属性为securityAuth,该属性的值是从commom-controller.xml中获取的,保存的是security标签里auth的值 ![image16.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-68ac7b82d7d1d3a2050b747ed5a4285725918c71.png) 向上看看requestUri的值是如何得到的,往上在第274行可以看到path经过getRequestUri()之后得到requestUri,在getRequestUri中将path以/为分隔符分开,接着返回list\[0\]也就是forgotPassword ![image17.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-2540f2778be063bce2152b5198099067e2697636.png) ![image18.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-042741f9e97759ecc1746f7964c65408783dbf65.png) 得到了requestUri之后,接着看后面一行调用getOverrideViewUri(),这个方法返回了ProgranExport保存在overrideViewUri变量中,这个在后面会用到 ![image19.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-b9c3f342d1e0b5f525262b65b5901dd71d3707e6.png) ![image20.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-2c2d4036adc67c56d31325b95d132b1e77479141.png) 接着继续向下执行到第480行,如果requestMap.security的值为true的话,就会进入到if语句,调用到下面的this.runEvent(request,response,checkLoginEvent,null,”security-auth”),这行代码实际上会调webapp.control.LoginWorker#checkLogin()进行用户身份验证 ![image21.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-814255b09a8514076c27dc77ab6993b8b1658c05.png) 由于我们的requestUri是forgotPassword,所以得到的requestMap.securityAuth为False,所以这里不会进入到if语句里,也就绕过了身份验证 继续向下执行到第717行,首先对nextRequestResponse.type的值进行判断,当type的值为view时进入到renderView(),通过调试可以看到nextRequestResponse.type=view,程序是会执行到739行的 ![image22.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-95d17a23bd14ebf437fd224f45f84cd192bc8521.png) ![image23.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-05c40fcb9893c34ce420bfaaeb390d7d1d17865a.png) 这里就用到了上面提到的overrideViewUri变量,最后得到viewName的值是ProgramExport,进入renderView()之后就开始处理业务逻辑了 ![image24.png](https://shs3.b.qianxin.com/attack_forum/2024/06/attach-61e816a23e7aee04266990d33ee1258e3958758c.png) **以上就是关于Apache OFBiz漏洞的分析,看到有错误的地方,麻烦师傅们指出来下!!**
发表于 2024-06-14 10:51:16
阅读 ( 31396 )
分类:
漏洞分析
1 推荐
收藏
0 条评论
请先
登录
后评论
kakakakaxi
4 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!