其中Server与Registry可以在同一服务器上实现,也可以布置在不同服务器上,现在一个完整的RMI流程可以大概描述为:
Registry先启动,并监听一个端口,一般为1099
Server向Registry注册远程对象
Client从Registry获得远程对象的代理(这个代理知道远程对象的在网络中的具体位置:ip、端口、标识符),然后Client通过这个代理调用远程方法,Server也是有一个代理的,Server端的代理会收到Client端的调用的方法、参数等,然后代理执行对应方法,并将结果通过网络返回给Client。
直接看图,话不多说
RMI调用远程方法的大致如下:
RMI客户端在调用远程方法时会先创建Stub(sun.rmi.registry.RegistryImpl_Stub)。
Stub会将Remote对象传递给远程引用层(java.rmi.server.RemoteRef)并创建java.rmi.server.RemoteCall(远程调用)对象。
RemoteCall序列化RMI服务名称、Remote对象。
RMI客户端的远程引用层传输RemoteCall序列化后的请求信息通过Socket连接的方式传输到RMI服务端的远程引用层。
RMI服务端的远程引用层(sun.rmi.server.UnicastServerRef)收到请求会请求传递给Skeleton(sun.rmi.registry.RegistryImpl_Skel#dispatch)。
Skeleton调用RemoteCall反序列化RMI客户端传过来的序列化。
Skeleton处理客户端请求:bind、list、lookup、rebind、unbind,如果是lookup则查找RMI服务名绑定的接口对象,序列化该对象并通过RemoteCall传输到客户端。
RMI客户端反序列化服务端结果,获取远程对象的引用。
而更通俗点来说:
1. 客户端请求代理 2. Stub编码处理消息 3. 消息传输 4. 到达管家skeleton并处理信息 5. 管家skeleton把信息提交给server 6. server接收到请求 7. server把请求的结果给管家 8. 管家skeleton把结果转交给stub 9. 代理Stub对结果解码 10. Stub把解码的结果交给client。具体可以参考该文章RMI由浅入深(一),那么我们知道了什么是RMI通信。RMI就是对服务器上的方法进行调用。那么weblogic上的RMI呢,在此处的cve-2015-4852是基于RMI T3协议反序列化导致的漏洞。两者有什么区别吗?
两者其实是一样的。只是weblogic这边的rmi通信用T3协议,只是优化了java rmi。T3传输协议是WebLogic的自有协议,Weblogic RMI就是通过T3协议传输的(可以理解为序列化的数据载体是T3)。
Java RMI默认使用的专有传输协议(或者也可以叫做默认协议)是JRMP,Weblogic RMI默认使用的传输协议是T3。T3协议对序列化的过程,包括一些特性,心脏跳动等等,进行了一些列优化,并且对rmi客户端量进行了增加等等
0x04、从历史长河探究cve-2015-4852摘取一张图,具体从哪里拿的,我也给忘记了,翻阅了太多文章了。可以看出这个cve-2015-4852是这些的祖宗。那我们从这个祖宗开始分析。从漏洞类型这边看,我们知道这个是T3反序列化漏洞,也就是说,是因为T3协议,从而导致的反序列化漏洞;那我们无可避免的去看看T3协议是什么东西
1、T3协议概述WebLogic Server 中的 RMI 通信使用 T3 协议在 WebLogic Server 和其他 Java 程序(包括客户端及其他 WebLogic Server 实例)间传输数据。同时T3协议包括
请求包头
请求主体
因此,在T3数据包构造过程中,需要发送两部分的数据。
我们通过部署好的环境,以及,去看看这个协议包情况
2、T3协议 t3 12.2.1 AS:255 HL:19 MS:10000000 PU:t3://us-l-breens:7001