Java反射-RCE
Java安全的开始要从反射开始.反射是指在程序运行时 , 对于任何一个类 , 都能知道这个类的所有属性和方法 , 对于任何一个实例对象 , 都能调用该对象的任何一个属性和方法 .
能拿到这个类,你就可以获取和调用了解关于这个类的任何信息.
类 对象 Class对象
class对象就是由Class类创建的对象,只是这个创建过程不是由用户主动创建的,而是由JVM自动实现的。JVM会为项目中每一个类(不论是JDK自带的类、第三方jar包的类、还是自己编写的类)创建一个class对象,用来保存与这个类相关的信息。class对象只与类有关,与对象无关。我们从一张图来看它们之间的关系。
获得对象类
obj.getClass()
obj.forName(className)
className.class
查找类方法
className.getMethod(functionName , [parameterTypes.class])
className.getMethods()
className.getDeclaredMethods()
className.getConstructor()
新建类示例
调用类方法
Method.invoke(obj , args[])
访问私有化
Test.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.charset.Charset;
public class Test { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException { reflectRunCalc(); }
public static void reflectRunCalc() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException { var cls = Class.forName("java.lang.Runtime"); var run = cls.getDeclaredMethod("getRuntime"); Object obj = run.invoke(null); Method mExec = cls.getMethod("exec", String.class); Process p = (Process) mExec.invoke(obj, "ping 127.0.0.1"); InputStream is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is, Charset.forName("GBK")); BufferedReader br = new BufferedReader(isr);
String line; while ((line = br.readLine()) != null) { System.out.println(line); } } }
|
上面的代码首先通过Class.forName
获取java.lang.Runtime
类,之后通过getRuntime
方法获取Runtime示例,之后调用exec
方法来进行命令执行,后续通过InputStreamReader
来捕获输出,完成了一次反射调用,在没有显式导入java.lang.Runtime
情况下完成了一次命令执行.
读取进程输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import java.io.*;
import static java.lang.System.out;
public class ProcessExecutor { public static void main(String[] args) throws Exception { Process process = Runtime.getRuntime().exec("whoami"); var inputStream = process.getInputStream(); var reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { out.println(line); } } }
|