Jackson-databind SSRF浅析

  • A+
所属分类:安全文章

影响范围

  • jackson-databind before 2.9.10.3
  • jackson-databind before 2.10.2

利用条件

开启enableDefaultTyping()

漏洞概述

漏洞类javax.swing.JEditorPane来源于JDK不需要依赖任何jar包,该类在jackson-databind进行反序列化时可造成SSRF

漏洞复现

环境搭建

pom.xml文件如下:

<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.10.3</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.transaction/jta -->
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
</dependencies>

漏洞利用

Poc.java代码如下所示

package com.jacksonTest;

import com.fasterxml.jackson.databind.ObjectMapper;


import java.io.IOException;

public class Poc {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
String payload = "["javax.swing.JEditorPane",{"page":"http://qb7fky.dnslog.cn"}]";
try {
mapper.readValue(payload, Object.class);
} catch (IOException e) {
e.printStackTrace();
}
}
}

之后在DNSlog端成功收到请求:
Jackson-databind SSRF浅析

漏洞分析

首先定位到javax.swing.JEditorPane类的setPage方法,之后在此处下断点进行断点调试分析:
Jackson-databind SSRF浅析
在setPage方法中会首先去判断传入的page是否为空,如果为空则抛出异常信息,不为空则初始化一个page上下文环境(矩形:长高各为1,从(0,0)开始,类似于一个新建的word文档):
Jackson-databind SSRF浅析
之后设置reloaded为false,并根据之前返回的loaded是否为空等组合判断语句来决定是否进入if语句中,而loaded源自getPage(),getPage为空所以此时的loaded为null,即满足if条件的第一项,由于是采用的或关系条件判断语句,所以直接进入if语句中执行后续代码:
Jackson-databind SSRF浅析
之后通过函数getAsynchronousLoadPriority来判断document的加载优先级并将其赋值给p变量,从下述代码中可以看出如果不支持则返回“-1”:
Jackson-databind SSRF浅析
Jackson-databind SSRF浅析
之后判断p的值是否小于0,如果小于0,则进入if语句中,此时的p返回值为—“-1”,之后进入if语句中,之后page(我们构造DNSlog域名)会作为参数传递进入getStream中,我们继续跟进去:
Jackson-databind SSRF浅析
之后可以看到在在getStream中调用page.openConnection()从而得到一个HttpURLConnection对象实例:
Jackson-databind SSRF浅析
之后判断新建的conn是否是一个HttpURLConnection对象的实例:
Jackson-databind SSRF浅析
之后新建HttpURLConnection实例对象,并将conn赋值给hconn,之后设置是否跟随重定向,以及postData,然而此时的postData并没有任何数据信息,所以会直接跳过if语句:
Jackson-databind SSRF浅析
之后继续跟进getResponseCode获取响应值的函数中:
Jackson-databind SSRF浅析
之后调用getInputStream(),并确保我们已经连接到服务器,如果没有status信息,则抛出异常,下面我们继续跟进到getInputStream()函数中:
Jackson-databind SSRF浅析
可以看到,截止目前为止我们还未连接到目标服务器,connecting为false,而接下来要做的就是连接目标服务器,也就是我们传递进去的DNSlog域名地址,我们继续跟进分析:
Jackson-databind SSRF浅析
之后connecting被设置为"true",并检查URL的Socket通信是否允许,之后调用getInputStream0()函数:
Jackson-databind SSRF浅析
在getInputStream0()函数中首先判断此时的doInput是否为false,如果此时的doInput为false则无法使用URL连接进行输入,也无法判断是否成功连接,故而会抛出异常,此时doInput为true,之后进入到else判断语句中,而此时的rememberException为null,所以也不会进入后续的else中,直接继续往下执行:
Jackson-databind SSRF浅析
streaming为false,继续跳过if中的语句,往下执行:
Jackson-databind SSRF浅析
之后一路往下跟踪,最后调用this.connect()来建立连接:
Jackson-databind SSRF浅析
之后调用this.plainConnect()方法
Jackson-databind SSRF浅析
之后再去调用plainConnect0():
Jackson-databind SSRF浅析
之后跟进到this.getNewHttpClient(this.url, var4, this.connectTimeout);处,下面继续跟进去
Jackson-databind SSRF浅析
Jackson-databind SSRF浅析
Jackson-databind SSRF浅析
之后调用get方法,并设置keep-alive:
Jackson-databind SSRF浅析
....
之后来到HttpClient()处,继续跟进:
Jackson-databind SSRF浅析
设置请求参数(host、port、proxy、keeepAliveConnection、KeepAliveTimeout等等)
Jackson-databind SSRF浅析
之后调用openServer()开启连接:
Jackson-databind SSRF浅析
之后检查协议等信息,并调用openServer(host,port)来建立连接,下面继续跟进:
Jackson-databind SSRF浅析
之后再次调用doConnect():
Jackson-databind SSRF浅析
之后调用InetSocketAddress()函数:
Jackson-databind SSRF浅析
之后调用InetAddress.getByName(),这个函数想必大家已经都很熟悉了,该函数在给定的主机名的情况下来获取主机的IP地址,这也是触发SSRF的根本所在点:
Jackson-databind SSRF浅析
Jackson-databind SSRF浅析
Jackson-databind SSRF浅析
Jackson-databind SSRF浅析
同时在DNSLog端也接收到请求:
Jackson-databind SSRF浅析
整个跟踪流程相对来说转接很多,涉及多个文件,有兴趣的小伙伴可以尝试跟踪分析一波看看~

补丁分析

官方在github的更新方式依旧是添加javax.swing.JEditorPane至黑名单类,但这种方式治标不治本,后续可能出现其他绕过黑名:
https://github.com/FasterXML/jackson-databind/commit/4d038c9de0aa80a5dae27f552a975cb39cc42b60
Jackson-databind SSRF浅析

修复建议

及时将jackson-databind升级到安全版本
升级到较高版本的JDK。

参考链接

https://github.com/FasterXML/jackson-databind/issues/2642
https://github.com/FasterXML/jackson-databind/commit/4d038c9de0aa80a5dae27f552a975cb39cc42b60

本文来源于互联网

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: