Apache OFBiz 命令执行漏洞分析

1. XML-RPC反序列化命令执行(CVE-2020-9496)

1-1. 前言

官方公告:

https://issues.apache.org/jira/browse/OFBIZ-11716

漏洞描述:

由于 webtools 中的 2 个 xmlrpc 相关请求(xmlrpc 和 ping)未使用身份验证,以及未对传入XML-RPC消息进行校验,所以容易受到不安全反序列化的影响。

影响版本:

Apache OfBiz 17.12.03

1-2. xml-rpc请求格式

XML内容的根元素是<methodCall>,每个<methodCall>元素都包含一个<methodName>元素和一个<params>元素。<methodName>元素标识要调用的过程的名称,而<params>元素包含参数列表和值。每个<params>元素包括一个<param>元素列表,而<param>元素又包含值元素。

示例:

<?xml version="1.0"?><methodCall>  <methodName>方法名</methodName>  <params>     <param>        <value>           值元素        </value>     </param>  </params></methodCall>
值元素类型可以是基本数据类型,也可以是复合数据类型。
基本数据类型有:
  • int<int>27</int>, <i4>27</i4>

  • double<double>27.31415</double>, <double>-1.1465</double>

  • Boolean<boolean>1</boolean>, <boolean>0</boolean>

  • string<string>Hello</string>, <string>bonkers! @</string>

  • dateTime.iso8601<dateTime.iso8601> 20021125T02:20:04 </dateTime.iso8601>

  • base64<base64>SGVsbG8sIFdvcmxkIQ==</base64>

复合数据类型就是指数组和结构;
数组<array>可以包含多种基本数据类型:
<array>  <data>     <value><boolean>1</boolean></value>     <value><string>Array collection, eh?</string></value>     <value><int>-91</int></value>     <value><double>142.14325</double></value>  </data></array>

结构<struct>通常用来传递复杂的数据结构(键-值对形式):

<struct>  <member>     <name>键1</name>     <value><string>值1</string></value>  </member>
<member> <name>键2</name> <value><int>值2</int></value> </member></struct>

参考链接:

http://xmlrpc.com/spec.md

https://www.yiibai.com/xml-rpc/xml_rpc_data_model.html

1-3. 环境搭建

下载地址https://archive.apache.org/dist/ofbiz/

解压后用IDEA打开,build之后会生成一个biuld目录,添加配置ofbiz.jar

Apache OFBiz 命令执行漏洞分析

能成功访问https://localhost:8443/webtools就说明环境搭好了。

Apache OFBiz 命令执行漏洞分析

Apache OFBiz 结构简单介绍:

applications:各个应用的目录,包含了OFBiz核心的应用程序组件,如订单管理,电子商务存储等。
framework:框架目录,包含OFBiz框架的组件,例如实体引擎和服务引擎。这是OFBiz框架的核心,其他应用程序都是基于它来构建的。
Ofbiz-component.xml:定义应用程序指定配置文件,库文件等,数据模型,业务逻辑,web应用程序的定位。
src:源文件目录,包含实现业务逻辑的Java类文件。
web.xml:用于配置 Web 应用程序的部署信息和行为,设置路由、filter等。

Controller.xml:定义view,controller之间的映射关系,不仅包含了请求的映射关系,同时还包含了视图的映射关系,以及一系列的处理器比如视图解析处理器,事件处理器等。

1-4. 漏洞复现

POST请求/webtools/control/xmlrpc,使用ysoserial工具生成一个  CommonsBeanutils1 链的payload,要用base64编码。

<?xml version="1.0"?><methodCall><methodName>ProjectDiscovery</methodName><params>    <param>    <value>        <struct>        <member>            <name>test</name>            <value>            <serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">           base64 payload            </serializable>            </value>        </member>        </struct>    </value>    </param></params></methodCall>

Apache OFBiz 命令执行漏洞分析

发送请求,dnslog成功收到请求信息。

Apache OFBiz 命令执行漏洞分析

1-5. 漏洞分析

入口/webtools/control/xmlrpc的路由配置在frameworkwebtoolswebappwebtoolsWEB-INFweb.xml,由ControlServlet处理;

Apache OFBiz 命令执行漏洞分析

直接下断点开始跟踪调试,提取了一堆值,然后调用requestHandler.doRequest()处理具体请求;

Apache OFBiz 命令执行漏洞分析

跟进,requestMap是从frameworkwebtoolswebappwebtoolsWEB-INFcontroller.xml中获取到的xmlrpc相关处理器;

Apache OFBiz 命令执行漏洞分析

跟进RequestHandler.runEvent()方法,调用XmlRcpEventHandler处理 XML-RPC 请求,传递必要的参数,然后获取并保存事件处理器执行后的返回结果。

Apache OFBiz 命令执行漏洞分析

跟进,调用getRequest()获取信息对象;

Apache OFBiz 命令执行漏洞分析

