最早我们看到黑产利用该漏洞(CVE-2017-3506)进行批量挖矿,后续又发现利用该漏洞的绕过去批量扫描攻击。我们先来看一下这次使用漏洞的成因是什么,依据捕获到的攻击数据包可知利用的是一个web service的服务,为了分析方便,我直接使用简单的PoC。
漏洞编号:CVE-2017-3506
调试环境:win7 x64+Idea
jdk版本:java 1.8.0_131
WebLogic版本:10.3.6.0(无补丁)
POST /wls-wsat/CoordinatorPortType HTTP/1.1 Host: localhost:7001 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:57.0) Gecko/20100101 Firefox/57.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;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 Accept-Encoding: gzip, deflate Cookie: wp-settings-time-1=1506773666 Connection: close Upgrade-Insecure-Requests: 1 Content-Type: text/xml Content-Length: 407 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"> <java version="1.8.0_131" class="java.beans.XMLDecoder"> ... ... ... </java> </work:WorkContext> </soapenv:Header> <soapenv:Body/> </soapenv:Envelope>
直接入口点是wls-wsat.war这个war提供的web service服务,然后通过WLSServletAdapter进行处理,在WorkContextServerTube类中进行处理POST数据包中的XML数据。
大体函数调用图,如下
这里我们分析数据解析的过程WorkContextServerTube类的processRequest函数。
public NextAction processRequest(Packet var1) { this.isUseOldFormat = false; if (var1.getMessage() != null) { HeaderList var2 = var1.getMessage().getHeaders(); Header var3 = var2.get(WorkAreaConstants.WORK_AREA_HEADER, true); if (var3 != null) { this.readHeaderOld(var3); this.isUseOldFormat = true; } Header var4 = var2.get(this.JAX_WS_WORK_AREA_HEADER, true); if (var4 != null) { this.readHeader(var4); } } return super.processRequest(var1); }
var3这个对象获取了和</work:WorkContext>相关的内容。然后执行readHeaderOld这个方法。我们来跟进一下。
protected void readHeaderOld(Header var1) { try { XMLStreamReader var2 = var1.readHeader(); var2.nextTag(); var2.nextTag(); XMLStreamReaderToXMLStreamWriter var3 = new XMLStreamReaderToXMLStreamWriter(); ByteArrayOutputStream var4 = new ByteArrayOutputStream(); XMLStreamWriter var5 = XMLStreamWriterFactory.create(var4); var3.bridge(var2, var5); var5.close(); WorkContextXmlInputAdapter var6 = new WorkContextXmlInputAdapter(new ByteArrayInputStream(var4.toByteArray())); this.receive(var6); } catch (XMLStreamException var7) { throw new WebServiceException(var7); } catch (IOException var8) { throw new WebServiceException(var8); } }
这里var4存储了java对象XML序列化后的数据。这里执行WorkContextXmlInputAdapter的构造函数,触发反序列化过程。
public final class WorkContextXmlInputAdapter implements WorkContextInput { private final XMLDecoder xmlDecoder; public WorkContextXmlInputAdapter(InputStream var1) { this.xmlDecoder = new XMLDecoder(var1); } ... }
四月份发布的补丁简要说明
public WorkContextXmlInputAdapter(InputStream is) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { int next = 0; next = is.read(); while (next != -1) { baos.write(next); next = is.read(); } } catch (Exception e) { throw new IllegalStateException("Failed to get data from input stream", e); } validate(new ByteArrayInputStream(baos.toByteArray())); this.xmlDecoder = new XMLDecoder(new ByteArrayInputStream(baos.toByteArray())); } private void validate(InputStream is) { WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory(); try { SAXParser parser = factory.newSAXParser(); parser.parse(is, new DefaultHandler() { public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("object")) { throw new IllegalStateException("Invalid context type: object"); } } }); } catch (ParserConfigurationException e) { throw new IllegalStateException("Parser Exception", e); } catch (SAXException e) { throw new IllegalStateException("Parser Exception", e); } catch (IOException e) { throw new IllegalStateException("Parser Exception", e); } }
只是在反序列化之前增加了一个validate函数,如果qName等于object,就抛出异常终止。可谓简单暴力,然而,这里的黑名单这种修复,很难彻底修复完整。值得深思…
因为,Oracle官方四月份补丁对该漏洞修复不彻底,可以绕过补丁,依旧执行远程命令。目前绕过的漏洞在官方发布的十月份的补丁中已修复。
1.可以触发漏洞的url为wls-wsat.war xml中所有url-pattern
2.关于XmlDecoder安全性及利用请参看http://blog.diniscruz.com/2013/08/using-xmldecoder-to-execute-server-side.html
3.请大家尽快登录Oracle官方网站,下载WebLogic十月份补丁并安装。
本文作者360攻防实验室 由安全客原创发布 如若转载,请注明出处: https://www.anquanke.com/post/id/92003
本文作者:360攻防实验室
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/66572.html
感谢楼主分享。
不过本人使用了对应的POC,而且目标也确实存在问题,但是一直没有复现,是否可以帮忙解答一下。
按照POC尝试后,发现右侧出现的是415,换了多个POC效果一样,请大神帮忙,谢谢![img=uploads/comments/2018/03/12/20180312073628_208.jpg][img=uploads/comments/2018/03/12/20180312073628_660.jpg][img=uploads/comments/2018/03/12/20180312073629_351.jpg]
@Blue 遇到过类似情况 主要原因应该是POC黏贴复制不规范导致的,可参考POC:https://www.secpulse.com/archives/66576.html 贴到burp的repeater的时候会要求主动填写host和port,然后就ok。
@secpulse 谢谢你的回复。试了你说的方法和POC,依然不好使[em_5],能不能帮忙再看下,谢谢。
本人尝试的内容包括:
1.直接粘贴POC到Burp的Repeater中,点击Go,按提示填写目标的IP和port,连接不上,失败
2.尝试修改POC中的HOST,X-forward的值,继续尝试,提示404,
3.继续第2步的报错检查到直接访问POC中的http://……?wsdl没有对应的服务,所以猜测报404,依据其他网站的帖子尝试直接干掉?wsdl,
是可以响应了,但是是响应值200,响应正常。
哎。。。
还是不行,
@Blue 我也有尝试先Proxy截取包,然后发到Repeater,然后在把POC中的XML部分粘贴到Repeater中拼接后再访问,但是还是不行。
已确定目标系统存在这个漏洞。
@Blue 可以私信测试地址到 hi@secpulse.com 协助你调试一下。