FastJson反序列化

概述

Fastjson允许用户在输入JSON串时通过“@type”键对应的value指定任意反序列化类名。Fastjson自定义的反序列化机制时会自动调用指定类中的setter方法及部分getter方法,那么当组件开启了autotype功能并且反序列化不可信数据时,攻击者可以构造数据,使目标应用的代码执行流程进入特定类的特定setter或者getter方法中,若指定类的指定方法中有可被恶意利用的逻辑(也就是通常所指的“Gadget”),则会造成一些严重的安全问题。并且在Fastjson 1.2.47及以下版本中,利用其缓存机制可实现对未开启autotype功能的绕过。

原理

反序列化的利用本质:
找到一条有效的攻击链,攻击链的末端就是有代码执行能力的类,来达到我们想做的事情,一般都是用来RCE(远程命令执行)。
构造一个触发器,也就是通过什么方式来让攻击链执行你想要的代码。触发器可以通过很多方式,比如静态代码块、构造方法等等。

这个时候我们可以考虑指定某些类,来远程调用一些恶意的类来实现RCE
这个时候可以考虑JNDI注入,JDNI是有sun提出的一个规范,全称是“命名和目录提供程序”(Naming and Directory Providers),用来解耦应用,让整个程序更便于扩展、部署以及应用。
JDNI底层可以驱动一系列的远程对象,例如RMI、LDAP等等,
如RMI(Remote Method Invocation)远程方法调用,是专为Java环境设计的远程方法调用机制,远程服务器实现具体的Java方法并提供接口,客户端本地仅需根据接口类的定义,提供相应的参数即可调用远程方法。
1、运行了RMI的一端可以被称为“RMIServer”,用来提供可被远程调用的方法,这个过程称为“注册”,
     然后通过http服务并把已经编译好的serialize.Exploit.class放到响应的目录供客户端获取。
这里就体现了RMI的核心,RMI核心特点之一就是动态类加载,如果当前JVM中没有某个类的定义,它可以从远程URL去下载这个类的class。
2、客户端通过lookup()方法请求服务端,根据RMI请求返回的结果来再次通过http获取所需的factory类并进行实例化


小结一下就是,如果要成功利用这个lookup()来做一些事,就必须要以下条件:
1、lookup()的参数是我们能控制的;
2、远程URL是我们能控制的;


接下来就是找到一条利用链
JdbcRowSetImpl的利用链
1、找到JdbcRowSetImpl中调用了lookup()方法的函数;
在com.sun.rowset.JdbcRowSetImpl.class中的connect()中调用了looup(),并且looup的参数是通过getDataSourceName()方法获取到的,这一点很关键,需要确认这个get的结果是否是我们可控的。
1.1、确认getDataSourceName()方法的传值;
javadoc里面写明了DataSource是通过setDataSourceName来设置的,也就是dataSource属性的set和get方法;
2、找到调用connect()方法的函数;
可通过setAutoCommit()方法用来设置autoCommit属性的值,传值是一个boolean。只要能设置autoCommit就能调用set方法,而setAutoCommit()方法里面又调用了connect(),connent里面就有我们需要的lookup()。


总结
1、驱动JdbcRowSetImpl库;
2、通过设置dataSourceName属性传参给lookup()方法;
3、通过设置autoCommit属性来触发执行最终的lookup()方法。
按照上面的例子,就可以构造出

你可能感兴趣的:(安全)