先依次扫描<methodCall>、<methodName>、<params>、<param>、<value>元素标签,记录它的值;

Apache OFBiz 命令执行漏洞分析

读到<struct>标签,返回一个MapParser对象;

Apache OFBiz 命令执行漏洞分析

重复调用XmlRpcRequestParser.startElement(),继续读取元素标签及其值;

Apache OFBiz 命令执行漏洞分析

读到<serializable>标签和使用的XML-RPC 扩展库链接时,跟进到RecursiveTypeParserImpl.startElement(),只有当pURIEXTENSIONS_URI相同时,才能匹配且返回SerializableParser对象,所以payload中必须要添加这个扩展库;

Apache OFBiz 命令执行漏洞分析

SerializableParser是继承ByteArrayParser的,所以跟进到ByteArrayParser.startElement(),创建了一个base64解码器,将payload解码写入baos中。

Apache OFBiz 命令执行漏洞分析

然后开始扫描结束标签,扫描到</serializable>标签,将payload的字节码设为result;

Apache OFBiz 命令执行漏洞分析

接着扫描到</value>标签,解析SerializableParser对象中的result添加到到结果中;

Apache OFBiz 命令执行漏洞分析

跟进SerializableParser.getResult(),对payload字节数组进行了反序列化,触发命令执行。

Apache OFBiz 命令执行漏洞分析

1-5-1. 使用 array 标签

前面使用的是 struct 结构传入数据,扫描到标签返回的是MapParser对象,MapParser.endElement()中调用了父类RecursiveTypeParserImpl.endValueTag(),进而调用SerializableParser.getResult()

同理,ObjectArrayParser.endElement()中也调用了父类RecursiveTypeParserImpl.endValueTag(),所以也可以使用<array>标签构造传入数组数据触发反序列化。

Apache OFBiz 命令执行漏洞分析

poc:

<?xml version="1.0"?>    <methodCall>        <methodName>ProjectDiscovery</methodName>        <params>            <param>                <value>                   <array>                        <data>                            <value>                                 <serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">                                     base64 payload                                 </serializable>                            </value>                        </data>                    </array>                </value>            </param>        </params>    </methodCall>

Apache OFBiz 命令执行漏洞分析

1-6. 补丁分析

补丁链接:https://github.com/apache/ofbiz-framework/commit/d955b03

在controller.xml中对/xmlrpc/ping路由添加了身份校验。

Apache OFBiz 命令执行漏洞分析

但是身份校验仍然可以绕过,产生POST-Auth漏洞(OFBIZ-12332):

https://issues.apache.org/jira/browse/OFBIZ-12332

又在后续补丁中添加CacheFilter对/control/xmlrpc</serializable进行校验,但是还是可以绕过。

Apache OFBiz 命令执行漏洞分析

2. XML-RPC反序列化命令执行(CVE-2023-49070)

2-1. 前言

官方通告:

https://issues.apache.org/jira/browse/OFBIZ-1281

https://lists.apache.org/thread/jmbqk2lp4t4483whzndp5xqlq4f3otg3

洞描述

由于对CVE-2020-9496修复的不完全,导致可以绕过路径检查和授权检查触发恶意数据的反序列化。

响版本:

Apache OfBiz < 18.12.10

2-2. 漏洞复现

环境搭建操作与CVE-2020-9496一样,这里用18.12.09复现。

用CVE-2020-9496的poc进行测试,可以看到调用了CacheFilter进行路径和</serializable标签的检查,检查失败出现报错。

Apache OFBiz 命令执行漏洞分析

在url中略作修改,即可绕过路径检查和授权检查,成功执行命令。

/webtools/control/xmlrpc/;/?USERNAME=ofbiz&PASSWORD=blckder02&requirePasswordChange=Y

Apache OFBiz 命令执行漏洞分析

说一下url的构造,这个请求结构如下:

  • 路径信息:/webtools/control/xmlrpc/
  • 矩阵参数:;/
  • 查询参数:?USERNAME=ofbiz&PASSWORD=blckder02&requirePasswordChange=Y
矩阵参数(Matrix Parameters)是一种在URL中传递参数的方式,其特点是使用分号;将参数附加在路径中。

这里就是附加了一个参数/,或许将参数换成;1要好理解一点,效果一样的。

Apache OFBiz 命令执行漏洞分析

与查询参数不同的是,使用getRequestURI()的返回结果会包含矩阵参数,所以能绕过路径检测。但是getPathInfo()仍然只返回/xmlrpc/,不影响后面xmlrpc处理器的调用。

Apache OFBiz 命令执行漏洞分析

查询参数的内容则是绕过授权检查的必要条件。

2-3. 漏洞分析

在发送请求的时候会进入CacheFilter.doFilter(),因为在uri的末尾添加了/;/,所以不会进入if语句,也就不会对</serializable进行校验;

Apache OFBiz 命令执行漏洞分析

