Java反射
通常我们想用一个类的时候,首先需要先调用import,而通过反射里面的forName可以直接调用该类
获取到类后,我们可以进一步的调用其属性、方法,也可先实例化后,在进行方法的调用
使用**newInstance()**可以调用无参构造函数
**newInstance()**可能会调用失败,原因可能是
- 你使用的类不是无参构造函数
- 你使用的可能是私有构造方法
使用 java.lang.Runtime举例
Class clazz = Class.forName("java.lang.Runtime");
clazz.getMethod("exec",String.class).invoke(clazz.newInstance(),"id");
这样直接进行调用会出现报错

报错会告诉我们这个类不能使用私有方法
这涉及到了单列模式,Runtime是一个私有方法,
为了我们能安全的使用这个函数,设计出单列模式,通过为Runtime创建一个公共方法的getRuntime来是实现调用这个函数
Class<?> clazz = CLass.forName("java.lang.Runtime");
clazz.getMethod("exec",String.class).invoke(clazz.getMethod("getRuntime").invoke(clazz),"calc.exe");

在这次使用我们用到了getMethod和invoke方法,在调用getMethod方法的时候,我们需要传给他你需要获取的参数类型的列表

我们使用最简单的,也就是第一个,它只有一个参数,类型是String,所以我们使用
getMethod(“exec”, String.class) 来获取 Runtime.exec 方法。
invoke 的作用是执行方法,它的第一个参数是:
- 如果这个方法是一个普通方法,那么第一个参数是类对象
- 如果这个方法是一个静态方法,那么第一个参数是类
将上述payload拆解为
Class<?> clazz = Class.forName("java.lang.Runtime");
Method getRuntimeMethod = clazz.getMethod("getRuntime");
Method execMethod = clazz.getMethod("exec",String.class);
Object runtime = getRuntimeMethod.invoke(clazz);
execMethod.invoke(runtime,"calc.exe");

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Antifrag!






