前言
最近公司内部提供了一份应用高危漏洞的清单,其中提到了fastjson和jackson,因为之前对fastjson因为多态问题引发的反序列化问题有过了解,所以打算也做一个简单的分析。
漏洞简述
2020年08月27日,360CERT监测发现 jackson-databind 发布了 jackson-databind 序列化漏洞 的风险通告,该漏洞编号为 CVE-2020-24616 ,漏洞等级:高危,漏洞评分:7.5。
br.com.anteros:Anteros-DBCP 中存在新的反序列化利用链,可以绕过 jackson-databind 黑名单限制,远程攻击者通过向使用该组件的web服务接口发送特制请求包,可以造成 远程代码执行 影响。
受影响的版本:fasterxml:jackson-databind
: <2.9.10.6,该版本还修复了下述利用链:
- org.arrahtec:profiler-core
- com.nqadmin.rowset:jdbcrowsetimpl
- com.pastdev.httpcomponents:configuration
上述 package 中存在新的反序列化利用链,可以绕过 jackson-databind
黑名单限制,远程攻击者通过向使用该组件的web服务接口发送特制请求包,可以造成 远程代码执行
影响。
漏洞分析
其实此漏洞和前几年jackson爆出来的另外一个漏洞(CVE-2017-7525)是一脉相承的,都是利用反序列化远程执行代码;至于为什么会出现这个问题,其实归根结底和多态有关,下面做一个简单的分析;
序列化中的多态问题
我们平时见得最多的json格式可能像下面这样:
{
"fruit":{
"name":"apple"},"mode":"online"}
里面是没有任何类信息的,拿到json字符串直接通过相关方法转化为对象:
public <T> T readValue(String content, Class<T> valueType)
像以上这种情况基本上是不会有什么问题的,但是很多业务中有多态的需求,比如像下面这样:
//水果接口类
public interface Fruit {
}
//通过指定的方式购买水果
public class Buy {
private String mode;
private Fruit fruit;
}
//具体的水果类--苹果
public class Apple implements Fruit {
private String name;
}
//具体的水果类--香蕉
public class Banana implements Fruit {
private String name;
}
可以发现这里的Buy对象里面存放的是Fruit,并不是具体的某种水果,如果这时候你去序列化:
Banana banana = new Banana();
banana.setName("banana");
Buy buy = new Buy("online", banana);
ObjectMapper mapper = new ObjectMapper();
// 序列化
String jsonString = mapper.writeValueAsString(buy);
System.out.println("toJSONString : " + jsonString);
// 反序列化
Buy newBuy = mapper.