然后进入ControlServlet处理请求,在RequestHandler.doRequest()中,securityAuth就是指Controller.xml中的security标签的值,为true则进入if分支;

Apache OFBiz 命令执行漏洞分析

跟进,调用JavaEventHandler处理该事件;

Apache OFBiz 命令执行漏洞分析

进入LoginWorker.checkLogin(),如果检测到是未登录状态,则直接从请求中获取USERNAMEPASSWORD参数的值,如果值为null,则会进入343行的if语句,返回error,表示校验失败;

Apache OFBiz 命令执行漏洞分析

参数值不为null,还需要使login(request, response)不返回error。

进入login(),从请求中获取了requirePasswordChange参数的值,执行登录操作时由于传入的用户名是随便构造的,所以返回“没有找到用户”,登录失败,进入else分支;

最后根据requirePasswordChange的值判断是返回参数值还是error,所以只要传入requirePasswordChange为true,这里就可以返回true了。

Apache OFBiz 命令执行漏洞分析

回到checkLogin(),uri中不包含loginoutsecurity.login.authorised.during.impersonate默认为false,登录历史也为null,所以跳过if语句,最后返回success,成功绕过登录检测。

Apache OFBiz 命令执行漏洞分析

后面的反序列化调用过程就与CVE-2020-9496一样了。

Apache OFBiz 命令执行漏洞分析

2-4. 补丁分析

补丁链接:https://github.com/apache/ofbiz-framework/commit/c59336f604f503df5b2f7c424fd5e392d5923a27

在补丁中删除了XML-RPC的相关引用。

Apache OFBiz 命令执行漏洞分析

3. groovy命令执行(CVE-2023-51467)

3-1. 前言

官方公告

https://lists.apache.org/thread/9tmf9qyyhgh6m052rhz7lg9vxn390b

https://issues.apache.org/jira/browse/OFBIZ-12873

漏洞描述:

仍然是基于对CVE-2020-9496修复的不完全,导致可以绕过路径检查和授权检查。以及对传入数据的校验不完善,导致可以通过groovy实现命令执行。

影响版本:

Apache OfBiz < 18.12.11

3-2. 漏洞复现

添加groovyProgram参数传入要执行的命令,payload:

/webtools/control/ProgramExport?USERNAME=ofbiz&PASSWORD=blckder02&requirePasswordChange=Y&groovyProgram='calc.exe'.execute()

Apache OFBiz 命令执行漏洞分析

3-3. 漏洞复现

授权检查绕过的过程与CVE-2023-49070的一致,这里就不重复了。

从绕过授权后开始看,在RequestHandler.doRequest()中,requestUriProgramExport,获取到对应的requestMap,又从中获取到success对应的响应,赋给了nextRequestResponse

Apache OFBiz 命令执行漏洞分析

在controller.xml中定义了响应类型为view,名称为ProgramExport,然后调用renderView()进行视图渲染。

Apache OFBiz 命令执行漏洞分析

跟进renderView(),从controller.xml中获取名称为ProgramExport的视图映射,定义在 component://webtools/widget/EntityScreens.xml#ProgramExport文件中;

Apache OFBiz 命令执行漏洞分析

获取到screen类型的视图处理器;

Apache OFBiz 命令执行漏洞分析

一直跟进,从EntityScreens.xml中获取到了ProgramExport对应的脚本文件位置component://webtools/groovyScripts/entity/ProgramExport.groovy,当遍历到此文件时跟进;

Apache OFBiz 命令执行漏洞分析

检测到文件后缀为.groovy,运行这个脚本文件;

Apache OFBiz 命令执行漏洞分析

进入ProgramExport.groovy,从传入的参数中获取到了groovyProgram参数值,最后调用evaluate()执行命令。

Apache OFBiz 命令执行漏洞分析

其中还调用了SecuredUpload.isValidText()groovyProgram进行黑白名单校验,黑名单内容来自frameworksecurityconfigsecurity.properties#deniedWebShellTokens,白名单就是import

Apache OFBiz 命令执行漏洞分析

3-4. 补丁分析

补丁地址:https://github.com/apache/ofbiz-framework/commit/ee02a33509

修复了授权检查的地方,在登录失败后直接返回error,而不是再去判断requirePasswordChange的值。

Apache OFBiz 命令执行漏洞分析


参考链接:

https://xz.aliyun.com/t/13168
https://xz.aliyun.com/t/8184/
https://xz.aliyun.com/t/13211
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/
https://mp.weixin.qq.com/s/iAvitO6otPdHSu1SjRNX3g
https://cwiki.apache.org/confluence/display/OFBIZ/Understanding+the+OFBiz+Widget+Toolkit


原文始发于微信公众号(中孚安全技术研究):Apache OFBiz 命令执行漏洞分析

版权声明:admin 发表于 2024年1月5日 下午6:10。
转载请注明:Apache OFBiz 命令执行漏洞分析 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...