这篇文章上次修改于 894 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
本文将介绍如何利用Java的反射机制来动态调用任意函数
文章目录:
利用Java反射机制构造payload
0x01 简介
在运行状态中:
1.对于任何一个类,都能知道该类的任何属性和方法。
2.对于任何一个对象,都能调用该对象的任何一个方法。
这种动态获取信息,动态调用对象的方法就叫做Java语言的反射机制。
该特性可以使得Java在程序运行期间,动态加载我们想要引入的任意类,并且调用任意的方法。
0x02 主要步骤
一般来说,我们都是通过dot运算符(.)来调用对象的方法的。
若使用反射调用,则有如下步骤:
1.获取该类的Class Type
2.通过getMethod方法,获取Method对象
3.通过invoke方法,执行对象的某个方法
接下来分为三步,分别介绍
1.获取Class对象
Class是一切反射操作的源头,Java中有三种方法来获取Class对象:
- 1.调用Object类的getClass方法
public class Demo
{
public static void main(String[] args) throws Exception
{
Person per = new Person();
Class c = per.getClass();
System.out.println(c);
}
}
输出:
class com.fxl.test.Person
- 2.使用类.class
public class Demo
{
public static void main(String[] args) throws Exception
{
Class c = Person.class;
System.out.println(c);
}
}
- 3.使用Class类的静态方法forName
public class Demo
{
public static void main(String[] args) throws Exception
{
Class c = Class.forName("com.fxl.test.Person");
System.out.println(c);
}
}
2.获取method对象
我们可以通过getMethod()方法,获得指定方法的对象
import java.lang.reflect.Method;
public class Demo
{
public static void main(String[] args) throws Exception
{
Class c = Person.class;
System.out.println(c);
//Method m = c.getMethod("eat", new Class[]{int.class, int.class});
Method m = c.getMethod("eat", int.class, int.class);
System.out.println(m);
}
}
getMethod()方法返回一个特定方法的对象,第一个参数为方法名,后面的参数为方法参数所对应的Class对象,以上的两种写法均可。
3.调用方法
获取了方法对象之后,就可以使用invoke()函数进行调用了。
invoke()的第一个参数为执行该方法的对象,后面是方法参数。
如果是静态方法调用,可以用null来作为invoke的参数
import java.lang.reflect.Method;
public class Demo
{
public static void main(String[] args) throws Exception
{
Class c = Person.class;
System.out.println(c);
Method m = c.getMethod("eat", int.class, int.class);
System.out.println(m);
//Object o = m.invoke(new Person(),1,2);
Object o = m.invoke(new Person(),new Object[]{1,2});
}
}
输出:
class com.fxl.test.Person
public void com.fxl.test.Person.eat(int,int)
i am eating!
0x03 构造payload
前面介绍了反射机制,以及其原理和方法,下面我们实例构造一个payload。
Runtime.getRuntime().exec("calc.exe");
要构造如上语句,依然是分为三步来进行,不过由于是静态方法调用,所以是四条语句:
import java.lang.reflect.Method;
public class Demo
{
public static void main(String[] args) throws Exception
{
Class a = Runtime.class;
Method m = a.getMethod("getRuntime");
Runtime run = (Runtime)m.invoke(null);
run.exec("calc.exe");
}
}
参考
- https://hacksec.xyz/2018/05/01/java-serialize/#JAVA%E5%8F%8D%E5%B0%84 Collections反序列化漏洞
- http://t.cn/RDKAHkt 利用反射机制构造payload
- http://t.cn/RDK5Kc9
- https://blog.csdn.net/qq_39266910/article/details/78567116 Java反射Method包
- https://www.zhihu.com/question/24304289 Java反射机制
- https://www.cnblogs.com/douder/p/7237883.html Java反射机制
没有评论