首页 > 编程语言 >Java安全-反射

Java安全-反射

时间:2024-10-22 21:21:27浏览次数:3  
标签:反射 forName Java 安全 获取 实例 obj Class

反射


反射是一种强大的机制,它允许程序在运行时访问、检查和修改它自己的结构,比如类、接口、字段(属性)和方法。反射提供了一种动态性,使得Java程序可以在运行时处理对象和类。所以说通过反射,我们可以使java这类静态语言附上动态的特征。

几个反射中重要的方法:

获取类的⽅法: forName
实例化类对象的⽅法: newInstance
获取函数的⽅法: getMethod
执⾏函数的⽅法: invoke

这⼏个⽅法基本上包揽了Java安全⾥各种和反射有关的Payload。

获取类名方法:

obj.class //直接通过类名获取,已加载某个类
obj.getClass() //通过实例对象获取,存在某个类的实例obj
obj.forName() //通过类名的字符串形式获取,知道类名,获取类

forName重载形式:

  1. Class.forName(String className)
    这是最基本的重载形式,它接受一个类名的字符串作为参数,并返回对应的 Class 对象。

    Class<?> clazz = Class.forName("java.lang.String");
    
  2. Class.forName(String className, boolean initialize, ClassLoader loader)
    这个重载形式允许你指定是否要初始化类(即调用类的静态初始化块和静态变量赋值),以及使用哪个类加载器来加载类。

    initialize 参数为true时,类会被初始化;为false时,类不会被初始化,这在Java 9及以后的版本中被称为“未链接”状态。

    loader 参数指定了用于加载类的 ClassLoader 实例。如果为 null,则使用调用者的类加载器。

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    Class<?> clazz = Class.forName("java.lang.String", true, classLoader);
    

    在Java中,当你使用Class.forName()方法加载类时,无论initialize参数是true还是false,JVM都会执行类的静态初始化块(即static块)。这是因为Class.forName()方法的目的就是加载并初始化类,包括执行静态初始化块中的代码。所以forname执行的是静态初始化块。

    静态初始化块在类被Java虚拟机(JVM)加载并初始化时执行。这发生在类首次被“主动使用”时,静态初始化块只执行一次,无论类的构造函数被调用多少次。实例初始化块在类的每个实例被创建时执行,实例初始化块在构造函数之前执行。构造函数在创建类的新实例时调用,构造函数在实例初始化块之后执行。但在执行实例化初始化块前会先执行构造函数的super()。

另外:

java我们一般情况下拿到一个类需要用import导入才可以,不过forName就不需要,那么对我们攻击者来说很有利,可以加载任意类。

一些类名中会使用 符号, 符号, 符号,作用是查找内部类。

