挖矿确实太火,现在只要存在RCE漏洞就会有矿机的身影,这不weblogic又火了一把。这次矿机使用的PoC是wls wsat模块的RCE漏洞,这个漏洞的核心就是XMLDecoder的反序列化漏洞,关于XMLDecoder反序列化的漏洞在2013年就被广泛传播,这次的漏洞是由于官方修复不完善导致被绕过。
1 补丁分析
首先来看下weblogic的历史补丁,四月份补丁通告:
http://www.oracle.com/technetwork/security-advisory/cpuapr2017-3236618.html
这里面主要关注CVE-2017-3506,这是web service模块的漏洞。
10月份补丁通告:
https://www.oracle.com/technetwork/topics/security/cpuoct2017-3236626.html
主要关注CVE-2017-10271,是WLS Security组建的漏洞,英文描述如下:
A remote user can exploit a flaw in the Oracle WebLogic Server WLS Security component to gain elevated privileges [CVE-2017-10271].这是CVE-2017-10271的描述信息。
测试的poc如下:
对于poc中uri中/wls-wsat/CoordinatorPortType
可以换成CoordinatorPortType11等wsat 这个webservice服务中存在的其他uri
执行的效果图如下:
跟踪到底这还是XMLDecoder的漏洞,下面来分析补丁代码:首先来看3506的补丁的分析,在文件weblogic/wsee/workarea/WorkContextXmlInputAdapter.java中,
添加了validate方法,方法的实现如下:
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 var5) { throw new IllegalStateException("Parser Exception", var5); } catch (SAXException var6) { throw new IllegalStateException("Parser Exception", var6); } catch (IOException var7) { throw new IllegalStateException("Parser Exception", var7); } }
简单来说就是在解析xml的过程中,如果Element字段值为Object就抛出异常,这简直太脑残了,所以马上就有了CVE-2017-10271。我前段时间分析Oracle Weblogic十月份的补丁的时候看到WorkContextXmlInputAdapter 相关代码时只关注了这块dos的漏洞,没看到10271添加的对new,method,void的去除,还想当然的以为自己找到0day了呢。因为可以通过其他方式绕过,比如典型的就是将object改为void,这是挖矿的人采用的poc,我也想到了,当然也还可以通过new关键字来创建反序列化执行的poc,下面简单示例一下通过new关键字来执行命令:
至于为什么XMLDecoder在解析的过程中能执行代码呢,大家可以以如下测试用例进行测试:
是不是觉得变种太多,写法太灵活了,比XStream远程执行代码的要求还低。根据如上poc首先生成JdbcRowSetImpl的实例,接着调用该实例的set方法来初始化该实例的属性,当调用完setAutoCommit接口的时候就会根据dataSourceName的值去远程加载一个类初始化。
针对上面的PoC,官方放出了10271的补丁,补丁如下:
private void validate(InputStream is) { WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory(); try { SAXParser parser = factory.newSAXParser(); parser.parse(is, new DefaultHandler() { private int overallarraylength = 0; public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if(qName.equalsIgnoreCase("object")) { throw new IllegalStateException("Invalid element qName:object"); } else if(qName.equalsIgnoreCase("new")) { throw new IllegalStateException("Invalid element qName:new"); } else if(qName.equalsIgnoreCase("method")) { throw new IllegalStateException("Invalid element qName:method"); } else { if(qName.equalsIgnoreCase("void")) { for(int attClass = 0; attClass < attributes.getLength(); ++attClass) { if(!"index".equalsIgnoreCase(attributes.getQName(attClass))) { throw new IllegalStateException("Invalid attribute for element void:" + attributes.getQName(attClass)); } } } if(qName.equalsIgnoreCase("array")) { String var9 = attributes.getValue("class"); if(var9 != null && !var9.equalsIgnoreCase("byte")) { throw new IllegalStateException("The value of class attribute is not valid for array element."); }
这个补丁限定了object,new,method,void,array等字段,就限定了不能生成java 实例。如下的测试用例就不可执行:
2 动态调试
为了更好的理解这个漏洞,我们通过本地的weblogic动态调试一番,PoC还是前面提到的,具体的调用栈如下:
调用栈非常深,我们简单解释一下关键的几个部位,首先是WorkContextServerTube.java中processRequest方法,主要功能就是分割整个xml,抽取真正执行的xml交给readHeadOld方法。
在上述代码中ByteArrayOutputStream var4会被填充为PoC实际执行部分代码即:
接着这部分xml会被传递到XMLDecoder的readObject方法中从而导致反序列化远程代码执行。
总之,尽快打上Weblogic 10月份的补丁。
文章转载自xxlegend.com