WebLogic | CVE-2019-2725反序列化漏洞分析
近日,Oracle公司发布了安全警报(Oracle Security Alert Advisory - CVE-2019-2725),修复了此前国家信息安全漏洞共享平台披露的WebLogic反序列化远程代码执行漏洞(CNVD-C-2019-48814)。由于补丁发布已经有一段时间,我们将对该漏洞进行详细分析。注意本文内容仅用于学习与研究,请勿非法利用。
漏洞介绍
漏洞编号
CNVD-C-2019-48814
CVE-2019-2725
漏洞描述
漏洞位于Weblogic内置的“wls9_async_response”组件与“wls-wsat”组件。漏洞产生的根本原因是CVE-2017-10271的补丁可被绕过,导致允许攻击者构造恶意SOAP消息内容进行XMLDecoder反序列化。由于互联网上关于CVE-2017-10271漏洞的分析文章已经非常丰富,所以我们此次主要针对wls9_async_response组件进行漏洞分析。
影响范围
WebLogic Server 10.3.6.0.0
WebLogic Server 12.1.3.0.0
漏洞分析
调用链
我们可以简单请求下接口使其产生空异常,因此通过报错信息来跟踪调用过程。所示函数的调用顺序从下到上:
经过反复调试,重点关注的函数如下。所列函数的调用顺序从上到下:
weblogic.wsee.server.servlet.SoapProcessor.process()
weblogic.wsee.server.servlet.SoapProcessor.handlePost()
weblogic.wsee.ws.WsSkel.invoke()
weblogic.wsee.ws.dispatch.server.ServerDispatcher.dispatch()
weblogic.wsee.handler.HandlerIterator.handleRequest()
weblogic.wsee.addressing.ServerAddressingHandler.handleRequest()
weblogic.wsee.async.AsyncResponseHandler.handleRequest()
weblogic.wsee.ws.dispatch.server.OperationLookupHandler.handleRequest()
weblogic.wsee.workarea.WorkAreaServerHandler.handleRequest()
weblogic.workarea.WorkContextMapImpl.receiveRequest()
weblogic.workarea.WorkContextLocalMap.receiveRequest()
weblogic.workarea.spi.WorkContextEntryImpl.readEntry()
weblogic.wsee.workarea.WorkContextXmlInputAdapter.readUTF()
调用过程
1、我们直接看到SoapProcessor的process函数,判断请求为POST后将请求内容传入handlePost函数处理,handlePost函数中获取WsPort等内容后传入关键函数invoke():
2、invoke函数中实例化ServerDispatcher对象后调用关键函数dispatch():
3、dispatch函数中从WsPort中获取InternalHandlerList进行setHandlerChain操作,后再调用getHandlerChain.handleRequest():
4、getHandlerChain函数返回对象为HandlerIterator,因此进入HandlerIterator.handleRequest()。handleRequest函数根据handlers列表依次调用每个handler的handleRequest()。但只要某个handler的handleRequest()返回false则直接return,后面handler的handleRequest()将不再被调用。
5、我们可以看到迭代器中的handlers列表,共21个,其中需关键控制的有4个。控制的重点在于:执行到WorkAreaServerHandler.handleRequest()之前,前面任意handler的handleRequest()均不返回false。
6、首先ServerAddressingHandler.handleRequest()中,我们先重点关注这俩函数:
7、其中setWSAVersion()中获取请求中Message的ActionHeader,根据ActionHeader中namespaceURI的不同进行不同的处理,处理结果区别在于“weblogic.wsee.addressing.version”属性的值是否被设置。
8、而接下来validateWSAVersion函数中判断“weblogic.wsee.addressing.version”属性若为空,则设置为WSAVersion.WSA10。
9、那么“weblogic.wsee.addressing.version”属性的不同会有什么影响呢?回到handleRequest()往下看,主要影响var24的值,其中等于WSAVersion.WSA10时var24为true。
10、继续往下看handleRequest(),判断MsgHeader中的ActionHeader、RelatesToHeader存在则对相应属性进行赋值。同时使var23、var28为true,而var23、var28跟var24直接影响是否抛出异常,抛出异常则函数无法往下进行,本次请求中断。
11、下面来到AsyncResponseHandler的handleRequest(),关键部分判断了Message的weblogic.wsee.addressing.RelatesTo属性值为空则返回false。一旦返回false后面的handler的handleRequest()将不再被调用。该属性在上图中进行赋值。
12、接着来到OperationLookupHandler的handleRequest(),判断Message内容中是否存在OperationName,不存在则抛出异常,抛出异常则函数无法往下进行,本次请求中断。
13、然后调用WorkAreaServerHandler的handleRequest(),把Header的WorkAreaHeader部分传入WorkContextXmlInputAdapter()进行实例化,然后调用receiveRequest处理。
14、最后执行到WorkContextXmlInputAdapter.readUTF()进行反序列化。
漏洞复现
根据上述分析内容尝试构造Poc,暂不考虑绕过补丁部分,如何能成功执行到WorkAreaServerHandler漏洞触发的关键。
我们先来认识SOAP消息的基本结构:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
</soapenv:Header>
<soapenv:Body>
</soapenv:Body>
</soapenv:Envelope>
分析过程发现关键内容主要在Header部分,根据上述分析过程7、8、9、10、11处,我们知道SOAP消息的Header部分的ActionHeader、RelatesToHeader需存在,且ActionHeader中的namespaceURI需为“http://www.w3.org/2005/08/addressing”。
另外分析过程的12也说明了要求SOAP消息中需存在operationName,operationName在AsyncResponseService.wsdl中可查得,存在于SOAP消息的Header或Body均可。
最后根据分析过程13知WorkAreaHeader内容为反序列化部分。
因此Poc构造如下:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:asy="http://www.bea.com/async/AsyncResponseService">
<soapenv:Header>
<wsa:Action/>
<wsa:RelatesTo/>
<asy:onAsyncDelivery/>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
xxx
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
大致构造完成后,接下来就要考虑如何绕过CVE-2017-10271补丁的问题了。
首先看CVE-2017-10271补丁,限制了object、new、method元素以及void、array元素的属性:
但在“JavaBeans组件的长期持久性:XML模式”文档中发现,class元素可代替object元素来生成对象,且class元素未在补丁中限制。
由于method元素、void属性被限制,不能指定方法。但是我们可以尝试寻找可利用的构造函数,重点关注构造函数中存在可控的文件读写操作、存在使用可控内容进行反序化操作、存在可控的执命令的操作的类。
如WebLogic10.3.6中存在UnitOfWorkChangeSet类,其构造函数中使用传入的字节数组进行反序列化操作。
借助该类可成功触发JAVA反序列化远程命令执行漏洞。
Oracle官方已在2019年4月26日发布紧急补丁,补丁显示在黑名单中添加了class元素。
修复建议
1、及时安装官方发布的紧急补丁。
2、通过访问策略禁止对/_async/*及/wls-wsat/*路径的访问。
3、若明确不使用wls9_async_response.war与wls-wsat.war,建议删除并重启。
参考链接
https://www.oracle.com/technetwork/security-advisory/alert-cve-2019-2725-5466295.html
https://www.oracle.com/technetwork/java/persistence3-139471.html
http://www.cnvd.org.cn/webinfo/show/4999