前言
这里去看这个是因为在看weblogic的漏洞时用到了,当时没去学,现在补一下所以记录一下,需要的前置知识 就是RMI执行流程,这个自己前面也记录过,但是还是建议师傅们去看su18的,自己写的有点垃圾,不想看
https://su18.org/post/rmi-attack/#%E4%B8%89-%E6%80%BB%E7%BB%93 在贴一下su18师傅的总结。
1 | 1. RMI 客户端在调用远程方法时会先创建 Stub ( `sun.rmi.registry.RegistryImpl_Stub` )。 |
简介
JRMP是一个Java远程方法协议,该协议基于TCP/IP之上,RMI协议之下。也就是说RMI该协议传递时底层使用的是JRMP协议,而JRMP底层则是基于TCP传递。
RMI默认使用的JRMP进行传递数据,并且JRMP协议只能作用于RMI协议。当然RMI支持的协议除了JRMP还有IIOP协议,而在Weblogic里面的T3协议其实也是基于RMI去进行实现的。
环境搭建
在之前cc链子分析的时候介绍过怎么搭建Ysoserial工具,需要去下一个源码导入到IDEA中
然后在配置这里配置好参数即可,注意pom.xml中可能会有报错,也就是一些依赖没有下载下来我的解决办法时直接去另一个项目中把这些依赖都下载下来就可以了。
Exploit模块
JRMPListenr
运行之后就会弹出计算器,其实原理就是起一个恶意的注册中心,在客户端获取时返回一个恶意的序列化数据,客户端反序列化触发RCE。
原理分析
在ysoserial端打上断点看看是如何生成并发送的
这里会将端口和payload传入JRMPListener实例化然后调用run方法,那具体看看JRMPListener是如何定义的
这里其实没什么好看的就是把paylaod和端口传进来初始化了而已,去看看run方法
1 | public void run () { |
会进入 doMessage 方法
继续走到doCall方法中
最终会通过反射将恶意的payload写入输出流返回给客户端造成RCE。返回看客户端的断点
这里会接收从恶意注册端返回的数据进行反序列化,这里的2其实就是恶意注册端设置的TransportConstants.ExceptionalReturn
JRMPClient
他是用来主动攻击我们开启的DGC服务端的,看一下主要逻辑是makeDGCCall方法
1 | //传入目标RMI注册端(也是DGC服务端)的IP端口,以及攻击载荷的payload对象。 |
具体参考RMI反序列化部分的DGC攻击即可,在我们运行之后受害者端会走到一个dispatch方法中
dgc服务端会走到dispatch这个方法中
继续走到oldDispatch方法中
这里会继续走到服务端的dispatch中
这里会走到这里进行反序列化
payload模块
JRMPListener
这个payloda模块的原理其实就是如果存在一个反序列化的数据是我们可以控制的,那么这个模块生成的序列化数据传入进去反序列化之后会在受害者端开启一个rmi服务,此时我们在像该端口传入恶意的序列化数据即可达成攻击
1 | java -jar ysoserial-all.jar ysoserial.payloads.JRMPListener 1099 | base64 |
这是用法,如果要分析原理可以写一个功能去反序列化这段数据跟踪调用过程就能发现就是在被控端开了一个rmi服务。然后在配合着Exploit模块的JRMPClient进行攻击
1 | package com.ocean.zbz; |
然后跟一下
会走到UnicastRemoteObject类的ReadObject方法中,然后继续调用reexport()方法
这里就和前面分析rmi的流程很像就是创建一个服务
直接贴调用栈
1 | readObject:297, HashSet (java.util) |
原理就是上面说的开启rmi服务,然后我们在攻击服务端的DGC。
JRMPClient
这个链子的原理就是找到我们可以控制反序列化的点传入数据,然后受害端会去连接我们恶意的rmi服务端,返回恶意的序列化数据从而造成漏洞。
在反序列化这段数据之后,会走到DGC的dirty方法中
然后继续通过newCall向我们的恶意端发送请求
然后恶意端给返回恶意的序列化数据
在贴一下调用栈
1 | getRuntime:58, Runtime (java.lang) |