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

JAVA安全入门之反射

反射

对于反射这个概念来说,直白的讲就是:

对象可以通过反射获取他的类,类可以通过反射拿到所有⽅法(包括私有),拿到的⽅法可以调⽤

而众所周知 JAVA 是一门静态语言,我们通过反射就可以达到动态的语言的特性。
我们可以类比一下我们的老朋友 PHP ,对于 PHP 来说,一个简单的 webshell 可以完成各种操作,而对于 JAVA 来说,我们就可以用 反射 达到一些动态的特性。
比如以下代码:

public void execute(String className, String methodName) throws Exception {Class clazz = Class.forName(className);clazz.getMethod(methodName).invoke(clazz.newInstance());
}

以上代码,有几个反射中重要的方法:

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

但是 forName 并不是获取类的唯一方法,对于反射来说,还有两种方法来获取类:
1、如果已经有了一个类的实例,我们只需要用 obj.getClass() 来获取他的类。
2、如果你知道某个类的名字,想获取到这个类,就可以使⽤ forName 来获取。
当然除了以上反射的方法,还有一种方法:
如果你已经加载了某个类,只是想获取到它的 java.lang.Class 对象,那么就直接拿它的 class 属性即可。

如果我们看一下 forName 会发现他有两个重载方法:

public static Class<?> forName(String className)  throws ClassNotFoundException {  Class<?> caller = Reflection.getCallerClass();  return forName0(className, true, ClassLoader.getClassLoader(caller), caller);  
}
public static Class<?> forName(String name, boolean initialize,  ClassLoader loader)  throws ClassNotFoundException  
{  Class<?> caller = null;  SecurityManager sm = System.getSecurityManager();  if (sm != null) {  // Reflective call to get caller class is only needed if a security manager  // is present.  Avoid the overhead of making this call otherwise.        caller = Reflection.getCallerClass();  if (sun.misc.VM.isSystemDomainLoader(loader)) {  ClassLoader ccl = ClassLoader.getClassLoader(caller);  if (!sun.misc.VM.isSystemDomainLoader(ccl)) {  sm.checkPermission(  SecurityConstants.GET_CLASSLOADER_PERMISSION);  }  }  }  return forName0(name, initialize, loader, caller);  
}

对比着来看,会发现第一个比第二个少了个点东西:

public static Class<?> forName(String className)public static Class<?> forName(String name, boolean initialize,  ClassLoader loader)

对于第二种:

  • name : 类名
  • initialize : 是否初始化
  • ClassLoader : 类的加载器

ClassLoader 看到这个名字就能看出来,他就是一个类的 加载器
Java 默认的 ClassLoader 是根据类的名字(类的全称,例如 : java.lang.runtime)加载类。

反射的主要目的就是不通过 import 来导入类,这一点是攻击者想要的,而 forName 就可以做到这一点。

Java 中可以在类中编写内部类,在编译的时候会产生两个类文件如下:

public class main {  public static void main(String[] args) throws Exception {  System.out.println("Hello World!");  }  class test1{  public String test =  "hello";  }  
}

会生成如下文件:

├── main$test1.class
└── main.class

而你想要通过反射拿到 test1 类的时候可以通过 Class.forName("main$test1") 的方式来加载内部类,从而一系列操作。

说了这么多,我们举个小例子:

public static void main(String[] args) throws Exception {  Class c = Class.forName("java.lang.Runtime");  c.getMethod("exec", String.class).invoke(c.newInstance(), "open -a Calculator ");  
}

发现会报错对吧!

Exception in thread "main" java.lang.IllegalAccessException: Class main can not access a member of class java.lang.Runtime with modifiers "private"

这里很好理解,c.newInstance() 的作用就是调用这个类的无参构造函数所以存在以下情况就会失败:

  • 加载的类没有无参构造函数
  • 加载的类的构造函数是私有的
    我们可以看一下 newInstance() 的代码:
if (cachedConstructor == null) {  if (this == Class.class) {  throw new IllegalAccessException(  "Can not call newInstance() on the Class for java.lang.Class"  );  }

这里就很明确了 if (cachedConstructor == null) 如果没有构造函数就抛出一个异常。

// Security check (same as in java.lang.reflect.Constructor)
int modifiers = tmpConstructor.getModifiers();  
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {  Class<?> caller = Reflection.getCallerClass();  if (newInstanceCallerCache != caller) {  Reflection.ensureMemberAccess(caller, this, null, modifiers);  newInstanceCallerCache = caller;  }  
}

跟进 ensureMemberAccess 方法:

public static void ensureMemberAccess(Class<?> var0, Class<?> var1, Object var2, int var3) throws IllegalAccessException {  if (var0 != null && var1 != null) {  if (!verifyMemberAccess(var0, var1, var2, var3)) {  throw new IllegalAccessException("Class " + var0.getName() + " can not access a member of class " + var1.getName() + " with modifiers \"" + Modifier.toString(var3) + "\"");  }  } else {  throw new InternalError();  }  
}

可以看到在这里抛出了异常,在此先不细说中间是怎么校验的。

所以我们可以这样来改造:

public static void main(String[] args) throws Exception {  Class c = Class.forName("java.lang.Runtime");  c.getMethod("exec", String.class).invoke(c.getMethod("getRuntime").invoke(c), "open -a Calculator");  
}

这里有两个方法需要说一下 getMethodinvokegetMethod 的作用是通过反射获取一个类的某个特定的公有方法,然后利用这个方式来获取 Runtime.exec 方法。

invoke 大家应该很熟悉,我们可以看看他的源码:

public Object invoke(Object obj, Object... args)  throws IllegalAccessException, IllegalArgumentException,  InvocationTargetException  
{  if (!override) {  if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {  Class<?> caller = Reflection.getCallerClass();  checkAccess(caller, clazz, obj, modifiers);  }  }  MethodAccessor ma = methodAccessor;             // read volatile  if (ma == null) {  ma = acquireMethodAccessor();  }  return ma.invoke(obj, args);  
}

这里做了一些操作,可以自己跟一下,这里就不过多叙述了。

invoke 的作用是执行方法,它的第一个参数是:

  • 如果这个方法是一个普通方法,那么第一个参数是类对象
  • 如果这个方法是一个静态方法,那么第一个参数是类
    正常执行方法是 [1].method([2], [3], [4]...),在反射里就是这样的 method.invoke([1], [2], [3], [4]...)

相关文章:

JAVA安全入门之反射

反射 对于反射这个概念来说&#xff0c;直白的讲就是&#xff1a; 对象可以通过反射获取他的类&#xff0c;类可以通过反射拿到所有⽅法&#xff08;包括私有&#xff09;&#xff0c;拿到的⽅法可以调⽤而众所周知 JAVA 是一门静态语言&#xff0c;我们通过反射就可以达到动…...

【c++|opencv】一、基础操作---2.图像信息获取

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 图像信息获取&#xff0c;roi 1. 图像信息获取 // 获取图像信息#include <iostream> #include <opencv2/opencv.hpp>using namespace cv; …...

HarmonyOS开发:探索组件化模式开发

前言 组件化一直是移动端比较流行的开发方式&#xff0c;有着编译运行快&#xff0c;业务逻辑分明&#xff0c;任务划分清晰等优点&#xff0c;针对Android端的组件化&#xff0c;之前有比较系统的总结过相关文章&#xff0c;感兴趣的朋友&#xff0c;可以查看&#xff0c;点击…...

目标URL启用了不安全的HTTP方法

修复中危web项目漏洞&#xff08;目标URL启用了不安全的HTTP方法&#xff09; 漏洞名 &#xff1a;目标URL启用了不安全的HTTP方法 等级&#xff1a; 中危 漏洞位置&#xff1a; PUT DELETE 描述&#xff1a; Web服务器配置为允许使用危险的HTTP方法&#xff0c;如PUT、MOVE、…...

大数据之LibrA数据库系统告警处理(ALM-12001 审计日志转储失败)

告警解释 根据本地历史数据备份策略&#xff0c;集群的审计日志需要转储到第三方服务器上。如果转储服务器满足配置条件&#xff0c;审计日志可以成功转储。审计日志转储失败&#xff0c;系统产生此告警。如果第三方服务器的转储目录磁盘空间不足&#xff0c;或者用户修改了转…...

大模型该被知道的技术实现-面向垂直领域

一个高度清晰的思维导图截图奉上&#xff08;下载&#xff1a;需3积分&#xff09; 内容截图...

赛灵思产品系列

FPGA概述&#xff1a; FPGA的性能主要划分为以下几个方面&#xff1a; 1. 逻辑单元数量&#xff1a;逻辑单元数量越多&#xff0c;FPGA的处理能力越强。 2. 存储单元数量&#xff1a;存储单元数量越多&#xff0c;FPGA的存储能力越强。 3. 时钟频率&#xff1a;时钟频率越高&a…...

[Linux C] signal 的使用

前言&#xff1a; signal 是一种通信机制&#xff0c;可以跨进程发送&#xff0c;可以同进程跨线程发送&#xff0c;可以不同进程向指定线程发送。 信号的创建有两套api&#xff0c;一个是signal&#xff0c;一个是sigaction&#xff0c;signal缺陷很多&#xff0c;比如没有提…...

AI时代产品经理升级之道:ChatGPT让产品经理插上翅膀

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 AI时代的产品经理面临着…...

计算机网络重点概念整理-第七章 网络安全【期末复习|考研复习】

计算机网络复习系列文章传送门&#xff1a; 第一章 计算机网络概述 第二章 物理层 第三章 数据链路层 第四章 网络层 第五章 传输层 第六章 应用层 第七章 网络安全 计算机网络整理-简称&缩写 文章目录 前言七、网络安全7.1网络安全7.2 网络威胁7.3 加密7.3.1 对称加密7.3.…...

【LeetCode力扣】42. 接雨水

目录 1、题目介绍 2、解题思路 2.1、暴力破解法 2.2、双指针法 1、题目介绍 原题链接&#xff1a; 42. 接雨水 - 力扣&#xff08;LeetCode&#xff09; 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1]输出&#xff1a;6解释&#xff1a;上面是由…...

03、SpringCloud -- 动态倒计时 及 当前用户的获取(用户未登录提示其登录)

目录 动态倒计时需求思路代码效果优化获取当前登录用户思路代码前端后端controllerservice接口impl实现效果问题修改动态倒计时 需求 根据不同时间展示不同状态,动态显示时间,如原型图: 思...

Mac用户心目中的四款首选原型工具

Wireframe、Mockup和prototype在原型工具中有什么区别&#xff1f; 无论你是刚进入这个行业的UX/UI设计师&#xff0c;还是已经进入这个行业多年的老手&#xff0c;你都必须在制作原型的过程中接触或听到三个非常重要的原型术语&#xff1a;“wireframe(线框图)Mockup”或“pr…...

国内内卷太严重,还不考虑一下在海外接单?那这几个平台你知道吗?

作为一个程序员&#xff0c;在平台上接单赚点外快是再正常不过的事情了&#xff0c;但是现今国内各个平台都内卷比较严重&#xff0c;你是否考虑过去“外面的世界”看看&#xff1f; 如果想过&#xff0c;那么这几个外国的接单平台你都知道吗&#xff1f; 接下来就和我一起来看…...

在excel中如何打出上标、下标

例如&#xff0c;想把A2的2变为下标。 在单元中输入内容&#xff1a; 选中2&#xff1a; 右键单击&#xff0c;然后点击“设置单元格格式”&#xff1a; 在特殊效果的下面勾选“下标”&#xff0c;然后点击下面的“确定”按钮&#xff1a; 就将2变为下标了&#xff1a;…...

LoongArch 五级流水线实现

在单周期的基础上进行拆分成取指、译码、执行、访存、写回五级流水线。 mycpu_top.v include "mycpu.h"module id_stage(input clk ,input reset ,//allowininput …...

「Qt中文教程指南」如何创建基于Qt Widget的应用程序(四)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 本文描述了如何使用…...

11、SpringCloud -- 利用redis优化查询秒杀商品的数据(就是可以把商品数据先存到redis中)

目录 秒杀商品数据存到redis中并查询需求hash理解代码&#xff1a;RedisService商品数据初始化&#xff1a;查询 测试&#xff1a; 秒杀商品数据存到redis中并查询 需求 利用redis优化查询秒杀商品的数据&#xff0c;就是可以把商品数据先存到redis中&#xff0c;要查的时候先…...

计算节点上iptables安全组分析

计算节点上iptables安全组分析 之前介绍过neutron 安全组基于iptables 和 ct 实现&#xff0c;分析一下计算节点上面的neutron 安全组的iptables&#xff0c;加深一下理解iptables以及安全组的实现。&#xff08;PS: 如下基于openstack stein) 查看某计算节点上面的iptables …...

香港科技大学广州|可持续能源与环境学域博士招生宣讲会—上海专场!!!(暨全额奖学金政策)

香港科技大学广州&#xff5c;可持续能源与环境学域博士招生宣讲会—上海专场&#xff01;&#xff01;&#xff01;&#xff08;暨全额奖学金政策&#xff09; “面向未来改变游戏规则的——可持续能源与环境学域” &#xfffd;&#xfffd;&#xfffd;专注于能源环境跨学…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...