当前位置: 首页 > news >正文

[Java安全】JDK 动态代理

文章目录

    • 动态代理的两个主要类
      • InvocationHandler:调用处理程序
      • Proxy : 代理
    • 代码示例
    • 动态代理在反序列化中的作用

动态代理的两个主要类

jdk的动态代理主要需要了解两个类

  • InvocationHandler 调用处理程序类
  • Proxy 代理类

InvocationHandler:调用处理程序

public interface InvocationHandler

InvocationHandler是由代理实例调用处理程序实现的接口

每一个代理实例都有一个调用处理程序

Object invoke(Object proxy, 方法 method, Object[] args)

当在代理实例上调用方法时,其实就会自动调用这个调用处理程序 invoke()

参数:

  • proxy : 代理实例对象
  • method: 当前被调用的方法对象,通过它可以获取方法名、参数类型等信息
  • args: 调用方法时传递的参数值

Proxy : 代理

public class Proxy extends Object implements Serializable

Proxy提供了创建动态代理类的和实例的静态方法,它也是由这个方法所创建的动态代理类的超类

动态代理类是一个实现 在类创建时 在运行时指定的接口列表的类

代理接口是由代理类实现的接口

代理实例是代理类的实例对象

public static Object newProxyInstance(ClassLoader loader,<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

返回指定接口的代理类的实例,该接口将 方法调用 分派给指定的 调用处理程序

参数

  • loader: 类加载器来定义代理类
  • interfaces: 代理类实现的接口列表
  • h : 调度方法调用的调用处理函数

代码示例

两个要点

  • 代理的是接口,而不是单个用户
  • 代理类是动态生成的,而不是静态写死的

首先定义接口类: UserService.java

package DynamicProxy;public interface UserService {public void add();public void del();public void update();public void query();
}

接口类的具体实现: UserServiceImpl.java

package DynamicProxy;public class UserServiceImpl implements UserService{@Overridepublic void add() {System.out.println("增加一个用户");}@Overridepublic void del() {System.out.println("删除一个用户");}@Overridepublic void update() {System.out.println("更新一个用户");}@Overridepublic void query() {System.out.println("查询一个用户");}
}

然后是动态代理的实现类: UserProxyInvocationHandler.java

package DynamicProxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class UserProxyInvocationHandler implements InvocationHandler {//要代理的接口private Object target;public UserProxyInvocationHandler() {}public UserProxyInvocationHandler(Object target) {this.target = target;}//动态生成代理类public Object getProxy() {Object proxy = Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);return proxy;}//处理代理类的实例对象@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {log(method.getName());Object obj = method.invoke(target, args);return obj;}//自定义需求public void log(String msg){System.out.println("【+】调用"+msg+"方法");}}

最后就是启动器 Client.java

package DynamicProxy;public class Client {public static void main(String[] args) {//真实角色UserService userService = new UserServiceImpl();//代理角色UserProxyInvocationHandler userProxyInvocationHandler = new UserProxyInvocationHandler(userService);//代理类(动态生成)UserService proxy = (UserService) userProxyInvocationHandler.getProxy();proxy.add();proxy.update();proxy.del();proxy.query();}
}

在这里插入图片描述

动态代理在反序列化中的作用

利用反序列化的漏洞,是需要一个入口类的

先假设存在一个能够漏洞利用的类为 B.f,比如 Runtime.exec 这种。
我们将入口类定义为 A,我们最理想的情况是 A[O] -> O.f,那么我们将传进去的参数 O 替换为 B 即可。但是这种情况是很少见的,不会这么简单。

那么如果入口类 A 存在 O.abc 这个方法,也就是 A[O] -> O.abc;而 O 呢,如果是一个动态代理类,Oinvoke 方法里存在 .f 的方法,便可以漏洞利用了

动态代理对象调用方法时,其所有的方法调用都会自动路由到InvocationHandler.invoke()里面去,也就是前面比如调用 proay.add()它会路由到UserProxyInvocationHandler.invoke方法里面去,从而多调用了一个log()方法,也就是打印调用了哪个函数

A[O] -> O.abc
O[O2] invoke -> O2.f // 此时将 B 去替换 O2
最后  ---->
O[B] invoke -> B.f // 达到漏洞利用效果

参考

https://drun1baby.top/2022/06/01/Java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E5%9F%BA%E7%A1%80%E7%AF%87-04-JDK%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/
https://www.bilibili.com/video/BV1mc411h719?p=9
https://www.bilibili.com/video/BV16h411z7o9/?p=3&vd_source=cf7d01598010e70f1da4b79252417e78
http://www.dtcms.com/a/283388.html

相关文章:

  • 3D TOF 安全防护传感器
  • 低精度定时器 (timer_list) 和 高精度定时器 (hrtimer)
  • 切比雪夫距离
  • Python高级编程技巧探讨:装饰器、Patch与语法糖详解
  • 二叉树思想草稿
  • 关于SaaS业务模式及其系统架构构建的详细解析
  • RICE-YOLO:基于改进YOLOv5的无人机稻穗检测新方法
  • 【C语言网络编程】HTTP 客户端请求(发送请求报文过程)
  • 在UE中如何操作视图的大小,方位,移动
  • 16路串口光纤通信FPGA项目实现指南 - 第二部分(上)
  • 【LeetCode刷题指南特别篇】--移除链表元素,调试技巧,链表分割
  • pyJianYingDraft 在 import_srt 字幕添加花字效果
  • 鸿蒙系统账号与签名内容整理
  • CG--资料分析1
  • 重载操作类型
  • 向量数据库Faiss vs Qdrant全面对比
  • ESP32——快速入门
  • 【深度学习】学习算法中为什么要使用“小批量随机”
  • 前后端分离项目中的接口设计与调用流程——以高仙机器人集成为例
  • CSS动画与变换全解析:从原理到性能优化的深度指南
  • JAVA同城自助羽毛球馆线上预约系统源码支持微信公众号+微信小程序+H5+APP
  • HugeGraph 【图数据库】JAVA调用SDK
  • 助力品牌从系统碎片化走向IT一体化建设,实现全渠道业务协同!——商派“数智化IT轻咨询”
  • MH32F103A单片机 可兼容替代STMCCT6/RCT6/RBT6,增强型
  • Kotlin重写函数中的命名参数
  • 【论文阅读】A Survey on Knowledge-Oriented Retrieval-Augmented Generation(4)
  • 【Android】CheckBox实现和监听
  • 归一化与激活函数:深度学习的双引擎
  • CentOS网络配置与LAMP环境搭建指南
  • Product Hunt 每日热榜 | 2025-07-16