通过t3协议识别weblogic版本

识别weblogic版本有什么用呢?

在检测weblogic漏洞之前,我们往往需要探测下weblogic版本。好判断是否在漏洞版本范围,同时也为我们构造EXP做准备(相同漏洞,可能因为weblogic版本不同需要的对应的EXP,比如CVE-2019-2725)

0x01 以前的方法

以前的方法是访问控制台登录页面,页面底部便有版本号!这里注意404页面的10.4.5并不是版本号。

http://...:7001/console/login/LoginForm.jsp

控制台登录页面

然而这个页面可能会被删除或禁止访问,那有没有其他方法呢?

0x02 通过t3协议识别

最近在学习t3协议时,使用wireshark抓包时发现,协议报文中带有weblogic的版本

使用t3协议10.3.6.0版本通信

使用t3协议12.1.3.0版本通信

所以只需要通过t3协议发送以下数据包,即可从返回包中获取Weblogic版本。

t3 10.3.6
AS: 255
HL: 19

这里需要注意,有时候发送数据包时,可能只会返回一个HELLO。这时候说明t3协议应该是开启的,需要多次提交探测包,才可能在某次中成功获取到。

下面使用脚本来完成我们的上面的想法。

#coding=utf-8
import sys
import socket
from socket import error as socket_error
import urllib

'''
'''

def t3conn(host, port):
        try:
            server_address = (host, port)
            #print 'INFO: Attempting Connection: ' + str(server_address)
            sock = socket.create_connection(server_address, 4)
            sock.settimeout(5)
            headers = 't3 10.3.6\nAS:255\nHL:19\n\n'
            sock.sendall(headers)
            data = ""

            try:
                data = sock.recv(1024)
            except socket.timeout:
                print 'ERROR: Socket Timeout Occurred: ' + str(host) + ':' + str(port) + '\n'

            sock.close()
            return data
        except socket_error:
            print 'ERROR: Connection Failed: ' + str(host) + ':' + str(port) + '\n'
            return ""


def parseURL(url):
    protocol, s1 = urllib.splittype(url)
    host, s2=  urllib.splithost(s1)
    host, port = urllib.splitport(host)

    if port == None and protocol == 'https':
        port = 443
    elif port == None and protocol == 'http':
        port = 80

    return protocol,host,port

def weblogic(url):
    for i in range(0, 10):
        protocol,host,port = parseURL(url)
        data = t3conn(host, port)
        if data.strip() == 'HELO':
            print 'INFO: Sever only returned HELO, retrying to get server version.'
            continue

        if data == "":
            break

        print data

        if 'HELO' in data:
            found_weblogic_version = data[5:13]

            print '[+] version: %s' % found_weblogic_version 
            #print '[+] result: %s' % data
            break

def poc(url):
    pass

if __name__ == '__main__':
    weblogic(sys.argv[1])

脚本探测结果

如果未探测到,以下几种可能情况:

  1. t3协议未启用
  2. 服务器做了负载均衡

0x03 遗留问题

有些weblogic站点用的https协议,得有t3s协议去探测,我虽然在代码中考虑到了。但是没未成功,一是没有现成的环境,二是没有实实在在使用过t3s协议。等等weblogic经验更丰富时,在解决!

0x04 后续

本来想学n1nty师傅对struts2框架的识别的思路,研究目标应用的底层代码,再构造特定的数据包来识别。无奈目前的知识和经验储备还无法支撑这个思路,等后面深入weblogic底层代码时,有发现再做尝试。