1098/1099/1050 - Pentesting Java RMI - RMI-IIOP

从零开始学习 AWS 黑客技术,成为专家 htARTE(HackTricks AWS 红队专家)

支持 HackTricks 的其他方式:

使用 Trickest 可以轻松构建和自动化工作流程,使用世界上最先进的社区工具。 立即获取访问权限:

基本信息

Java 远程方法调用,或 Java RMI,是一种面向对象的 RPC 机制,允许一个位于一个 _Java 虚拟机_中的对象调用另一个 _Java 虚拟机_中的对象上的方法。这使开发人员能够使用面向对象的范例编写分布式应用程序。可以在此黑帽演讲中找到从攻击者角度的 Java RMI 的简短介绍。

默认端口: 1090,1098,1099,1199,4443-4446,8999-9010,9999

通常,只有默认的_Java RMI_组件(RMI Registry_和_Activation System)绑定到常见端口。实现实际_Java RMI_应用程序的_远程对象_通常绑定到随机端口,如上所示的输出。

_nmap_有时会在识别受_SSL保护的_RMI_服务时遇到问题。如果在常见_RMI_端口上遇到未知的ssl服务,应进一步调查。

RMI组件

简单来说,Java RMI_允许开发人员在网络上提供一个_Java对象。这会打开一个_TCP_端口,客户端可以连接并调用相应对象上的方法。尽管听起来很简单,但_Java RMI_需要解决几个挑战:

  1. 通过_Java RMI_分派方法调用,客户端需要知道目标对象的IP地址、监听端口、实现的类或接口以及ObjIDObjID是在对象在网络上可用时创建的唯一随机标识符。它是必需的,因为_Java RMI_允许多个对象在同一个_TCP_端口上监听)。

  2. 远程客户端可能通过调用暴露对象上的方法在服务器上分配资源。_Java虚拟机_需要跟踪这些资源中哪些仍在使用,哪些可以进行垃圾回收。

第一个挑战由_RMI注册表_解决,它基本上是_Java RMI_的命名服务。RMI注册表_本身也是一个_RMI服务,但实现的接口和ObjID是固定的,并且所有_RMI_客户端都知道。这使_RMI_客户端可以通过知道相应的_TCP_端口来使用_RMI注册表。

当开发人员希望将他们的_Java对象_在网络中提供时,他们通常将它们绑定到_RMI注册表_。注册表_存储了连接到对象所需的所有信息(IP地址、监听端口、实现的类或接口和ObjID值),并将其提供在一个人类可读的名称下(绑定名称)。想要消费_RMI服务_的客户端向_RMI注册表_请求相应的_绑定名称,注册表返回所有连接所需的信息。因此,情况基本上与普通_DNS_服务相同。以下清单显示了一个小例子:

上述挑战的第二个问题是通过分布式垃圾收集器(Distributed Garbage Collector,DGC)解决的。这是另一个具有众所周知的ObjID值的RMI服务,基本上每个RMI端点上都可以找到它。当RMI客户端开始使用RMI服务时,它会向DGC发送一个信息,说明相应的远程对象正在使用中。DGC然后可以跟踪引用计数,并能够清理未使用的对象。

连同已弃用的激活系统一起,这些是Java RMI的三个默认组件:

  1. RMI注册表ObjID = 0

  2. 激活系统ObjID = 1

  3. 分布式垃圾收集器ObjID = 2

Java RMI的默认组件长期以来一直是已知的攻击向量,并且在过时的Java版本中存在多个漏洞。从攻击者的角度来看,这些默认组件很有趣,因为它们实现了已知的类/接口,很容易与它们进行交互。对于自定义RMI服务,情况则有所不同。要调用远程对象上的方法,您需要事先知道相应的方法签名。如果不知道现有方法签名,就无法与RMI服务进行通信。

RMI枚举

remote-method-guesser是一个Java RMI漏洞扫描器,能够自动识别常见的RMI漏洞。每当您识别到一个RMI端点时,都应该尝试使用它:

枚举操作的输出在项目的文档页面中有更详细的解释。根据结果,您应该尝试验证已识别的漏洞。

_remote-method-guesser_显示的ObjID值可用于确定服务的正常运行时间。这可能有助于识别其他漏洞:

强制破解远程方法

即使在枚举过程中未发现漏洞,可用的 RMI 服务仍可能暴露危险函数。此外,尽管 RMI 通信到 RMI 默认组件受到反序列化过滤器的保护,但与自定义 RMI 服务通信时,通常不会设置此类过滤器。因此,了解 RMI 服务上的有效方法签名非常有价值。

不幸的是,Java RMI 不支持枚举 远程对象 上的方法。尽管如此,可以使用诸如 remote-method-guesserrmiscout 等工具来强制破解方法签名:

已识别的方法可以这样调用:

或者您可以执行类似这样的反序列化攻击:

以下文章中可以找到更多信息:

除了猜测之外,您还应该在搜索引擎或GitHub中查找遇到的RMI服务的接口甚至实现。这里的绑定名称和实现类或接口的名称可能会有所帮助。

已知接口

remote-method-guesser会将类或接口标记为known,如果它们在该工具的已知RMI服务的内部数据库中列出。在这些情况下,您可以使用known操作来获取有关相应RMI服务的更多信息:

Shodan

  • port:1099 java

工具

参考资料

HackTricks 自动命令

使用Trickest轻松构建并由全球最先进的社区工具驱动的自动化工作流程。 立即获取访问权限:

从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS红队专家)

支持HackTricks的其他方式:

最后更新于