payloads_JRMPListener学习

前言

好吧,我建议你去跟一次RMI的操作你就懂的这个了。推荐文章:https://paper.seebug.org/1251/

简介

JRMP是一个Java远程方法协议,该协议基于TCP/IP之上,RMI协议之下。也就是说RMI该协议传递时底层使用的是JRMP协议,而JRMP底层则是基于TCP传递。

RMI默认使用的JRMP进行传递数据,并且JRMP协议只能作用于RMI协议。当然RMI支持的协议除了JRMP还有IIOP协议,而在Weblogic里面的T3协议其实也是基于RMI去进行实现的。

攻击流程:

1.生成payloads/JRMPListener发送给服务器,当服务器反序列化payloads/JRMPListener后,即会开启一个端口进行监听。

2.使用exploit/JRMPClient模块发送payload,服务器就会把payload进行反序列化,从而完成进行攻击。

可以直接在JRMPListener中设置参数断点启动也可以在GeneratePayload下设置都没问题
image-20220206203632481

第一行就是获取端口号直接看第二行,我们直接转到工具类Reflections

image-20220206204322697

而下面的setAccessible(objCons);这个其实就是修改暴力反射的一个方法类

继续跟踪ReflectionFactory.getReflectionFactory().newConstructorForSerialization()

image-20220206205436008

实际上就借助ReflectionFactory.getReflectionFactory()工厂方法在这里就是返回了ReflectionFactory的实例对象,继续跟踪newConstructorForSerialization

image-20220206205823444

传入的第一个值是ActivationGroupImpl.class,第二个则是它的父类RemoteObject的构造方法getDeclaringClass()方法返回表示声明由此Method对象表示的方法的类的Class对象。然后通过字节码的方式生成constructorAccessor后面涉及底层感觉自己有点说不清楚了,感兴趣师傅自行查看。

这里用@洋洋师傅的一个demo来说明一下

新建一个Person类,创建其有参和无参构造方法

public class Person{
    private String name;
    public Person() {
        System.out.println("Person无参构造方法");
    }

    public Person(String name) {
        this.name = name;
        System.out.println("调用有参构造" + name.toString());
    }
}

新建一个User类,继承Person

public class User extends Person{
    public void eat(){
        System.out.println("eat...");
    }
}

新建Test类

public class Test1 {
    public static void main(String[] args) throws Exception {
        //获得Person的有参构造函数
        Constructor<Person> personConst = Person.class.getDeclaredConstructor(String.class);
        //获得Person的Constructor对象
        Constructor constructor = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(
                User.class,
                personConst
        );
        //第一个参数是需要创建对象的Class,比如User.class
		//第二个参数是对象的父类的构造方法,比如Person.class.getDeclaredConstructor()或者								//Person.class.getDeclaredConstructor(String.class)
        //constructor.setAccessible(true);
        //实例化对象,给person构造方法传入xxx,并转型成User
        User user = (User) constructor.newInstance("xxx");
        user.eat();
    }
}

运行结果

调用有参构造xxx
eat...

可以看到,虽然User类没有构造方法,但是依然能通过父类创建出来,并且调用其方法。

newConstructorForSerialization大致就是返回一个无参的constructor对象,但是绝对不会与原来的constructor冲突,被称为munged 构造函数

image-20220206212303422

所以会创建出ActivationGroupImpl对象,把获取到的Constructor进行了newInstance,并且传入了consArgs,即UnicastServerRef对象,然后对其向下转型成了ActivationGroupImpl类(T即为ActivationGroupImpl)所以返回值也是ActivationGroupImpl对象

返回到getObject类49行调用了Reflections类得getField方法,把UnicastRemoteObject中的port值设置成了jrmpPort

然后返回ActivationGroupImpl对象然后进行序列化操作。

gadget链调试

因为ActivationGroupImpl对象没有readObject方法所以它要从父类找readobject最终找到UnicastRemoteObject所以它是入口点。

image-20220206221908698

进入reexport

image-20220206221948325

调用exportObject方法并且传入this和port 这里的this,实际上是ActivationGroupImpl,因为前面进行了向上转型。跟踪exportObject

继续跟进到UnicastServerRef#exportObject

image-20220206222357645

然后LiveRef传入port里面会进行new ObjID的操作

image-20220206222442507

继续跟进

image-20220206222516604

new一个UID赋值给space成员变量,随机获取一个值赋值给objNum

介绍下ObjID

ObjID用于标识导出到RMI运行时的远程对象。 导出远程对象时,将根据用于导出的API来隐式或明确地分配一个对象标识符。

执行完返回到LiveRef进行重载

image-20220206223103380

里面再一次调用重载方法,并且在传递的第二个参数调用了TCPEndpoint.getLocalEndpoint并且传入端口进行获取实例化对象。继续跟踪。

image-20220206223146533

其实就是获取本地地址,如果端口为0就返回共享的默认值。

image-20220206223824015

然后返回到exportObject。因为前面都是一些赋值没啥好说的了。

image-20220206224954390

进入重载

image-20220206225048375

调用ref.exportObject(target)传入前面创建的实例对象

image-20220206225334069

继续调用transport.exportObject(target);

image-20220206225353588

到了这一步就调用了listen()进行启动监听。

image-20220206225516245

image-20220206225605448

RMI是基于JRMP实现的,当然我们也是可以向目标机发送 exploit/RMIRegistryExploit ,然后自己服务器挂起 exploit/JRMPListener,意思就是我们去打别人可能别人反手打你一巴掌。

image-20220207011022591

其他的分析可以查看orich1写的太好了

https://xz.aliyun.com/t/2650#toc-3
https://xz.aliyun.com/t/2651#toc-0
https://blog.csdn.net/whatday/article/details/106971531

参考

https://xz.aliyun.com/t/2649#toc-5
https://xz.aliyun.com/t/10036#toc-2
posted @ 2022-02-07 21:07  R0ser1  阅读(229)  评论(0编辑  收藏  举报