前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >初探java安全之反射(1)

初探java安全之反射(1)

作者头像
pankas
发布2022-10-08 08:46:03
2450
发布2022-10-08 08:46:03
举报
文章被收录于专栏:pankas的技术分享

初探java安全之反射(1)

前言

上次和亮去接了个渗透的比赛,结果我还是啥都不会,当时意识到现在大多数的网站的后端都基本上是 java 和 go了,想 php 的基本上比较少了,php 在以后肯定会没落的,java不想 php 那样 简单易用且灵活,所以很有必要系统性的学习一下java安全。

初探java反射

Java安全可以从反序列化漏洞开始说起,反序列化漏洞⼜可以从反射开始说起。 反射是⼤多数语⾔⾥都必不可少的组成部分,对象可以通过反射获取他的类,类可以通过反射拿到所有 ⽅法(包括私有),拿到的⽅法可以调⽤,总之通过“反射”,我们可以将Java这种静态语⾔附加上动态 特性。

java反射这块学校的教科书上并没有,我是参考这篇学习的 https://www.cainiaojc.com/java/java-reflection.html

什么是java反射

Java中有一个名为Class的类,该类在运行时保留有关对象和类的所有信息。

Class对象描述了特定类的属性。该对象用于执行反射。

反射机制允许程序在执行期借助于 ReflectionAPI 取得任何类的内部信息(比如成员变量、构造器、成员方法等等),并能操作对象的属性及方法。 加载完类后,在堆中就产⽣了⼀个Class类型的对象(⼀个类只有⼀个Class对象),这个对象包含了类的完整结构 信息。通过这个对象得到类的结构。

image-20221007204432423
image-20221007204432423

利用反射机制可以使 java 这样的编译型语言 更加灵活起来

Java反射机制可以完成:

  • 在运⾏时判断任意⼀个对象所属的类
  • 在运⾏时构造任意⼀个类的对象
  • 在运⾏时得到任意⼀个类所具有的成员变量和⽅法
  • 在运⾏时调⽤任意⼀个对象的成员变量和⽅法
  • ⽣成动态代理

反射相关的主要类如下:

代码语言:javascript
复制
1、Java.lang.Class:代表⼀个类,Class对象表示某个类加载后在堆中的对象
2、Java.lang.reflect.Method:代表类的⽅法
3、Java.lang.reflect.Field:代表类的成员变量
4、Java.lang.reflect.Constructor:代表类的构造⽅法
反射要用到的一些方法

参考 https://www.cainiaojc.com/java/java-reflection.html

获得名为 Class 的类的对象

使用 forName() 方法

forName() 接受字符串参数(类的名称)并返回Class对象。返回的对象引用字符串指定的类。例如,

代码语言:javascript
复制
Class Dog {  }
Class c1 = Class.forName("Dog"); //获得名为Dog的Class对象

使用getClass()方法

getClass() 方法使用特定类的对象来创建新的对象Class。例如,

代码语言:javascript
复制
Dog d1 = new Dog();
Class c1 = d1.getClass();

使用.class

java 的每个类中默认会创建一个名为 class 的属性,该属性就是该类的 Class 对象

我们还可以使用 .class 扩展名创建Class对象。例如,

代码语言:javascript
复制
Class c1 = Dog.class;   //使用   类名.class   获得Class对象

创建Class对象后,我们可以使用这些对象执行反射。

获取接口

若一个类实现了某个接口,可以使用 Class 的 getInterfaces() 方法来获取。此方法返回一个接口数组。

代码语言:javascript
复制
Class obj = d1.getClass();//获得class对象 
Class[] objInterface = obj.getInterfaces();//获得接口
获取父类和访问修饰符

类 Class 的方法 getSuperclass() 可用于获取有关特定类的父类的信息。

而且,Class提供了一种 getModifier() 方法,该方法以整数形式返回class的修饰符。

代码语言:javascript
复制
Class obj = d1.getClass();
//以整数形式获取Dog的访问修饰符
int modifier = obj.getModifiers();
//获取Dog的父类
Class superClass = obj.getSuperclass();
获取字段(属性)

我们可以使用 Field 类提供的各种方法检查和修改类的不同字段。

  • getFields() -> Field 返回该类及其父类的所有公共字段
  • getDeclaredFields() -> Field[] 返回类的所有字段
  • getModifier() -> int 以整数形式返回字段的修饰符
  • set(Object, value) -> void 使用指定的值设置字段的值(注意是 Object,是个对象实列)
  • get(Object) -> Object 获取字段的值 (注意是 Object)
  • setAccessible(boolean) -> void 使私有字段可访问

