java-RMI恶意服务
概述
Java RMI机制能够让一台Java虚拟机上的对象调用运行在另一台Java虚拟机上的对象的方法。总结一下,RMI机制的实现依赖于以下三个部分
- RMI Server
- RMI Registry
- RMI Client
简单概括一下RMI的流程:Server端事先在Registry处bind
将要被调用的远程对象。当Client需要调用远程对象时,先根据rmi://
地址连接到Registry,然后在Registry处查看是否绑定有需要的远程对象。如果有,则Registry返回Server端的rmi://
地址以及开放的端口,Client据此连接到Server。然后才开始真正的远程方法调用,远程方法在Server端执行,Server将执行后的结果发送给Client。
RMI的恶意利用
先创建两个项目
RMIServer
RMIClient
这两个项目都要有相同的接口
先创建两个项目,分别是客户端和服务端(然后有相同的接口)
服务端已经开了个端口出去了,客户端就可以直接去进行访问
但是客户端并不知道开的端口是啥,这里就得通过这个注册中心开的端口来找
默认的是1099,然后又因为注册中心于服务端开放的端口绑定了,于是就可以通过注册中心来查到服务端开放的端口
这里的话是获取注册中心的端口,然后获取绑定的名字,然后在进行函数的调用
成功在服务端回显 这里调用的是服务端的sayHello()方法
这里客户端没写回显,所以没输出
上面就是简单的RMI的执行过程了
攻击客户端
注册中心攻击客户端
此方法可以攻击客户端和服务端
对于注册中心来说,我们还是从这几个方法触发:
- bind
- unbind
- rebind
- list
- lookup
除了unbind和rebind都会返回数据给客户端,返回的数据是序列化形式,那么到了客户端就会进行反序列化,如果我们能控制注册中心的返回数据,那么就能实现对客户端的攻击,这里使用ysoserial的JRMPListener,命令如下
1 | java -cp ysoserial-all.jar ysoserial.exploit.JRMPListener 1099 CommonsCollections1 '' |
这里的意思是开启一个恶意的RMI服务端
成功执行,只不过本地开的话java版本太高,开不了,所以就用kali的ip,执行不了计算器
这里即使调用unbind也会触发反序列化,推测是在之前传输一些约定好的数据时进行的序列化和反序列化。所以实际上这五种方法都可以达到注册中心反打客户端或服务端的目的
剩下的去参考上面的文章就行了,因为其他的没有用到ysoserial服务端进行伪造
JEP290及其绕过
这里就不写了,因为写了也是照搬下来