原理
参考博客:博客
看博客分析就是出现了一个checkAutoType
函数,会判断autoTypeSupport
是否为true,由于autoTypeSupport
默认为false,需要通过黑白名单变为true
|
|
之前用的就是
com.sun.rowset.JdbcRowSetImpl
被ban了,没法用了
试了一下之前的payload会报错
autoTypeSupport
autoTypeSupport是checkAutoType()
函数出现后ParserConfig.java中新增的一个配置选项,在checkAutoType()
函数的某些代码逻辑起到开关的作用。
默认情况下autoTypeSupport为False,将其设置为True有两种方法:
- JVM启动参数:
-Dfastjson.parser.autoTypeSupport=true
- 代码中设置:
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
,如果有使用非全局ParserConfig则用另外调用setAutoTypeSupport(true);
AutoType白名单设置方法:
- JVM启动参数:
-Dfastjson.parser.autoTypeAccept=com.xx.a.,com.yy.
- 代码中设置:
ParserConfig.getGlobalInstance().addAccept("com.xx.a");
- 通过fastjson.properties文件配置。在1.2.25/1.2.26版本支持通过类路径的fastjson.properties文件来配置,配置方式如下:
fastjson.parser.autoTypeAccept=com.taobao.pac.client.sdk.dataobject.,com.cainiao.
绕过
1.2.25 - 1.2.41 补丁绕过
既然 sun 包里面的这个 JdbcRowSetImpl
类被 ban 了,尝试在 com.sun.rowset.JdbcRowSetImpl
前面加一个 L,结尾加上 ;
绕过
|
|
可以绕过
Lcom.sun.rowset.JdbcRowSetImpl;
这个本身是不存在的类
原理解析
在ParserConfig.checkAutoType
下断点,调试的时候会进入TypeUtils的loadClass方法
进入loadClass方法能看到绕过的核心
如果className是以L
开头,;
结尾的会截取掉开头结尾返回新的newClassName给loadClass
1.2.25-1.2.42 补丁绕过
上面的payload到了1.2.42就不行了
调试到这里的时候发现传入的Lcom.sun.rowset.JdbcRowSetImpl;
已经开头结尾已经被截取掉了
那payload继续双写
|
|
1.2.25-1.2.43 补丁绕过
payload
|
|
1.2.25-1.2.45补丁绕过
前提条件:需要目标服务端存在mybatis的jar包,且版本需为3.x.x系列<3.5.0的版本。
直接给出payload,要连LDAP或RMI都可以:
JSON
|
|
关键PoC:org.apache.ibatis.datasource.jndi.JndiDataSourceFactory
依赖
|
|
org.apache.ibatis.datasource.jndi.JndiDataSourceFactory
本身绕过黑名单,且setProperties
满足fastjson调用setter
data_source
可控
1.2.25-1.2.47补丁绕过
本次Fastjson反序列化漏洞也是基于checkAutoType()
函数绕过的,并且无需开启AutoTypeSupport,大大提高了成功利用的概率。
绕过的大体思路是通过 java.lang.Class,将JdbcRowSetImpl类加载到Map中缓存,从而绕过AutoType的检测。因此将payload分两次发送,第一次加载,第二次执行。默认情况下,只要遇到没有加载到缓存的类,checkAutoType()
就会抛出异常终止程序。
Demo如下,无需开启AutoTypeSupport,本地Fastjson用的是1.2.47版本:
EXP 如下
|
|
补丁分析
由于1.2.47这个洞能够在不开启AutoTypeSupport实现RCE,因此危害十分巨大,看看是怎样修的。1.2.48中的修复措施是,在loadClass()
时,将缓存开关默认置为False,所以默认是不能通过Class加载进缓存了。同时将Class类加入到了黑名单中。
调试分析,在调用TypeUtils.loadClass()时中,缓存开关cache默认设置为了False,对比下两个版本的就知道了。
Fastjson <= 1.2.61 通杀
Fastjson1.2.5 <= 1.2.59
需要开启AutoType
|
|
Fastjson1.2.5 <= 1.2.60
需要开启 autoType:
|
|
Fastjson1.2.5 <= 1.2.61
|
|