前言
weblogic 的反序列化漏洞分为两种 ,一种是基于T3 协议的反序列化漏洞,一个是基于XML的反序列化漏洞,这篇来分析一下基于T3 协议的反序列化漏洞,本文参考了很多师傅的文章,我会贴在最后面。
环境搭建:
[JAVA安全]weblogic反序列化介绍及环境搭建_snowlyzz的博客-CSDN博客
https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar
mirrors / angelwhu / ysoserial · GitCode
T3协议
RMI 通信时会将数据进行序列化后传输,同样的接收数据后反序列化进行接收,正常RMI通信使用的是JRMP协议,而在Weblogic的RMI通信中使用的是T3协议,T3是weblogic独有的一个协议,相比于JRMP多了如下协议:
- 服务端可以持续追踪监控客户端是否存活(心跳机制),通常心跳的间隔为60秒,服务端在超过240秒未收到心跳即判定与客户端的连接丢失。
- 通过建立一次连接可以将全部数据包传输完成,优化了数据包大小和网络消耗。
结构
主要包含请求头和请求主体这两部分,总共分为七个部分,第一部分是协议头,也就是请求包头,后面2-7都是请求主题(这图叠buff了):
从流量到对象:
借用师傅的一张图
weblogic 通过7001端口,获取到流量钟的T3协议的反序列化数据,他会从图钟的readObject开始,经过一系列的操作,终于在上图的流程终点的 resolveProxyclass 或者是 resolveClass 处将流量钟的代理类 / 类类型的字节转变为了对应的class对象。
在ObjcetInputStream 钟的readClassDesc 方法,存在两个路径,也就是分叉点,导致了序列化的流量流向了两个不同的分支,其中一些流量流向了readProxyDesc 并最终采用resolveProxyClass获取类对象,而另一些则流向了readNonProxyDesc并最终使用resolveClass获取类对象。
readClassDesc
看名字就知道,desc是描述,readClassDesc的功能很简单,读入字节流,通过读取字节流钟的描述符来确定字节流钟传递的数据类型,并交给对应的方法处理。
看下readClassDesc的实现:
private ObjectStreamClass readClassDesc(boolean unshared)
throws IOException
{
byte tc = bin.peekByte();
switch (tc) {
case TC_NULL:
return (ObjectStreamClass) readNull();
case TC_REFERENCE:
return (ObjectStreamClass) readHandle(unshared);
case TC_PROXYCLASSDESC:
return readProxyDesc(unshared);
case TC_CLASSDESC:
return readNonProxyDesc(unshared);
default:
throw new StreamCorruptedException(
String.format("invalid type code: %02X", tc));
}
}
从 readClassDesc 方法 的实现可见,readClassDesc 钟switch 语句中有5个分支 :
TC_NULL描述符表示空对象引用 TC_REFERENCE描述符表示引用已写入流的对象 TC_PROXYCLASSDESC是新的代理类描述符 TC_CLASSDESC是新的类描述符
TC_PROXYCLASSDESC 与 TC_CLASSDESC描述符 标识了流量中代理类与类这两种类型的数据,因此我们重点关注TC_PROXYCLASSDESC 与 TC_CLASSDESC 这两个分支,也是上文流程图里只有这两处分支的原因,
当readClassDesc从字节流中读取到TC_CLAS