Fastjson系列五——高版本JDK绕过及检测与防御
/0x01 高版本JDK绕过
由之前利用的PoC知道,利用范围最广的PoC是基于com.sun.rowset.JdbcRowSetImpl的利用链的,而这种利用方式是基于JNDI注入漏洞的,是需要我们有RMI服务或LDAP服务。
这样就会导致一个限制的问题,即JNDI注入漏洞利用的限制问题——JDK版本。
由之前的分析知道,JDK对于JNDI注入漏洞在不同版本有着不同的防御措施:
- JDK 6u45、7u21之后:java.rmi.server.useCodebaseOnly的默认值被设置为true。当该值为true时,将禁用自动加载远程类文件,仅从CLASSPATH和当前JVM的java.rmi.server.codebase指定路径加载类文件。使用这个属性来防止客户端VM从其他Codebase地址上动态加载类,增加了RMI ClassLoader的安全性。
- JDK 6u141、7u131、8u121之后:增加了com.sun.jndi.rmi.object.trustURLCodebase选项,默认为false,禁止RMI和CORBA协议使用远程codebase的选项,因此RMI和CORBA在以上的JDK版本上已经无法触发该漏洞,但依然可以通过指定URI为LDAP协议来进行JNDI注入攻击。
- JDK 6u211、7u201、8u191之后:增加了com.sun.jndi.ldap.object.trustURLCodebase选项,默认为false,禁止LDAP协议使用远程codebase的选项,把LDAP协议的攻击途径也给禁了。
因此,相比之下,我们在Fastjson反序列化漏洞的基于com.sun.rowset.JdbcRowSetImpl的利用链上,更倾向于使用LDAP服务来实现攻击利用,因为其对于JDK的适用范围更广。
但是如果目标环境的JDK版本在6u211、7u201、8u191之后,我们是不是就没有办法绕过了呢?
当然是有的,KINGX大佬已经写:如何绕过高版本JDK的限制进行JNDI注入利用
主要是有两种方式:
- 利用本地Class作为Reference Factory
- 利用LDAP返回序列化数据,触发本地Gadget
具体可参考另一篇文章:浅析高低版JDK下的JNDI注入及绕过
0x02 检测方法
全局搜索是否使用到了Fastjson,若使用了则进一步排查是否为漏洞版本号即1.2.22-1.2.47,若是则可能存在反序列化漏洞的风险,需进一步排查。
全局搜索如下关键代码,若存在则进一步排查参数是否外部可控:
1 | import com.alibaba.fastjson.JSON; |
0x03 防御方法
升级到最新版的Fastjson。