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");
}
这里有两个方法需要说一下 getMethod 和 invoke ,getMethod 的作用是通过反射获取一个类的某个特定的公有方法,然后利用这个方式来获取 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安全入门之反射
反射 对于反射这个概念来说,直白的讲就是: 对象可以通过反射获取他的类,类可以通过反射拿到所有⽅法(包括私有),拿到的⽅法可以调⽤而众所周知 JAVA 是一门静态语言,我们通过反射就可以达到动…...
【c++|opencv】一、基础操作---2.图像信息获取
every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 图像信息获取,roi 1. 图像信息获取 // 获取图像信息#include <iostream> #include <opencv2/opencv.hpp>using namespace cv; …...
HarmonyOS开发:探索组件化模式开发
前言 组件化一直是移动端比较流行的开发方式,有着编译运行快,业务逻辑分明,任务划分清晰等优点,针对Android端的组件化,之前有比较系统的总结过相关文章,感兴趣的朋友,可以查看,点击…...
目标URL启用了不安全的HTTP方法
修复中危web项目漏洞(目标URL启用了不安全的HTTP方法) 漏洞名 :目标URL启用了不安全的HTTP方法 等级: 中危 漏洞位置: PUT DELETE 描述: Web服务器配置为允许使用危险的HTTP方法,如PUT、MOVE、…...
大数据之LibrA数据库系统告警处理(ALM-12001 审计日志转储失败)
告警解释 根据本地历史数据备份策略,集群的审计日志需要转储到第三方服务器上。如果转储服务器满足配置条件,审计日志可以成功转储。审计日志转储失败,系统产生此告警。如果第三方服务器的转储目录磁盘空间不足,或者用户修改了转…...
大模型该被知道的技术实现-面向垂直领域
一个高度清晰的思维导图截图奉上(下载:需3积分) 内容截图...
赛灵思产品系列
FPGA概述: FPGA的性能主要划分为以下几个方面: 1. 逻辑单元数量:逻辑单元数量越多,FPGA的处理能力越强。 2. 存储单元数量:存储单元数量越多,FPGA的存储能力越强。 3. 时钟频率:时钟频率越高&a…...
[Linux C] signal 的使用
前言: signal 是一种通信机制,可以跨进程发送,可以同进程跨线程发送,可以不同进程向指定线程发送。 信号的创建有两套api,一个是signal,一个是sigaction,signal缺陷很多,比如没有提…...
AI时代产品经理升级之道:ChatGPT让产品经理插上翅膀
💂 个人网站:【工具大全】【游戏大全】【神级源码资源网】🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】💅 寻找学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 AI时代的产品经理面临着…...
计算机网络重点概念整理-第七章 网络安全【期末复习|考研复习】
计算机网络复习系列文章传送门: 第一章 计算机网络概述 第二章 物理层 第三章 数据链路层 第四章 网络层 第五章 传输层 第六章 应用层 第七章 网络安全 计算机网络整理-简称&缩写 文章目录 前言七、网络安全7.1网络安全7.2 网络威胁7.3 加密7.3.1 对称加密7.3.…...
【LeetCode力扣】42. 接雨水
目录 1、题目介绍 2、解题思路 2.1、暴力破解法 2.2、双指针法 1、题目介绍 原题链接: 42. 接雨水 - 力扣(LeetCode) 示例 1: 输入:height [0,1,0,2,1,0,1,3,2,1,2,1]输出:6解释:上面是由…...
03、SpringCloud -- 动态倒计时 及 当前用户的获取(用户未登录提示其登录)
目录 动态倒计时需求思路代码效果优化获取当前登录用户思路代码前端后端controllerservice接口impl实现效果问题修改动态倒计时 需求 根据不同时间展示不同状态,动态显示时间,如原型图: 思...
Mac用户心目中的四款首选原型工具
Wireframe、Mockup和prototype在原型工具中有什么区别? 无论你是刚进入这个行业的UX/UI设计师,还是已经进入这个行业多年的老手,你都必须在制作原型的过程中接触或听到三个非常重要的原型术语:“wireframe(线框图)Mockup”或“pr…...
国内内卷太严重,还不考虑一下在海外接单?那这几个平台你知道吗?
作为一个程序员,在平台上接单赚点外快是再正常不过的事情了,但是现今国内各个平台都内卷比较严重,你是否考虑过去“外面的世界”看看? 如果想过,那么这几个外国的接单平台你都知道吗? 接下来就和我一起来看…...
在excel中如何打出上标、下标
例如,想把A2的2变为下标。 在单元中输入内容: 选中2: 右键单击,然后点击“设置单元格格式”: 在特殊效果的下面勾选“下标”,然后点击下面的“确定”按钮: 就将2变为下标了:…...
LoongArch 五级流水线实现
在单周期的基础上进行拆分成取指、译码、执行、访存、写回五级流水线。 mycpu_top.v include "mycpu.h"module id_stage(input clk ,input reset ,//allowininput …...
「Qt中文教程指南」如何创建基于Qt Widget的应用程序(四)
Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。 本文描述了如何使用…...
11、SpringCloud -- 利用redis优化查询秒杀商品的数据(就是可以把商品数据先存到redis中)
目录 秒杀商品数据存到redis中并查询需求hash理解代码:RedisService商品数据初始化:查询 测试: 秒杀商品数据存到redis中并查询 需求 利用redis优化查询秒杀商品的数据,就是可以把商品数据先存到redis中,要查的时候先…...
计算节点上iptables安全组分析
计算节点上iptables安全组分析 之前介绍过neutron 安全组基于iptables 和 ct 实现,分析一下计算节点上面的neutron 安全组的iptables,加深一下理解iptables以及安全组的实现。(PS: 如下基于openstack stein) 查看某计算节点上面的iptables …...
香港科技大学广州|可持续能源与环境学域博士招生宣讲会—上海专场!!!(暨全额奖学金政策)
香港科技大学广州|可持续能源与环境学域博士招生宣讲会—上海专场!!!(暨全额奖学金政策) “面向未来改变游戏规则的——可持续能源与环境学域” ���专注于能源环境跨学…...
保姆级教程:用TensorFlow 2.x和EfficientNetB0搞定CASIA-HWDB手写汉字识别(附完整代码)
从零构建手写汉字识别系统:TensorFlow 2.x与EfficientNetB0实战指南 在数字化办公场景中,手写体识别技术正逐渐成为提升效率的隐形助手。无论是银行票据处理、教育作业批改还是历史档案数字化,准确识别手写汉字的能力都显得尤为重要。本文将带…...
Linux CoreDump实战指南:从原理到容器化环境配置与自动化分析
1. 项目概述:为什么我们需要一份CoreDump实战指南?在服务器运维和后台开发领域,最让人头疼的瞬间之一,莫过于半夜被电话叫醒,被告知线上服务“挂了”。登录服务器一看,进程消失得无影无踪,只留下…...
LinkSwift:九大网盘直链下载的终极解决方案,快速获取真实下载地址
LinkSwift:九大网盘直链下载的终极解决方案,快速获取真实下载地址 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘…...
保姆级教程:用HackRF One复现汽车钥匙重放攻击(附完整命令与避坑点)
从零掌握HackRF One信号重放:433MHz汽车钥匙实战全解析 当你在停车场按下车钥匙按钮时,那串看似神秘的无线电波背后隐藏着怎样的安全漏洞?作为硬件安全领域的入门神器,HackRF One让普通爱好者也能窥探射频世界的奥秘。本文将带你用…...
Pixelle-Video全球化架构:智能AI短视频引擎的多语言解决方案
Pixelle-Video全球化架构:智能AI短视频引擎的多语言解决方案 【免费下载链接】Pixelle-Video 🚀 AI 全自动短视频引擎 | AI Fully Automated Short Video Engine 项目地址: https://gitcode.com/GitHub_Trending/pi/Pixelle-Video Pixelle-Video作…...
Langchain的学习(一)
目录 一,实操 编码 Runnable Runnable 是什么 核心方法(所有 Runnable 都有) 最关键能力:用 | 组合(LCEL) 常用内置 Runnable 总结 二,聊天模型-核心能力 定义模型 init_chat_model 本地部署 调用工具 定义工具-Tool version1 schema: version2(基于…...
Day33-1: Serilog(日志中间件)VS OperLogHelper(操作日志帮助类)
一、一句话分清它们的作用 1. Serilog(日志中间件) 作用:记录系统运行日志 → 给程序员看的 控制台打印文件保存报错、异常、请求信息用于排查问题、调试、监控 2. OperLogHelper(操作日志帮助类) 作用࿱…...
非规则区域上空间分数阶偏微分方程的有限元方法【附仿真】
✨ 长期致力于空间分数阶导数、高维问题、有限元方法、非规则区域、非结构化网格、非光滑解研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,点击《获取方式》 (1)二维非规则…...
主从结合,安全互联:Anybus工业通信解决方案全栈升级
HMS亮相2026 PROFINET技术路演杭州站,展出全新Anybus SoM及全栈PROFINET方案,助力设备商应对CRA与机械法规双重合规挑战。 5月14日,由PI China主办的2026 PROFINET技术路演(杭州站)在西玥酒店圆满举行。HMS华东区OEM销…...
AI技术总监的晋升密码:搞定这6件事,你也能领导AI团队
在AI技术重塑各行各业的当下,软件测试从业者正站在职业转型的关键路口。从测试工程师到AI技术总监,不仅是职位的跃迁,更是能力模型的全面升级。想要在AI浪潮中脱颖而出,成为引领团队的技术掌舵人,你需要搞定这6件事。一…...