注意:如果我们知道字段名称,则可以使用

  • getField(“fieldName”) -> Field 从类返回名称为 fieldName 的公共字段。
  • getDeclaredField(“fieldName”) -> Field 从类返回名称为 fieldName 的字段。(若获得的是私有字段,则要在使用之前设置 setAccessible(true)

例如有

代码语言:javascript
复制
class Dog {
  public String type;
}

访问公共字段

代码语言:javascript
复制
 Dog d1 = new Dog();
//创建Class对象
Class obj = d1.getClass();
//操纵Dog类的公共字段type
Field field1 = obj.getField("type");
//设置字段的值,第一个参数是对象实例
field1.set(d1, "labrador");
//通过转换成字符串来获取字段的值,第一个参数是对象实例
String typeValue = (String)field1.get(d1);
//获取类型的访问修饰符
int mod1 = field1.getModifiers();
String modifier1 = Modifier.toString(mod1);

访问私有字段

设有

代码语言:javascript
复制
class Dog {
 private String color;
}
代码语言:javascript
复制
 Dog d1 = new Dog();
//创建类Class对象
Class obj = d1.getClass();

//访问私有字段
Field field2 = obj.getDeclaredField("color");

//使私有字段可访问
field2.setAccessible(true);
//设置color值(注意第一个参数为对象实例)
field2.set(d1, "brown");
// get the value of type converting in String
String colorValue = (String)field2.get(d1);
//获取color的访问修饰符
int mod2 = field2.getModifiers();
String modifier2 = Modifier.toString(mod2);
获取方法

像字段一样,我们可以使用 Method 类提供的各种方法来检查类的不同方法。

  • getMethods() -> Method[] 返回该类及其超类的所有公共方法
  • getDeclaredMethod() -> Method[] 返回该类的所有方法
  • getName() -> String 返回方法的名称
  • getModifiers() -> int 以整数形式返回方法的访问修饰符
  • getReturnType() -> Class<?> 返回方法的返回类型
代码语言:javascript
复制
class Dog {
   public void display() {
      System.out.println("I am a dog.");
   }

   protected void eat() {
      System.out.println("I eat dog food.");
   }

   private void makeSound() {
      System.out.println("Bark Bark");
   }

}

class ReflectionDemo {
   public static void main(String[] args) {
      try {
          Dog d1 = new Dog();

          //创建一个Class对象
          Class obj = d1.getClass();
          
          //使用getDeclaredMethod()获取所有方法
          Method[] methods = obj.getDeclaredMethods();

          //获取方法的名称
          for(Method m : methods) {
               
             System.out.println("方法名称: " + m.getName());
              
             //获取方法的访问修饰符
             int modifier = m.getModifiers();
             System.out.println("修饰符: " + Modifier.toString(modifier));
              
             //获取方法的返回类型
             System.out.println("Return Types: " + m.getReturnType());
             System.out.println(" ");
          }
       }
       catch(Exception e) {
           e.printStackTrace();
       }
   }
}
实例化对象与执行函数
  • newInstance() 实例化类对象的方法 ,位于 Class 类中 (只能无参构造)
代码语言:javascript
复制
Class clsd = Class.forName("Dog");
Dog dog = (Dog) clsd.newInstance();//通过反射实例化一个对象
dog.display();
  • invoke 执行函数的方法,位于 Method 类中
代码语言:javascript
复制
//执行Dog中的display方法
public class Invo {
    public static void main(String[] args) throws Exception {
        execute("Dog", "display");
    }
    public static void execute(String className, String methodName) throws Exception {
        Class clazz = Class.forName(className);
        clazz.getMethod(methodName).invoke(clazz.newInstance());
    }
}
class Dog {

    public void display() {
        System.out.println("I am a dog.");
    }
}

重点方法

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

基本上,这几个方包揽了Java安全里各种和反射有关的Payload。

代码语言:javascript
复制
public void execute(String className, String methodName) throws Exception {
     Class clazz = Class.forName(className);
     clazz.getMethod(methodName).invoke(clazz.newInstance());
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-10-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初探java安全之反射(1)
    • 前言
      • 初探java反射
        • 什么是java反射
        • 反射要用到的一些方法
      • 重点方法
      相关产品与服务
      文件存储
      文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档