偶尔走失,从未离开

本文将介绍如何利用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");
    }
}

参考

 标签: java

作者  :  watcher


添加新评论