Java的普通类 C1中支持编写内部类 C2,而在编译的时候,会生成两个文件:C1.class 和 C1 C 2. c l a s s ,我们可以把他们看作两个无关的类,通过 C l a s s . f o r N a m e ( " C 1 C2.class,我们可以把他们看作两个无关的类,通过Class.forName("C1 C2.class,我们可以把他们看作两个无关的类,通过Class.forName("C1C2") 即可加载这个内部类。

在Java中,内部类是一种定义在另一个类中的类。内部类可以访问外部类的成员,包括私有成员。当内部类被编译时,它们会被编译成独立的.class文件,但文件名会包含外部类的名称和一个$符号,后跟内部类的名称。当你使用Class.forName("C1$C2")来加载内部类时,JVM会查找名为C1$C2的类,并将其加载到内存中。如果C1$C2类依赖于外部类C1的某些特性,那么C1类也必须已经被加载,因为内部类与外部类之间存在依赖关系。获得类以后,我们可以继续使用反射来获取这个类中的属性、方法,也可以实例化这个类,并调用方法。

获取类的字段:

obj.getFields() //获取所有public字段
obj.getDeclaredFields() //获取所有字段(包含private)

获取类的方法:

obj.getMethods() //获取所有public方法
obj.getDeclaredMethods() //获取所有方法(包含private)

Java中支持类的重载,不能仅通过函数名来确定一个函数,还需要传给他你想要获取的函数的参数类型列表。

获取类的构造器:

obj.getConstructors() //获取所有public构造器
obj.getDeclaredConstructors() //获取所有构造器,私有记得用法setAccessible修改作用域

创建类实例:

obj.newInstance() //只适用于无参构造器
constructor = obj.getDeclaredConstructor()
constructor.newInstance() //有参构造器

class.newInstance()的作用就是调用这个类的无参构造函数,不过,我们有时候在写漏洞利用方法的时候,会发现使用newInstance总是不成功,这时候原因可能是:

  1. 使用的类没有无参构造函数

  2. 使用的类构造函数是私有的
    这是因为私有类是限定在定义它的类内部使用的,它不能被外部类直接访问,因此也不能通过反射机制来创建实例。在Java 9及以后的版本中,引入了一个新的方法getDeclaredConstructor(),它可以用来获取私有构造器,但是即使如此,你仍然需要在定义私有类的类内部来使用它。

    Constructor<InnerClass> constructor = InnerClass.class.getDeclaredConstructor();
    InnerClass instance = constructor.newInstance();
    

    但是,这仍然需要 InnerClass 不是顶级私有类,并且你需要有权限访问它。对于顶级私有类,你仍然不能通过反射来创建实例。

    这里有一个特殊的类(java.lang.Runtime),这里是很常见的单例模式(单例模式是一种常用的软件设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。单例模式通常用于管理共享资源,如配置信息、线程池、缓存等。)。
    java.lang.Runtime是 Java 的一个核心类,它提供了一系列方法来与运行时环境进行交互。这个类不能被实例化,但可以通过Runtime.getRuntime()方法获取其实例,该实例代表了当前 Java 应用程序的运行时环境。
    Runtime 类的一些常用方法:
    Process exec(String command):执行指定的字符串命令,并返回一个Process对象。
    void load(String filename):从指定的文件路径加载库(如DLL或SO文件)。
    void loadLibrary(String libname):从系统的库路径中加载库。
    void addShutdownHook(Thread hook):注册一个新线程,该线程将在 Java 虚拟机退出时执行。
    void removeShutdownHook(Thread hook):取消注册之前添加的shutdown hook。

获取注解:

obj.getAnnotations()

执行方法:

method.invoke()

如果这个方法是一个普通方法,那么第一个参数是类对象
如果这个方法是一个静态方法,那么第一个参数是类

另一种执行命令方式:ProcessBuilder。使用反射来获取其类构造器,然后调用start()来执行命令。

public ProcessBuilder(List<String> command)
public ProcessBuilder(String... command)
class clazz = Class.forName("java.lang.ProcessBuilder");
((ProcessBuilder)clazz.getConstructor(List.class).newInstance(Arrays.asList("calc.exe"))).start();

有时候我们利用漏洞的时候(在表 达式上下文中)是没有强转换类型的。所以,我们仍需利用反射来完成这一步。

Class clazz = Class.forName("java.lang.ProcessBuilder");
clazz.getMethod("start").invoke(clazz.getConstructor(List.class).newInstance(Arrays.asList("calc.exe")));

通过getMethod(“start”)获取到start方法,然后 invoke 执行,根据咱们上面说的invoke 的第一个参数就是 ProcessBuilder Object了。

Class clazz = Class.forName("java.lang.ProcessBuilder");
((ProcessBuilder)clazz.getConstructor(String[].class).newInstance(new String[][]{{"calc.exe"}})).start();

在调用newInstance的时候,因为这个函数本身接收的是一个可变长参数,我们传给ProcessBuilder的也是一个可变长参数,二者叠加为一个二维数组。

标签:反射,forName,Java,安全,获取,实例,obj,Class
From: https://blog.csdn.net/wbqww_/article/details/143168556

相关文章

  • Java调用第三方接口、http请求详解,一文学会
    系列文章目录提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加例如:第一章Python机器学习入门之pandas的使用提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录系列文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据......
  • 精通Java并发锁机制:24种锁技巧+业务锁匹配方案
    在Java并发编程中,锁是确保线程安全、协调多线程访问共享资源的关键机制。从基本的synchronized同步关键字到高级的ReentrantLock、读写锁ReadWriteLock、无锁设计如AtomicInteger,再到复杂的同步辅助工具如CountDownLatch、CyclicBarrier和Semaphore,每种锁都针对......
  • 网络安全人员必知的35个安全框架及模型
    一、概括网络安全专业机构制定的一套标准、准则和程序,旨在帮助组织了解和管理面临的网络安全风险。优秀的安全框架及模型应该为用户提供一种可靠方法,帮助其实现网络安全建设计划。对于那些希望按照行业最佳实践来设计或改进安全策略的组织或个人来说,网络安全框架及模型是不可......
  • 黑马程序员Java进阶学习(三)
    异常Java的异常体系异常的基本处理异常的作用异常是什么?异常是代码在编译或者执行的过程中可能出现的错误。异常的代表是谁?分为几类?Exception,分为两类:编译时异常、运行时异常。编译时异常:没有继承RuntimeExcpetion的异常,编译阶段就会出错。运行时异常:继承自Runtim......
  • 【java】抽象类和接口(了解,进阶,到全部掌握)
    各位看官早安午安晚安呀如果您觉得这篇文章对您有帮助的话欢迎您一键三连,小编尽全力做到更好欢迎您分享给更多人哦大家好我们今天来学习Java面向对象的的抽象类和接口,我们大家庭已经来啦~一:抽象类1.1:抽象类概念在面向对象的概念中,所有的对象都是通过类来描绘的,但是......
  • java的三大程序结构
    JAVA的三大程序结构一:顺序结构程序走上执行到下。二:选择结构if单选择结构if(布尔表达式){//如果布尔表达式的值为ture则执行{}里的语句块}publicclassIfDemo01{publicstaticvoidmain(String[]args){//接收键盘输入Scannerscanner=newSca......
  • java计算机毕业设计基于的仓储管理系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景随着经济的发展和商业活动的日益频繁,仓储管理在企业运营中的重要性不断凸显。传统的仓储管理方式多依赖人工操作,例如依靠纸质文件记录货物的进出......
  • java计算机毕业设计机票订单管理系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景随着旅游业的蓬勃发展以及人们出行需求的不断增加,航空运输作为一种快速、便捷的交通方式,在现代交通体系中占据着越来越重要的地位。据统计,近年来......
  • java计算机毕业设计基于springboot的低碳生活记录网站(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景随着全球气候变化问题的日益严峻,低碳生活方式的推广成为了全球共同关注的焦点。传统的低碳生活推广主要依赖于线下宣传、教育活动等方式,然而这些......
  • java计算机毕业设计重修课程信息管理(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景在现代教育体系中,随着教育规模的不断扩大以及课程体系的日益复杂,重修课程管理面临着诸多挑战。传统的重修课程管理多依赖手工操作,这种方式效率低......