编程语言
首页 > 编程语言> > java安全

java安全

作者:互联网

java安全-

反射

学习之前推荐你们看一下这个文章
要学的东西太多,但是时间却不够了,由于我也是第一次学,希望有错误的地方能有大佬给纠正

需要了解到这几个函数

获取类的⽅法: forName
实例化类对象的⽅法: newInstance
获取函数的⽅法: getMethod
执⾏函数的⽅法: invoke

一般来说最简单的形式就是这个样子的

Class c = Class.forName(className); c.getMethod(methodName).invoke(c.newInstance());

但实际上在真实的生活中往往需要绕过各式各样的东西

在这里需要说一下在类的运行时

class A{
    public A(){
        System.out.println("A");
    }

    static {
        System.out.println("B");
    }

    {
        System.out.println("C");
    }
}

首先调用的是static,其次是{},最后是构造函数,也就是BCA

static在类初始化的时候就会调用,{}是在构造函数的super()之后

所以在forName对类进行初始化的时候实际上会调用static模块

java在普通类的class_1中如果你在后面接着定义了一个class_2类,会生成class_1.class和class_1$class_2.class

所以该怎么利用呢?

如果有一个函数里面如果有一个这个语句

Class.forName(class);

这个时候我们可以控制其中的class,那么我们就可以自己编写一个恶意类,将恶意代码放在static模块下面

在使用这个方法的时候我们就已经获得了一个类了,接下来我们要获得它里面的东西了

class.newInstance()可以调用类的无参构造函数。但是如果类是私有的就会报错

如果想要调用私有类就不能使用这个函数了,我们因该用class.getMethod来调用这个私有类中的静态函数去调用这个私有类的构造函数(这里可能有点绕),因为一般私有类都会有一个静态函数实现相应的功能

在将这个之前我要说一下两个函数getMEthodinvoke

getMethod的作用是通过反射获取一个类的某个特定的共有方法,因为java中类可能会有很多重载,我们没有办法通过函名儿去确定一个函数,所以需要传递一个函数参数类型的列表

method(String str)=>class.getMethod("method",String.class)
method(String[] strN)=>class.getMethod("method",String[].class)

举个例子java.lang.Runtime就是一个私有类,在调用这个私有类的构造函数的时候不能直接

Class clazz = Class.forName("java.lang.Runtime");
clazz.getMethod("exec", String.class).invoke(clazz.newInstance(), "id");

invoke的作用是执行方法,一般紧跟着getMethod使用

我们应该利用getMethod函数去获得这个类的Runtime.getRuntime()方法来获得对象

所以这个payload可以改成

Class c = Class.forName("java.lang.Runtime");
c.getMethod("exec", String.class).invoke(c.getMethod("getRuntime").innoke(c), "id");

这个payload可以一步一步的去看

第一步获得java.lang.Runtime

Class c = Class.forName("java.lang.Runtime");

第二步获得我们想要执行的exec方法

Method method = c.getMethod("exec",String.class);

第三步获得我们这个类的对象

method  getObject = c.getMethod("getRuntime");

第四步实现第三步

Object run= getObject.invoke(c);

第五步实现我们的payload

method.invoke(run,"id");

在这之前我们说过一个问题:类是私有类的时候不能直接使用newInstance()来获取无参构造函数,用getMethod去调用它的方法,那如果方法是私有的怎么办?

那就是使用getDeclared系列的反射

继续上面的例子

我们不用getMethod去获得getRuntime我们直接用getDclaredConstructor来获取私方法

它的使用方法和getMethod类似,不过需要使用setAccessible来修改作用域

Class c = Class.forName("java.lang.Runtime");
Constructor gouzao = c.getDeclaredConstructor():
gouzao.setAccessible(true);
c.getMethod("exec",String.class).invoke(gouzo.newInstance(),"id");

如果我们要获得有参的构造函数呢

那就是用getConstructor是不是与上面的玩意儿很眼熟我去百度了一波他们的区别

getMethod 系列方法获取的是当前类中所有公共方法,包括从父类继承的方法 getDeclaredMethod 系列方法获取的是当前类中“声明”的方法,是实在写在这个类里的,包括私 有的方法,但从父类里继承来的就不包含了

getConstructorgetDeclaredConstructor也类似

我先创建一个类

package DG
public class test {
    private int age;
    private String name;
 
    public test( String name,int age) {
        this.age = age;
        this.name = name;
        System.out.println("有参数");
    }
 
    public test() {
        System.out.println("无参数");
    }
    
}

我们再去获得有参构造函数

 Class cl=Class.forName("DG.test");
      
 Constructor con=cl.getConstructor(String.class,int.class);
 Object obj=con.newInstance("DG",19);

最终回显为“有参数”

再看看我们常用的另一个有命令执行的类ProcessBuilder

它的构造函数有两个

一个的参数是List<String> command

另一个是String command

随便选一个

Class clazz = Class.forName("java.lang.ProcessBuilder"); clazz.getMethod("start").invoke(clazz.getConstructor(String.class).newInstance( "calc.exe"));

如果有什么错误的地方希望大神能够指点我一下,嘻嘻嘻嘻

标签:java,String,getMethod,Class,安全,class,构造函数
来源: https://blog.csdn.net/chizhaji/article/details/113826375