java安全学习篇:1-反射

文章发布时间:

最后更新时间:

java 安全学习篇 – 1 反射

参考文章:知识星球 phithon 的文章(java 安全漫谈 - 01.反射篇(1))

参考文章:javaguide

反射:

java 反射可以动态获取类信息,对象通过反射获取类,类反射获取所有方法,包括私有,p 牛这里给动态特性一个定义,“⼀一段代码,改变其中的变量量,将会导致 这段代码产⽣生功能性的变化,我称之为动态特性

白嫖一段代码

1
2
3
4
public void execute(String className, String methodName) throws Exception {
Class clazz = Class.forName(className);
clazz. getMethod(methodName).invoke(clazz.newInstance());
}
  • forName 方法获取类此外还有别的方法,obj.getClass() 这个方法针对下文有类对应实例,通过实例获取对应类

  • getmethod 方法获取类的方法

  • invoke 方法执行函数

  • newInstance 方法实例化类对象

那我们想获取 Runtime 类,我们可以根据给到的实例,通过 obj.getClass().forName(java.lang.Runtime) 获取到 Runtime 类

forName 方法还有重载, forName(String name, boolean initialize, ClassLoader loader) 我们常用的实际上是

forName(classname, true, currentLoader) 。第二个参数表示是否初始化,第三个参数是加载器,告诉虚拟机怎么加载

java 加载器

涉及到的东西有点多,先粗略了解一下

规则: 由于 java 采用延迟加载机制只有当程序需要使用某个类时,才会由类加载器加载该类。

作用: 动态加载 java 类的字节码到虚拟机中,还可以加载 Java 应用所需的资源如文本、图像、配置文件、视频等等文件资源

initialize

我们知道这个参数负责类是否初始化,那类的初始化有什么用呢

白嫖一段代码:

1
2
3
4
5
6
7
8
9
10
11
public class TrainPrint {
{
System.out.printf("Empty block initial %s\n", this.getClass());
}
static {
System.out.printf("Static initial %s\n", TrainPrint.class);
}
public TrainPrint() {
System.out.printf("Initial %s\n", this.getClass());
}
}

当这个类被初始化时,首先调用 static,然后调用父类构造方法,之后是{},最后是自己的构造方法

根据这个特性,我们能够发现当 forName() 方法中的参数可控时,我们如果能将一个类放到被攻击机中并在里面 static 部分写入恶意代码,就能达到攻击目的